Running Scripts Across Multiple AWS Accounts with AWS SSO

Running Scripts Across Multiple AWS Accounts with AWS SSO

aws aws-cli aws-sso automation bash

Managing multiple AWS accounts is common in organizations following best practices. You might have separate accounts for development, staging, and production, or multiple sandbox accounts for different teams. But what happens when you need to run the same AWS CLI command across many of those accounts?

In this post, I’ll show you how to use a bash script with AWS SSO to execute commands across multiple AWS accounts and regions from your local machine.

🎯 The Challenge

When working with multiple AWS environments, you often need to:

  • Check resource configurations across all accounts
  • Deploy or update resources consistently
  • Audit settings or gather information
  • Clean up resources across environments

Doing this manually means:

  1. Running aws sso login for each profile
  2. Switching between profiles using --profile
  3. Repeating commands for each region using --region
  4. Manually tracking success and failures

This process is tedious, error-prone, and time-consuming.

🛠️ The Solution

Here’s a bash script that automates running AWS CLI commands across multiple accounts and regions. It handles authentication, execution, and provides clear feedback on success or failure.

#!/bin/bash

set -euo pipefail

# Configuration
PROFILES=("product-dev" "product-test" "product-prod" "sandbox-one" "sandbox-two")
REGIONS=("eu-central-1" "eu-west-1")

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

check_credentials() {
    local profile=$1

    if aws sts get-caller-identity \
        --profile "${profile}" \
        --no-cli-pager &>/dev/null; then
        return 0
    else
        return 1
    fi
}

execute_aws_cli_command() {
    local profile=$1
    local region=$2

    log_info "Processing profile: ${profile}, region: ${region}"

    # Replace this with your actual AWS CLI command
    if aws sts get-caller-identity \
        --profile "${profile}" \
        --region "${region}" \
        --no-cli-pager 2>/dev/null; then
        log_info "✓ Successfully ran AWS CLI command for ${profile} in ${region}"
        return 0
    else
        log_error "✗ Failed to run AWS CLI command for ${profile} in ${region}"
        return 1
    fi
}

main() {
    local total=0
    local success=0
    local failed=0

    log_info "Running AWS CLI command across multiple AWS accounts and regions..."
    log_info "Profiles: ${PROFILES[*]}"
    log_info "Regions: ${REGIONS[*]}"
    echo ""

    for profile in "${PROFILES[@]}"; do
        if ! check_credentials "${profile}"; then
            log_warning "No valid credentials for profile ${profile}, starting login procedure..."
            aws sso login --profile "${profile}"
        fi

        for region in "${REGIONS[@]}"; do
            ((total++))
            if execute_aws_cli_command "${profile}" "${region}"; then
                ((success++))
            else
                ((failed++))
            fi
        done
    done

    echo ""
    log_info "Summary: Total=${total}, Success=${success}, Failed=${failed}"

    if [ ${failed} -gt 0 ]; then
        exit 1
    fi
}

main

🔧 How It Works

1. Configuration

The script starts by defining your AWS SSO profiles and target regions:

PROFILES=("product-dev" "product-test" "product-prod")
REGIONS=("eu-central-1" "eu-west-1")

2. Credential Check

Before executing commands, the script verifies that each profile has valid credentials:

check_credentials() {
    local profile=$1
    if aws sts get-caller-identity --profile "${profile}" &>/dev/null; then
        return 0
    else
        return 1
    fi
}

If credentials are missing or expired, it automatically triggers the AWS SSO login flow.

3. Command Execution

The execute_aws_cli_command function runs your AWS CLI command for each profile-region combination. Replace aws sts get-caller-identity with your actual command:

# Example: List all S3 buckets
aws s3 ls --profile "${profile}" --region "${region}"

# Example: Describe EC2 instances
aws ec2 describe-instances --profile "${profile}" --region "${region}"

# Example: Get CloudFormation stack status
aws cloudformation describe-stacks --profile "${profile}" --region "${region}"

4. Summary Report

The script tracks execution statistics and provides a summary:

[INFO] Summary: Total=10, Success=10, Failed=0

It exits with code 1 if any commands failed.

💡 Use Cases

This script is useful for:

Resource Auditing

  • Check security group configurations across all accounts
  • List Lambda functions and their runtime versions
  • Find untagged resources

Compliance Checks

  • Verify encryption settings on S3 buckets
  • Check IAM password policies
  • Audit CloudTrail configurations

Cost Management

  • Identify unused resources across environments
  • Check for unattached EBS volumes
  • Find stopped EC2 instances (see my post on shutting down resources overnight for cost savings)

Bulk Operations

  • Update tags across all resources
  • Enable AWS Config in all accounts
  • Deploy infrastructure consistently

⚠️ Important Considerations

AWS SSO Configuration Make sure your ~/.aws/config file has profiles configured correctly:

[profile product-dev]
sso_start_url = https://your-org.awsapps.com/start
sso_region = eu-central-1
sso_account_id = 123456789012
sso_role_name = ReadOnlyAccess
region = eu-central-1

Rate Limiting AWS has API rate limits. For large numbers of accounts, consider adding delays:

sleep 0.5  # Add to execute_aws_cli_command function

Error Handling The set -euo pipefail directive makes the script fail fast. This is intentional - you want to know immediately if something goes wrong.

Permissions Ensure your SSO role has the necessary permissions for the commands you’re executing. Test with a read-only command first.

🚀 Getting Started

  1. Save the script as run-across-accounts.sh
  2. Make it executable: chmod +x run-across-accounts.sh
  3. Update the PROFILES and REGIONS arrays
  4. Replace aws sts get-caller-identity with your command
  5. Run: ./run-across-accounts.sh

Let me know if you were able to solve your problem with this script!

Sebastian Hesse

About Sebastian Hesse

AWS Cloud Consultant specializing in serverless architectures. Helping teams build scalable, cost-efficient cloud solutions.

Related Articles