Skip to content

Instantly share code, notes, and snippets.

@fagiani
Created May 24, 2021 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fagiani/6cb9946967dbff1c812f8b579ab411ca to your computer and use it in GitHub Desktop.
Save fagiani/6cb9946967dbff1c812f8b579ab411ca to your computer and use it in GitHub Desktop.
Migrate/Move/Transfer SQS queues between AWS accounts
#!/bin/bash
# This script aims to copy/move AWS SQS queues between accounts using CLI profiles
# It will include tags and attributes
# It will postpone creation of queues that require deadletter queues
# It will create users with tags and related boundary permissions policy related to a queue
# It will postpone creation of queues that require users/policies
# It will process postponed queues recursively
# Regarding queues, users and policies, this script currently DOES NOT:
# - Migrate messages from original to destination queue
# - Create all versions of a Policy, only the default one
# - Create any groups or attaches users to groups
# - Involve any policies that are no the boundary permissions one
# - Create IAM account programatic access/secret key for the created users
# Define the AWS profiles to migrate SQS queues from and to
from=profileA
to=profileB
# Use regex to filter the queues names intended to be migrated
queue_filter='staging\|development\|test'
set -e -o pipefail
migrate_policy () {
echo " CURRENT POLICY: ${1##*/}"
policy_info=$(aws iam get-policy --policy-arn $1 --profile $from | jq -c .Policy)
policy_path=$(jq -cr '.Path //empty' <<< "$policy_info")
policy_description=$(jq -c '.Description //empty' <<< "$policy_info")
policy_tags=$(jq -c '.Tags //empty' <<< "$policy_info")
policy_version=$(jq -cr .DefaultVersionId <<< "$policy_info")
policy_document=$(aws iam get-policy-version --policy-arn $1 --version-id $policy_version --profile $from | jq .PolicyVersion.Document)
aws iam create-policy --policy-name ${1##*/} ${policy_path:+ --path "$policy_path"} --policy-document "${policy_document//$from_id/$to_id}" ${policy_description:+ --description "$policy_description"} ${policy_tags:+ --tags "$policy_tags"} --profile $to
}
migrate_users () {
for user in $1; do
echo " CHECKING USER $user ALREADY EXISTS"
{
aws iam get-user --user-name $user --profile $to
} || {
echo " CREATING USER: $user"
user_info=$(aws iam get-user --user-name $user --profile $from | jq -c .User)
user_path=$(echo $user_info | jq -cr '.Path //empty')
user_tags=$(echo $user_info | jq -c '.Tags //empty')
user_permissions_boundary=$(echo $user_info | jq -cr .PermissionsBoundary.PermissionsBoundaryArn)
if [[ ! -z $user_permissions_boundary ]]; then
echo " CREATING POLICIES FOR USER"
migrate_policy "$user_permissions_boundary"
fi
aws iam create-user ${user_path:+ --path "$user_path"} --user-name $user ${user_permissions_boundary:+ --permissions-boundary "${user_permissions_boundary//$from_id/$to_id}"} ${user_tags:+ --tags "$tags"} --profile $to
aws iam attach-user-policy --user-name $user --policy-arn ${user_permissions_boundary//$from_id/$to_id} --profile $to
}
done
}
migrate_queues () {
postponed=""
for queue in $1; do
echo "CURRENT QUEUE: ${queue##*/}"
attributes=$(aws sqs get-queue-attributes --queue-url $queue --attribute-names All --profile $from | jq -c '.Attributes | del(.QueueArn, .ApproximateNumberOfMessagesDelayed, .CreatedTimestamp, .ApproximateNumberOfMessages, .ApproximateNumberOfMessagesNotVisible, .LastModifiedTimestamp)')
if [[ -z $2 ]] && [[ $attributes =~ "deadLetterTargetArn" ]]; then
echo " POSTPOINING QUEUE"
postponed="$postponed $queue"
else
if [[ $attributes =~ "arn:aws:iam::$from_id:user/" ]]; then
echo " CREATING USERS FOR QUEUE"
migrate_users "$(echo $attributes | grep -Po 'arn:aws:iam::[0-9]{1,12}:user/\K.*?(?=\\)')"
fi
tags=$(aws sqs list-queue-tags --queue-url $queue --profile $from | jq -c .Tags)
echo " ATTRIBUTES: ${attributes//$from_id/$to_id}"
echo " TAGS: $tags"
echo " CREATING QUEUE:"
{
aws sqs create-queue --queue-name ${queue##*/} --attributes ${attributes//$from_id/$to_id} ${tags:+ --tags "$tags"} --profile $to
} || {
echo " POSTPONING QUEUE"
postponed="$postponed $queue"
}
echo "--------------"
fi
done
if [[ ! -z $postponed ]]; then
echo "CREATING POSTPONED QUEUES"
migrate_queues "${postponed// /$'\n'}" true
fi
}
retrieve_account_id () {
aws sts get-caller-identity --profile $1 | jq -cr .Account
}
queues_list () {
aws sqs list-queues --profile $1 | jq -r '.QueueUrls | .[]' | grep $queue_filter
}
remove_queues () {
for queue in $1; do
echo "REMOVING $queue"
aws sqs delete-queue --queue-url $queue --profile $2
done
}
#remove_queues "$(queues_list $to)" "$to"
from_id=$(retrieve_account_id "$from")
to_id=$(retrieve_account_id "$to")
migrate_queues "$(queues_list $from)"
#remove_queues "$(queues_list $from)" "$from"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment