Clone AWS IAM Roles Across Environments/Accounts Using AWS CLI Automation

The Challenge: Scaling AWS IAM Role Across Multiple Environment
Picture this: you’ve just finished setting up your AWS infrastructure for development, complete with perfectly configured IAM roles for secure resource access. Everything works beautifully. Now comes the inevitable next step — replicating this setup for your UAT (User Acceptance Testing) environment.
Sound familiar? This is a common scenario that many AWS engineers face when managing multi-environment deployments.
Here’s what I was dealing with:
Multiple IAM roles (5+) configured for my application’s dev environment
Each role using role-based authentication for AWS resource access
Need to duplicate these roles for UAT with minimal changes
The only difference: resource ARNs pointing to UAT-specific resources
Both environments residing in the same AWS account but different VPCs
The manual approach? Copy-paste each role configuration, update ARNs, rename roles, attach policies… rinse and repeat. Not only time-consuming but also error-prone.
The smart approach? Automate the entire process using AWS CLI.
In this guide, I’ll walk you through a battle-tested CLI method that automates IAM role cloning across environments. Whether you’re moving roles between VPCs in the same account or even across different AWS accounts, this approach scales beautifully and saves hours of manual work.
Prerequisites: Setting Up Your AWS CLI Environment
Before we dive into the automation magic, let’s ensure your local environment is properly configured. Don’t worry — this is a one-time setup that will serve you well beyond this tutorial.
Step 1: Install AWS CLI v2
For this guide, I’m using Ubuntu, but the process is similar across Linux distributions. AWS provides comprehensive installation instructions in their official documentation:
Step 2: Configure Your AWS Credentials
Once installed, open your terminal and run:
aws configure
This interactive command will prompt you for:
Access Key ID — Your AWS programmatic access key
Secret Access Key — The corresponding secret
Default Region — Your preferred AWS region (e.g.,
us-east-1
)Output Format — Recommended:
json
for better script compatibility
Pro Tip: Managing Multiple AWS Accounts
Here’s where things get interesting — and this is a game-changer for developers juggling multiple environments or clients. AWS CLI supports named profiles, allowing you to seamlessly switch between different AWS accounts.
# Configure your personal AWS account
aws configure --profile personal
# Configure your work/company account
aws configure --profile work
# Use commands with specific profiles
aws s3 ls --profile personal # Lists S3 buckets from personal account
aws s3 ls --profile work # Lists S3 buckets from work account
This approach eliminates the constant reconfiguration headache and reduces the risk of accidentally running commands against the wrong account — trust me, we’ve all been there!
For This Tutorial
To keep things focused and straightforward, I’ll demonstrate the role migration process using a single AWS account. However, the same principles and scripts work seamlessly across multiple accounts when using profiles.
Implementation: Building the IAM Role Cloning Solution
Now for the exciting part — let’s build our automated role cloning system. I’ll break this down into digestible steps, explaining the logic behind each component.
Step 1: Creating the Core Clone Function
The heart of our solution is a bash function that handles the heavy lifting. This function will:
Extract trust relationships from the source role
Clone all attached managed and inline policies
Apply intelligent naming conventions
Handle error scenarios gracefully
Here’s the complete clone_role()
function:
clone_role() {
local original_role=$1
local new_role=$(echo $orginal_role | sed 's/^dev_/test_/')
echo "Cloning $original_role to $new_role"
echo " Getting trust relationship"
# update this with --profile argument for fetch it from other account
aws iam get-role --role-name $original_role\
--query 'Role.AssumeRolePolicyDocument'\
--ouput json > /tmp/trust-policy-$new_role.json
if [$? -ne 0]; then
echo " ERROR: Failed to get trust policy for $original_role"
fi
# create new role
echo " Creating new role $new_role"
aws iam create-role \
--role-name $new_role \
--assume-role-policy-document file:///tmp/trust-policy-$new_role.json \
--description "Cloned from $original_role"
if [$? -ne 0]; then
echo " ERROR: Failed to create role $new_role"
fi
# get and attach managed policies
echo " Getting Mangaed policies attached $original_role:"
managed_policies=$(aws iam list-attached-role-policies --role-name $original_role --query 'AttachedPolicies[].PolicyArn' --ouput text)
if [! -z "$managed_policies"]; then
for policy_arn in $managed_policies; do
echo " Attaching managed Policy: $policy_arn"
aws iam attach-role-policy --role-name $new_role --policy-arn $policy-arn
done
fi
# get and attach inline policies
echo " Getting inline policies..."
inline_policies=$(aws iam list-role-policies --role-name $original_role --query 'PolicyNames' --output text)
if [ ! -z "$inline_policies" ]; then
for policy_name in $inline_policies; do
echo " Copying inline policy: $policy_name"
# Get policy document
aws iam get-role-policy \
--role-name $original_role \
--policy-name $policy_name \
--query 'PolicyDocument' \
--output json > /tmp/inline-policy-$policy_name.json
new_policy_name = $(echo $policy_name | sed 's/dev/test/g')
aws iam put-role-policy \
--role-name $new_role \
--policy_name $new_policy_name \
--policy-document file:///tmp/inline-policy-$policy_name.json
done
fi
# copy tags (optional)
echo " Copying tags..."
tags=$(aws iam list-role-tags --role-name $original_role --query 'Tags' --output
if [ "$tags" != "[]" ]; then
# Update Environment tag from dev to test
updated_tags=$(echo $tags | jq 'map(if .Key == "Environment" then .Value = "test" else . end)')
echo $updated_tags > /tmp/tags-$new_role.json
aws iam tag-role --role-name $new_role --tags file:///tmp/tags-$new_role.json
fi
echo " ✅ Successfully cloned $original_role to $new_role"
echo ""
}
Step 2: Orchestrating the Complete Solution
Now let’s build the main script that ties everything together:
#!/bin/bash
# Original role names
ORIGINAL_ROLES=(
# put your roles here
)
echo "Starting IAM role cloning process..."
echo "========================================"
aws sts get-caller-identity > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "ERROR: AWS CLI not configured or no permissions"
exit 1
fi
for role in "${ORIGINAL_ROLES[@]}"; do
clone_role $role
done
# Cleanup temporary files
echo "Cleaning up temporary files..."
rm -f /tmp/trust-policy-*.json
rm -f /tmp/inline-policy-*.json
rm -f /tmp/tags-*.json
echo "========================================"
echo "✅ Role cloning completed!"
echo ""
echo "New roles created:"
for role in "${ORIGINAL_ROLES[@]}"; do
new_role=$(echo $role | sed 's/^dev_/test_/')
echo " - $new_role"
done
Key Features of This Implementation:
Intelligent Naming: Automatically converts
dev_
prefixes totest_
Comprehensive Cloning: Copies trust policies, managed policies, inline policies, and tags
Error Handling: Gracefully handles failures and provides clear error messages
Environment-Aware: Updates environment tags appropriately
Clean Operations: Automatically removes temporary files
Pro Tips for Customization:
Cross-Account Migration: Add
--profile
flags to AWS commands for different accountsCustom Naming: Modify the
sed
pattern for your naming conventionsSelective Cloning: Add conditions to skip certain policies or tags
Ready to Use?
The complete, production-ready script is available in my GitHub repository:
Feel free to clone, customize, and adapt it to your specific requirements. The script is configured for dev-to-test migration but can be easily modified for any environment combination.
Thank you for taking the time to read through this guide! I hope this automation solution saves you as much time and effort as it has saved me. There’s nothing quite like watching a script handle tedious manual work while you focus on more strategic tasks.
If you found this helpful, please follow me for more AWS automation tips, infrastructure-as-code tutorials, and DevOps best practices. I regularly share battle-tested solutions from real-world scenarios.
Happy coding! 🚀
Subscribe to my newsletter
Read articles from DEEPAK M S directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
