diff --git a/agent/credentials/instancecreds/instancecreds.go b/agent/credentials/instancecreds/instancecreds.go index 70947c92c2d..f471f6826d3 100644 --- a/agent/credentials/instancecreds/instancecreds.go +++ b/agent/credentials/instancecreds/instancecreds.go @@ -14,6 +14,7 @@ package instancecreds import ( + "os" "sync" "github.com/aws/amazon-ecs-agent/agent/credentials/providers" @@ -38,7 +39,25 @@ func GetCredentials() *credentials.Credentials { mu.Lock() if credentialChain == nil { credProviders := defaults.CredProviders(defaults.Config(), defaults.Handlers()) - credProviders = append(credProviders, providers.NewRotatingSharedCredentialsProvider()) + /* + The default credential chain provided by the SDK includes: + * EnvProvider + * SharedCredentialsProvider + * RemoteCredProvider + + In the case of ECS-A on Windows, the `SharedCredentialsProvider` takes + precedence over the `RotatingSharedCredentialsProvider` and this results + in the credentials not being refreshed. To mitigate this issue, we will + use the environment variable `ECS_EXTERNAL` to reorder the credential + chain and ensure that `RotatingSharedCredentialsProvider` takes precedence + over the `SharedCredentialsProvider`. + + */ + if _, ok := os.LookupEnv("ECS_EXTERNAL"); ok { + credProviders = append(credProviders[:1], append([]credentials.Provider{providers.NewRotatingSharedCredentialsProvider()}, credProviders[1:]...)...) + } else { + credProviders = append(credProviders, providers.NewRotatingSharedCredentialsProvider()) + } credentialChain = credentials.NewCredentials(&credentials.ChainProvider{ VerboseErrors: false, Providers: credProviders, diff --git a/agent/credentials/providers/credentials_filename_linux.go b/agent/credentials/providers/credentials_filename_linux.go new file mode 100644 index 00000000000..965eebf15a0 --- /dev/null +++ b/agent/credentials/providers/credentials_filename_linux.go @@ -0,0 +1,22 @@ +//go:build linux + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package providers + +const ( + // defaultRotatingCredentialsFilename is the default location of the credentials file + // for RotatingSharedCredentialsProvider. + defaultRotatingCredentialsFilename = "/rotatingcreds/credentials" +) diff --git a/agent/credentials/providers/credentials_filename_unsupported.go b/agent/credentials/providers/credentials_filename_unsupported.go new file mode 100644 index 00000000000..a01fd2ff35b --- /dev/null +++ b/agent/credentials/providers/credentials_filename_unsupported.go @@ -0,0 +1,22 @@ +//go:build !windows && !linux + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package providers + +const ( + // defaultRotatingCredentialsFilename is the default location of the credentials file + // for RotatingSharedCredentialsProvider. + defaultRotatingCredentialsFilename = "/unsupported/file_path/file_name" +) diff --git a/agent/credentials/providers/credentials_filename_windows.go b/agent/credentials/providers/credentials_filename_windows.go new file mode 100644 index 00000000000..58fbdc47da4 --- /dev/null +++ b/agent/credentials/providers/credentials_filename_windows.go @@ -0,0 +1,20 @@ +//go:build windows + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package providers + +// defaultRotatingCredentialsFilename is the default location of the credentials file +// for RotatingSharedCredentialsProvider. +const defaultRotatingCredentialsFilename = "C:\\Windows\\System32\\config\\systemprofile\\.aws\\credentials" diff --git a/agent/credentials/providers/rotating_shared_credentials_provider.go b/agent/credentials/providers/rotating_shared_credentials_provider.go index 7878891fff5..bc829781950 100644 --- a/agent/credentials/providers/rotating_shared_credentials_provider.go +++ b/agent/credentials/providers/rotating_shared_credentials_provider.go @@ -24,8 +24,6 @@ import ( const ( // defaultRotationInterval is how frequently to expire and re-retrieve the credentials from file. defaultRotationInterval = time.Minute - // defaultFilename is the default location of the credentials file within the container. - defaultFilename = "/rotatingcreds/credentials" // RotatingSharedCredentialsProviderName is the name of this provider RotatingSharedCredentialsProviderName = "RotatingSharedCredentialsProvider" ) @@ -46,7 +44,7 @@ func NewRotatingSharedCredentialsProvider() *RotatingSharedCredentialsProvider { return &RotatingSharedCredentialsProvider{ RotationInterval: defaultRotationInterval, sharedCredentialsProvider: &credentials.SharedCredentialsProvider{ - Filename: defaultFilename, + Filename: defaultRotatingCredentialsFilename, Profile: "default", }, } diff --git a/agent/credentials/providers/rotating_shared_credentials_provider_test.go b/agent/credentials/providers/rotating_shared_credentials_provider_test.go index 404701cfec3..d0519554b93 100644 --- a/agent/credentials/providers/rotating_shared_credentials_provider_test.go +++ b/agent/credentials/providers/rotating_shared_credentials_provider_test.go @@ -29,7 +29,7 @@ func TestNewRotatingSharedCredentialsProvider(t *testing.T) { p := NewRotatingSharedCredentialsProvider() require.Equal(t, time.Minute, p.RotationInterval) require.Equal(t, "default", p.sharedCredentialsProvider.Profile) - require.Equal(t, "/rotatingcreds/credentials", p.sharedCredentialsProvider.Filename) + require.Equal(t, defaultRotatingCredentialsFilename, p.sharedCredentialsProvider.Filename) } func TestRotatingSharedCredentialsProvider_RetrieveFail_BadPath(t *testing.T) {