━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Install AWS CLI v2 (
aws --version) - Configure AWS profiles in
~/.aws/config(SSO, static keys, or credential_process — all supported) - Install
jqfor JSON parsing - Install
python3(3.6+) for cross-platform credential expiry parsing (macOS:brew install python3) - Install
expectfor file upload functionality (macOS:brew install expect) - Install
nc(netcat) for file transfers (usually pre-installed on macOS/Linux)
Example AWS profiles (in ~/.aws/config):
[sso-session my-session]
sso_start_url = https://example.awsapps.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access
[profile my-sso-profile]
sso_session = my-session
sso_account_id = 123456789012
sso_role_name = ReadOnly
region = us-east-1
output = jsonChained profiles (role assumption via source_profile) are also supported:
[profile dev-admin]
source_profile = my-sso-profile
role_arn = arn:aws:iam::098765432109:role/AdminRole
region = eu-west-1
[profile prod-readonly]
role_arn = arn:aws:iam::111222333444:role/ReadOnly
source_profile = my-sso-profile
region = us-west-2━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Decide how you want to load the helpers:
- One-time (current shell only):
- Run:
- One-time (current shell only):
source /path/aws-cli-helpers/main.sh- Permanent (every new shell):
- Add to
~/.zshrc,~/.bashrc(or~/.bash_profile:
- Add to
Notes:
main.shexportsAWS_HELPERS_DIRand loads all helper functions and aliases.- An alias
sso_loginis created for convenience:sso_login <profile>.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
aws_session- Lists all configured AWS profiles from
~/.aws/config— SSO, static keys, and credential_process - If only one profile exists, it is auto-selected (no prompt)
- Performs SSO login if not already authenticated (SSO profiles only)
- After authentication, detects chained profiles (profiles with
source_profile):- One chained profile: auto-selects it
- Multiple chained profiles: displays a selection table
- No chained profiles: continues with the base profile
- Clears the terminal and displays account/profile/region in a styled table
- Updates the shell prompt with
[profile:region](bash and zsh) - Warns if credentials will expire in ≤ 15 minutes (yellow) or ≤ 5 minutes (red)
- Lists all configured AWS profiles from
-
aws_logout- Unsets all AWS session environment variables (
AWS_PROFILE,AWS_REGION, etc.) - Restores the original shell prompt
- Does not delete any files from
~/.aws/
- Unsets all AWS session environment variables (
-
aws_switch- Switches to a different profile without re-running the full
aws_sessionflow - Triggers SSO login automatically if the selected profile needs it
- Updates the prompt and checks for upcoming expiry
- Switches to a different profile without re-running the full
-
sso_login <profile>(alias)- Shortcut for
aws sso login --profile <profile>
- Shortcut for
-
ec2helper with subcommands:ec2 ls— list all EC2 instances (id, name, state)ec2 ls-running— list only running EC2 instancesec2 ls-stopped— list only stopped EC2 instancesec2 session <instance-id>— start an SSM shell sessionec2 run <instance-id>— start (run) an EC2 instanceec2 stop <instance-id>— stop an EC2 instanceec2 port-forward <remote-port> <local-port> <instance-id> [host]— start SSM port forwarding- Without host: forwards from the EC2 instance itself (e.g., web server on the instance)
- With host: forwards from a remote service through the EC2 instance (e.g., RDS, ElastiCache)
ec2 upload <instance-id> <local-file> [remote-path] [port]— upload a file to an EC2 instance via SSM port forwarding- Arguments:
<instance-id>— EC2 instance ID (e.g.,i-0123456789abcdef0)<local-file>— Path to the local file to upload[remote-path]— (Optional) Remote file path (default:/home/ec2-user/<filename>)[port]— (Optional) Port number for transfer (default: random port 50000-59999)
- Features:
- Uses SSM port forwarding for secure file transfer
- Automatically creates remote directory if needed
- Displays file size and MD5 checksums for verification
- Verifies file was successfully uploaded
- Cleans up SSM sessions automatically
- Arguments:
-
ecshelper with subcommands:ecs clusters— list all ECS clustersecs services <cluster>— list services in a clusterecs tasks <cluster> [--running]— list tasks in a cluster (optionally only running)ecs service-tasks <cluster> <service> [--running]— list tasks for a specific serviceecs task-info <cluster> <task-id>— get detailed task information (status, container, image, uptime)ecs exec <cluster> <task-id> <container> [command]— execute command in a container (default: /bin/bash)ecs logs <cluster> <task-id> [--tail N]— get task information and container logsecs stop <cluster> <task-id> [reason]— stop a running taskecs describe <cluster> <service>— describe a service (status, running/desired count, task definition)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Load the helpers (see Setup above)
- Run
aws_session- Select from the interactive profile list (or it auto-selects if only one profile exists)
- If prompted, complete SSO login in your browser
- Choose a chained profile if applicable (or it auto-selects if only one)
- Verify the printed table shows the expected Account, Profile, Region
- To switch accounts mid-session, run
aws_switch - To clear the session, run
aws_logout - Use EC2 helpers as needed, for example:
ec2 lsec2 ls-runningec2 ls-stoppedec2 session i-0123456789abcdef0ec2 run i-0123456789abcdef0ec2 stop i-0123456789abcdef0ec2 port-forward 8080 8080 i-0123456789abcdef0(forward to EC2 instance itself)ec2 port-forward 3306 3306 i-0123456789abcdef0 mydb.123456789012.us-west-2.rds.amazonaws.com(forward to RDS through EC2)ec2 upload i-0123456789abcdef0 /local/file.txtec2 upload i-0123456789abcdef0 /local/file.txt /home/ec2-user/file.txtec2 upload i-0123456789abcdef0 /local/file.txt /home/ec2-user/file.txt 8888
- Use ECS helpers as needed, for example:
ecs clustersecs services my-clusterecs tasks my-cluster --runningecs service-tasks my-cluster my-service --runningecs task-info my-cluster abc123def456ecs exec my-cluster abc123def456 my-container /bin/bashecs exec my-cluster abc123def456 my-container ls -la /var/logecs logs my-cluster abc123def456ecs stop my-cluster abc123def456ecs describe my-cluster my-service
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Running
aws_sessionshows a table with:- Correct AWS Account (formatted
XXXX-XXXX-XXXX) - Selected AWS Profile (or chained profile if applicable)
- Current Region
- Identity ARN
- User ID
- Correct AWS Account (formatted
- If only one SSO profile exists, it is auto-selected without prompting
- Chained profiles (via
source_profile) are detected and offered after authentication ec2 lsoutputs instances data as JSON lines (viajq -r), without errorsec2 session <instance-id>starts an interactive SSM shell sessionec2 port-forward <remote-port> <local-port> <instance-id>forwards from the EC2 instance itselfec2 port-forward <remote-port> <local-port> <instance-id> <host>forwards from a remote service through EC2ec2 upload <instance-id> <local-file>uploads a file to the instance and displays verification (file size, MD5 checksums)ecs clusterslists all available ECS clustersecs services <cluster>lists services in the specified clusterecs tasks <cluster>displays a formatted table with task ID, status, container, and uptimeecs exec <cluster> <task-id> <container>starts an interactive shell in the containerecs describe <cluster> <service>shows service details in a table format- Your shell prompt updates to include
user@account:profile:region
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
jq: command not found- Install
jq(macOS:brew install jq)
- Install
-
aws: command not foundor AWS CLI v1 detected- Install
awscli(macOS:brew install awscli)
- Install
-
No profiles listed in
aws_session- Ensure your
~/.aws/configprofiles includesso_account_id,aws_access_key_id, orcredential_process - Example provided in the Prerequisites section
- Ensure your
-
Chained profile not detected
- Ensure the chained profile has
source_profile = <base-profile-name>matching the selected SSO profile name exactly - The chained profile must be defined in
~/.aws/configwith a[profile name]section header
- Ensure the chained profile has
-
Chained profile fails to assume role
- Verify the
role_arnin the chained profile is correct and your SSO user has permission to assume it - The session will fall back to the base SSO profile automatically
- Verify the
-
SSM session errors
- Ensure the instance has SSM agent installed and proper IAM role
- Ensure network/VPC endpoints allow SSM
-
ECS exec command fails
- Ensure ECS Exec is enabled on the service (
enableExecuteCommand: true) - Verify the task role has required permissions for SSM
- Check that the container has a shell available at the specified path
- Ensure ECS Exec is enabled on the service (
-
ECS tasks showing incorrect uptime
- Ensure system time is synchronized
- Verify
jqversion supports time functions (jq 1.5+)
-
File upload fails
- Ensure
expectis installed (which expect) - Ensure
nc(netcat) is available on both local and remote systems - Verify the instance has SSM agent running and proper IAM permissions
- Check that the specified port is not already in use (script uses random port 50000-59999 by default)
- Ensure the remote directory path exists or can be created
- Ensure
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
main.sh— Entrypoint; exportsAWS_HELPERS_DIR, loads sessions and EC2/ECS helperssession.sh— Session orchestration: profile picker (with auto-select), SSO login, chained profile detection, table displayservices/ec2.sh—ec2command group: list instances, SSM session, port forwarding, file uploadservices/_ec2_upload.sh— File upload script using Expect for SSM port forwarding transfersservices/ecs.sh—ecscommand group: clusters, services, tasks, exec, logs, stop, describe
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Full documentation is available in docs/:
- docs/guides/aws-auth.md — Authentication guide: commands, expiry warnings, profile types, troubleshooting
- docs/adr/ADR-001-aws-auth-enhancement.md — Architecture decisions for the auth enhancement
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
Lint (Shellcheck)
Install Shellcheck (e.g.brew install shellcheckon macOS), then run:make shellcheck
Or:
shellcheck -x main.sh session.sh services/ec2.sh services/ecs.sh -
Smoke tests (no AWS credentials required):
make testOr:
bash test/run.shfrom the repo root. Tests verify that sourcingmain.shsucceeds and thatec2/ecswith no arguments print usage and exit non-zero. -
CI
On push or pull request tomain, GitHub Actions runs Shellcheck and the smoke tests. See.github/workflows/ci.yml.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Remove or comment out the
source /path/aws-cli-helpers/main.shline from:~/.zshrc(Zsh) or~/.bashrc/~/.bash_profile(Bash)
- Restart your terminal (or re-source the rc file)