Skip to content

Add set-env ctl action to persist agent environment variables - #2211

Merged
sky333999 merged 3 commits into
mainfrom
add-set-env-ctl-action
Jul 21, 2026
Merged

Add set-env ctl action to persist agent environment variables#2211
sky333999 merged 3 commits into
mainfrom
add-set-env-ctl-action

Conversation

@sky333999

@sky333999 sky333999 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Description of the issue

Setup/enablement scripts need to persist environment variables such as CWAGENT_ROLE_ARN and AWS_REGION into env-config.json. Today the only way to do that is invoking the agent binary's internal -setenv/-envconfig flags directly and hardcoding the env-config.json path, bypassing the public ctl interface. The ctl script already wraps this exact mechanism for one specific key via set-log-level.

Description of changes

Adds a generic set-env action to the Linux and Windows ctl scripts, following the existing set-log-level pattern:

  • amazon-cloudwatch-agent-ctl -a set-env -e KEY=VALUE (Linux)
  • amazon-cloudwatch-agent-ctl.ps1 -a set-env -e KEY=VALUE (Windows)

The action validates the KEY=VALUE format (rejects missing = or empty key) and delegates to the agent binary's -setenv, which merges the key into env-config.json. Keys set this way are retained across config translations per #2131, unless they are translator-managed keys.

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

Tested on EC2 with agent 1.300069.0b1529 plus this change, on both Amazon Linux 2023 (x86_64) and Windows Server 2022. On both platforms:

  • set-env creates env-config.json when missing, merges additional keys, overwrites repeated keys
  • Rejects NOEQUALS, =value, and missing -e with exit 1 and usage
  • Custom keys survive fetch-config and full agent restart; translator-managed CWAGENT_LOG_LEVEL is wiped/regenerated from the JSON config as expected
  • Agent process loads the vars at startup (verified via I! MY_CUSTOM_VAR is set to ... log lines) and the 30s env watcher hot-reloads changes
  • set-log-level regression: still works end to end, including hot reload

@sky333999
sky333999 requested a review from a team as a code owner July 20, 2026 19:22
@sky333999 sky333999 added the ready for testing Indicates this PR is ready for integration tests to run label Jul 20, 2026
@sky333999

Copy link
Copy Markdown
Contributor Author

Addressed review findings in 742c887:

  1. Windows value handling (critical): SetEnv now invokes the agent binary directly instead of through cmd /c, so values containing spaces or shell metacharacters are passed as a single argument and never interpreted by cmd.exe. Verified on Windows Server 2022: KEY=hello world with spaces stored intact, KEY=val & echo pwned > C:\pwned.txt stored verbatim with no command execution, %PATH% not expanded.
  2. Linux error handling: set_env now checks the agent binary exit code explicitly and prints a failure message with exit 1 instead of relying implicitly on set -e. Verified on AL2023 with an unwritable env-config.json.
  3. Usage text: added a note (both platforms) that translation-produced values (proxy, CA bundle, log level, etc.) are overwritten on fetch-config/append-config or restart.

Additional re-test coverage on both platforms: KEY=A=B=C (splits on first = only), values with double quotes, failure path leaves env-config.json unmodified, and existing basic/validation cases regression-tested.

Deferred (pre-existing or out of scope, tracked separately): -setenv without -envconfig silently exits 0 in the agent binary; set_log_level_all shares the old exit-code pattern; darwin ctl lacks both set-log-level and set-env; strict key-name validation.

@sky333999

Copy link
Copy Markdown
Contributor Author

Added darwin platform parity in a8b9586: the darwin ctl now supports both set-env and set-log-level (it never received set-log-level when that action was added to Linux/Windows). Both use the same explicit exit-code handling introduced for the Linux set_env in 742c887.

Tested on an EC2 mac2.metal (macOS Sonoma, arm64) with agent 1.300069.0b1529 plus this branch's binaries and ctl:

  • set-env: creates/merges env-config.json, values with spaces/metacharacters stored intact, KEY=A=B splits on first = only, all invalid inputs (missing =, empty key, missing -e) exit 1
  • set-log-level: sets CWAGENT_LOG_LEVEL, rejects invalid levels
  • Stickiness: custom keys survive fetch-config; translator-managed keys regenerated
  • Runtime: agent log confirms I! MY_CUSTOM_VAR is set to ... after start
  • End-to-end: a draft update to the ManageAgent SSM document's MacOS step (separate internal change) drove set-env through this ctl successfully with a spaces-containing value

sky333999 added a commit to aws/amazon-cloudwatch-agent-test that referenced this pull request Jul 21, 2026
Adds integration test cases for the new set-env action in the
ManageAgent document (synced in this branch, delegating to the
ctl set-env action from aws/amazon-cloudwatch-agent#2211):

- Happy path: custom key with a space-containing value; asserts
  command success, the ctl's "Set <KEY>" stdout, unchanged agent
  status/configstatus, and the pair persisted to env-config.json
  on disk (read back via AWS-RunShellScript/AWS-RunPowerShellScript
  with platform-specific paths).
- Merge: a second key persists alongside the first.
- Error path: empty optionalEnvironmentVariable fails with the
  document-level error message (new failure-path helper that
  requires terminal status Failed).

Cases are appended after the existing configure flow so prior
status assertions are unaffected, mirrored across the unix and
windows implementations.
@@ -448,6 +477,7 @@ main() {
# helper for rpm+deb uninstallation hooks, not expected to be called manually
preun) preun_all ;;
set-log-level) set_log_level_all "${log_level}" ;;

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.

nit: Should we have set-log-level call set_env?

Comment thread packaging/windows/amazon-cloudwatch-agent-ctl.ps1
sky333999 added a commit to aws/amazon-cloudwatch-agent-test that referenced this pull request Jul 21, 2026
Adds integration test cases for the new set-env action in the
ManageAgent document (synced in this branch, delegating to the
ctl set-env action from aws/amazon-cloudwatch-agent#2211):

- Happy path: custom key with a space-containing value; asserts
  command success, the ctl's "Set <KEY>" stdout, unchanged agent
  status/configstatus, and the pair persisted to env-config.json
  on disk (read back via AWS-RunShellScript/AWS-RunPowerShellScript
  with platform-specific paths).
- Merge: a second key persists alongside the first.
- Error path: empty optionalEnvironmentVariable fails with the
  document-level error message (new failure-path helper that
  requires terminal status Failed).

Cases are appended after the existing configure flow so prior
status assertions are unaffected, mirrored across the unix and
windows implementations.
@jefchien
jefchien force-pushed the add-set-env-ctl-action branch from 4efa2d0 to 6add08b Compare July 21, 2026 14:28
Adds a 'set-env' action to the Linux and Windows ctl scripts that
wraps the agent binary's internal -setenv/-envconfig flags, so
callers (e.g. setup scripts) no longer need to invoke the raw agent
binary or hardcode the env-config.json path.

Usage:
  amazon-cloudwatch-agent-ctl -a set-env -e KEY=VALUE
  amazon-cloudwatch-agent-ctl.ps1 -a set-env -e KEY=VALUE

Keys set this way are retained across config translations (#2131)
unless they are translator-managed keys.
…n set-env

- Windows: invoke the agent binary directly instead of through cmd /c so
  values containing spaces or shell metacharacters are passed as a single
  argument and never interpreted by cmd.exe
- Linux: check the agent binary exit code explicitly and fail with a
  message instead of relying on set -e
- Document in usage text that translation-produced values are overwritten
  on fetch-config/restart
The darwin ctl predates set-log-level and never received it. Both
actions are needed for parity now that the ManageAgent SSM document
(which has a MacOS step) will offer set-env. Uses the same explicit
exit-code handling as the Linux implementation.
@jefchien
jefchien force-pushed the add-set-env-ctl-action branch from 6add08b to 7f063b4 Compare July 21, 2026 14:39
@sky333999
sky333999 merged commit 0f45eeb into main Jul 21, 2026
396 of 399 checks passed
@sky333999
sky333999 deleted the add-set-env-ctl-action branch July 21, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for testing Indicates this PR is ready for integration tests to run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants