Skip to content

Instantly share code, notes, and snippets.

@dex4er
Created November 19, 2024 14:20
Show Gist options
  • Save dex4er/634c27dee1b141e2c7e9d24414bade3c to your computer and use it in GitHub Desktop.
Save dex4er/634c27dee1b141e2c7e9d24414bade3c to your computer and use it in GitHub Desktop.
#!/bin/bash
set -eu
set -o pipefail
shopt -s inherit_errexit
if [[ $# -lt 4 ]]; then
echo "Usage: $0 aws_profile_from aws_region_from aws_profile_to aws_region_to [shell patterns]"
exit 99
fi
aws_profile_from=$1 aws_region_from=$2 aws_profile_to=$3 aws_region_to=$4
shift 4
patterns=("$@")
if [[ ${#patterns[*]} == 0 ]]; then
patterns=("*")
fi
unset AWS_ACCESS_KEY_ID AWS_PROFILE AWS_REGION AWS_SECRET_ACCESS_KEY AWS_SESSION_EXPIRATION AWS_SESSION_TOKEN
function log() {
echo "$(LC_ALL=C date '+%Y/%m/%d %H:%M:%S') $*" 1>&2
}
function log_from() {
log "[${aws_profile_from}](${aws_region_from}) $*"
}
function log_to() {
log "[${aws_profile_to}](${aws_region_to}) $*"
}
function aws_from() {
msg=$*
log_from "aws ${msg%%--*}"
env AWS_PROFILE="${aws_profile_from}" AWS_REGION="${aws_region_from}" aws "$@"
}
function aws_to() {
msg=$*
log_to "aws ${msg%%--*}"
env AWS_PROFILE="${aws_profile_to}" AWS_REGION="${aws_region_to}" aws "$@"
}
function crane_auth() {
msg=$*
log "crane auth ${msg%%--*}"
crane auth "$@"
}
function crane_cp() {
msg=$*
log "crane cp ${msg%%--*}"
crane cp "$@"
}
function crane_ls() {
msg=$*
log "crane ls ${msg%%--*}"
crane ls "$@"
}
account_id_from=$(aws_from sts get-caller-identity --query "Account" --output text)
account_id_to=$(aws_to sts get-caller-identity --query "Account" --output text)
log_from "${account_id_from}"
log_to "${account_id_to}"
aws_from ecr get-login-password | crane_auth login "${account_id_from}.dkr.ecr.${aws_region_from}.amazonaws.com" --username AWS --password-stdin
aws_to ecr get-login-password | crane_auth login "${account_id_to}.dkr.ecr.${aws_region_to}.amazonaws.com" --username AWS --password-stdin
declare -A repos_from
for repo in $(aws_from ecr describe-repositories --query 'repositories[].repositoryName' --output text); do
for pattern in "${patterns[@]}"; do
case "${repo}" in
${pattern}) repos_from[${repo}]=${repo} ;;
esac
done
done
declare -A repos_to
for repo in $(aws_to ecr describe-repositories --query 'repositories[].repositoryName' --output text); do
for pattern in "${patterns[@]}"; do
case "${repo}" in
${pattern}) repos_to[${repo}]=${repo} ;;
esac
done
done
declare -A tags_to
for repo in "${repos_from[@]}"; do
if [[ -z ${repos_to[${repo}]:-} ]]; then
aws_to ecr create-repository --repository-name "${repo}" >/dev/null
repo_from_arn=$(aws_from ecr describe-repositories --repository-names "${repo}" --query repositories[].repositoryArn --output text)
repo_to_arn=$(aws_to ecr describe-repositories --repository-names "${repo}" --query repositories[].repositoryArn --output text)
while read -r key value; do
aws_to ecr tag-resource --resource-arn "${repo_to_arn}" --tags "Key=${key},Value=${value}"
done < <(aws_from ecr list-tags-for-resource --resource-arn "${repo_from_arn}" --query 'tags[]' --output text)
fi
tags_to=()
for tag in $(crane_ls "${account_id_to}.dkr.ecr.${aws_region_to}.amazonaws.com/${repo}"); do
tags_to[${tag}]=${tag}
done
for tag in $(crane_ls "${account_id_from}.dkr.ecr.${aws_region_from}.amazonaws.com/${repo}"); do
if [[ -z ${tags_to[${tag}]:-} ]]; then
crane_cp \
"${account_id_from}.dkr.ecr.${aws_region_from}.amazonaws.com/${repo}:${tag}" \
"${account_id_to}.dkr.ecr.${aws_region_to}.amazonaws.com/${repo}:${tag}"
fi
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment