Skip to content

Migrate wizard, downloader, and translator to SDKv2#1995

Merged
jefchien merged 2 commits intofeature/aws-sdk-v2from
aws-sdk-v2/bin
Feb 3, 2026
Merged

Migrate wizard, downloader, and translator to SDKv2#1995
jefchien merged 2 commits intofeature/aws-sdk-v2from
aws-sdk-v2/bin

Conversation

@jefchien
Copy link
Copy Markdown
Contributor

@jefchien jefchien commented Jan 26, 2026

Description of the issue

The last bit of the migration is the tools and utilities used by the wizard, downloader, and translator binaries.

Description of changes

extension/agenthealth

  • Copies the seekerLen function and readerSeekerCloser struct from github.com/aws/aws-sdk-go-v2/feature/s3/manager. This function is no longer exposed by the core package in v2, so this was done to avoid the full import of an S3 package we would otherwise not use.

tool/downloader

  • Uses the v2 credential chain to get an AWS config for the SSM GetParameter call.

tool/processors/ssm

  • Reuses the RefreshableSharedCredentialsProvider from the credential chain since v2 does not provide an equivalent for credentials.NewSharedCredentials.
  • Updates SSM SendParameter call to use SDKv2

tool/util

  • Removed unused SDKRegion function.
  • Changed DefaultEC2Region to reuse ec2metadataprovider

translator/util/ec2util

  • Changed deriveEC2MetadataFromIMDS to reuse ec2metadataprovider

translator/util

  • Updated SDKRegionWithCredsMap to use SDKv2

License

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Tests

Ran unit tests with https://github.com/aws/amazon-cloudwatch-agent/actions/runs/21376946856

Integration test: https://github.com/aws/amazon-cloudwatch-agent/actions/runs/21597922889

Tested wizard to store config in SSM parameter store

The config file is also located at /opt/aws/amazon-cloudwatch-agent/bin/config.json.
Edit it manually if needed.
Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]:

What parameter store name do you want to use to store your config? (Use 'AmazonCloudWatch-' prefix if you use our managed AWS policy)
default choice: [AmazonCloudWatch-linux]

Trying to fetch the default region based on ec2 metadata...
2026/02/03 16:25:26 D! Fallback shared config file(s): [/root/.aws/credentials]
2026/02/03 16:25:26 D! Successfully created credential sessions
2026/02/03 16:25:26 D! Using credential <snip> from EC2RoleProvider
I! IMDS retry client will retry 1 timesWhich region do you want to store the config in the parameter store?
default choice: [us-east-1]

Which AWS credential should be used to send json config to parameter store?
1. <snip>(From SDK)
2. Other
default choice: [1]:

Successfully put config to parameter store AmazonCloudWatch-linux.
Program exits now.

Tested downloader to pull config from SSM parameter store

$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -c ssm:AmazonCloudWatch-linux
****** processing amazon-cloudwatch-agent ******
2026/02/03 16:43:17 D! Fallback shared config file(s): [/root/.aws/credentials]
2026/02/03 16:43:17 D! Successfully created credential sessions
2026/02/03 16:43:17 D! Using credential <snip> from EC2RoleProvider
2026/02/03 16:43:17 D! Fallback shared config file(s): [/root/.aws/credentials]
2026/02/03 16:43:17 D! Successfully created credential sessions
2026/02/03 16:43:17 D! Using credential <snip> from EC2RoleProvider
Starting config-downloader, this will map back to a call to amazon-cloudwatch-agent
Executing /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent with arguments: [config-downloader -output-dir /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d -config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml -multi-config default -mode ec2 -download-source ssm:AmazonCloudWatch-linux]I! Trying to detect region from ec2
Trying to fetch the default region based on ec2 metadata...
I! IMDS retry client will retry 1 times
Start configuration validation...
2026/02/03 16:43:17 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_AmazonCloudWatch-linux.tmp ...
2026/02/03 16:43:17 I! Valid Json input schema.
2026/02/03 16:43:17 D! Fallback shared config file(s): [/root/.aws/credentials]
2026/02/03 16:43:17 D! Successfully created credential sessions
2026/02/03 16:43:17 D! Using credential <snip> from EC2RoleProvider
2026/02/03 16:43:17 D! ec2tagger processor required because append_dimensions is set
2026/02/03 16:43:17 Configuration validation first phase succeeded
Starting config-translator, this will map back to a call to amazon-cloudwatch-agent
Executing /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent with arguments: [config-translator -input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -input-dir /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d -output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml -mode ec2 -config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml -multi-config default]I! Trying to detect region from ec2
Trying to fetch the default region based on ec2 metadata...
I! IMDS retry client will retry 1 timesD! [EC2] Found active network interface
I! IMDS retry client will retry 1 times
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -schematest -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml
Configuration validation second phase succeeded
Configuration validation succeeded

Requirements

Before commiting your code, please do the following steps.

  1. Run make fmt and make fmt-sh
  2. Run make lint

Integration Tests

To run integration tests against this PR, add the ready for testing label.

@jefchien jefchien requested a review from a team as a code owner January 26, 2026 23:13

// seekerLen attempts to get the number of bytes remaining at the seeker's
// current position. Returns the number of bytes remaining or error.
func seekerLen(s io.Seeker) (int64, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a fairly generic func (likely stable with no future changes?), but how do we ensure upstream changes are synchronized with this copied version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to take upstream changes. There's nothing really AWS SDK specific about this.

}
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
fmt.Printf("Error code: %s, message: %s\n", apiErr.ErrorCode(), apiErr.ErrorMessage())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is ErrorFault equivalent to original error?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. It's an enum indicating whether the error is client-side or server-side.

Comment thread tool/processors/ssm/ssm.go Outdated
fileCreds, err := fileCredentialsProvider.Get()
fileCredentialsProvider := configaws.RefreshableSharedCredentialsProvider{
Profile: "AmazonCloudWatchAgent",
ExpiryWindow: 10 * time.Minute,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be a const? also is this the previous window from v1?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. Can make it one. In SDK v1, they never expired (since they're technically static credentials). I can create a separate provider for that where it doesn't mess with the ExpiryWindow stuff.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question on the expiry window

profile, profile_ok := credsMap[commonconfig.CredentialProfile]
sharedConfigFile, sharedConfigFile_ok := credsMap[commonconfig.CredentialFile]
if !profile_ok && !sharedConfigFile_ok {
profile, profileOK := credsMap[commonconfig.CredentialProfile]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these by the new linter or you are pretty much rewriting? 😄

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Little bit of both lol

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there no unit tests for this file ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SDK didn't have unit tests, but I've added some.

Comment thread cfg/aws/v2/refreshable.go
sharedConfig, err := config.LoadSharedConfigProfile(ctx, p.Profile, func(options *config.LoadSharedConfigOptions) {
options.CredentialsFiles = []string{p.Filename}
})
var opts []func(*config.LoadSharedConfigOptions)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these just general linter changes outside the scope of the V2 migration ? I like it nonetheless

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so the SharedCredentialsProvider can be called with the default filepath.

Comment thread tool/processors/ssm/ssm.go Outdated
fileCreds, err := fileCredentialsProvider.Get()
fileCredentialsProvider := configaws.RefreshableSharedCredentialsProvider{
Profile: "AmazonCloudWatchAgent",
ExpiryWindow: 10 * time.Minute,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question on the expiry window

@jefchien jefchien merged commit 42a8509 into feature/aws-sdk-v2 Feb 3, 2026
@jefchien jefchien deleted the aws-sdk-v2/bin branch February 3, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants