Skip to content

Instantly share code, notes, and snippets.

@derekmurawsky
Last active May 30, 2024 20:34
Show Gist options
  • Save derekmurawsky/27aac8d19c0170e28a9a0a2ce1778731 to your computer and use it in GitHub Desktop.
Save derekmurawsky/27aac8d19c0170e28a9a0a2ce1778731 to your computer and use it in GitHub Desktop.
Bash script to push secrets to multiple AWS accounts based on configured CLI profiles.

Script to push secrets to multiple AWS accounts

Warning

Secrets management and distribution is a very tricky subject. Don't use tools like this that you find on the net without thoroughly understanding their risks. For example, using this as-is will result in a secret in your bash history. This script works for us because we have significant compensating controls in the environment where it runs. This may not work well or be allowed by your organiztion. I accept no liability if you use this code and it does something bad!

AWS accounts are a great way to enforce hard boundaries on infrastructure and the code that runs on it. However, that can often make it more difficult to manage things like secrets across accounts. This script helps with that by pushing a secret to the same location in secrets manager across several AWS accounts for a properly configured user or service.

Though it is a best practice to use a separate secret for each environment, that is often not possible with certain third parties or organizations. I typically require using at least one separate secret for production vs non-production environments with a separate secret for each environment being strongly preferred.

#!/bin/bash
# This script pushes secrets to multiple AWS accounts. It should be used with IAC where IAC creates the secret for this script to push to.
# This ensures that IAC knows where the secrets are stored, but that the secrets themselves can be managed by a separate process.
# This script relies on the AWS CLI being installed and configured properly (profiles and auth) with the necessary permissions.
# The default behaviour is to update a secret with a new value. To create a new secret, use the -c flag.
usage() { echo "Usage: $0 [-p target,aws,profiles] [-s <secret string>] -d \"Description\" -k \"KMS Key Id create only\" -n \"Secret Name\" " 1>&2; exit 1; }
while getopts ":cd:kn:p:s:" flag
do
case "$flag" in
c) echo "Create New Secret: $OPTARG"
create=1;;
d) echo "Description: $OPTARG"
description="$OPTARG";;
k) echo "KMS Key: $OPTARG"
kmsKey="$OPTARG";;
n) echo "Secret Name: $OPTARG"
secretName="$OPTARG";;
p) echo "Profiles to push to: $OPTARG"
profiles="$OPTARG";;
s) echo "Secret String: ***"
secretString="$OPTARG";;
?) usage;;
esac
done
# Disable bash history for this run
set +o history
# Handle create vs update
baseCommand="aws secretsmanager"
if [[ "$create" == 1 ]]; then
baseCommand="$baseCommand create-secret --name \"$secretName\""
else
baseCommand="$baseCommand update-secret --secret-id \"$secretName\""
fi
if [ -n "$kmsKey" ]; then
baseCommand="${baseCommand} --kms-key-id \"$kmsKey\""
fi
baseCommand="$baseCommand --secret-string \"$secretString\""
if [ -n "$description" ]; then
baseCommand="${baseCommand} --description \"$description\""
fi
for i in ${profiles//,/ }
do
echo Command: AWS_PROFILE="$i" "${baseCommand[*]} --no-cli-pager"
eval "AWS_PROFILE=$i ${baseCommand[*]} --no-cli-pager"
done
# Re-enable bash history
set -o history
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment