AWS Lambda environment variables → AWS SSM parameters in one (long) bash line
So, you want to use AWS SSM parameters instead of AWS Lambda environment variables? But you already have dozens of variables defined?
Keep calm (tested in production) and use this one-liner.
aws lambda list-functions --query 'Functions[?starts_with(FunctionName, `prod-`) == `true`].FunctionName' | jq '.[]' | xargs -L 1 -I {} aws lambda get-function-configuration --function-name {} --query Environment.Variables | jq -cr 'keys[] as $key | {Name: "/prod/\($key)", Value: "\(.[$key])", Type: "String"}' | xargs -d'\n' -I {} echo "aws ssm put-parameter --cli-input-json '{}'" | xargs -d'\n' -tI {} bash -c "{} || true"
Nobody in sane will run one-liners from the internet without the explanations. So here it is:
aws lambda list-functions --query 'Functions[?starts_with(FunctionName, `prod`) == `true`].FunctionName' | # Select functions
jq '.[]' | # Previous command returns an array, so expand it
xargs -L 1 -I {} aws lambda get-function-configuration --function-name {} --query Environment.Variables | # Get configuration for each function
jq -cr 'keys[] as $key | {Name: "/prod/\($key)", Value: "\(.[$key])", Type: "String"}' | # Craft a JSON for later use with aws ssm
xargs -d'\n' -I {} echo "aws ssm put-parameter --cli-input-json '{}'" | # Craft an aws ssm put-parameter command
xargs -d'\n' -tI {} bash -c "{} || true" # Finally, evaluate that command
BTW copy-pasting it in bash with all the comments will (surprisingly) work fine!:
Some notes:
-
The whole flow assumes single AWS region is used (and defined in
~/.aws/configfor usedAWS_PROFILE). Add--regionoptions where needed. -
You can use any valid query to get function names on the first step.
-
JSON is used as input to
aws ssm put-parameterbecause of automatichttp://andhttps://expansion in some places! This lame behavior was fixed just a few hours prior to writing this article! -
Instead of hustling with
jqon the final stage trying to pass arguments toxarg aws ssm put parameter, IMHO, it’s much more simpler to craft the command you need as a string and then just eval it.
What I’ve learned about bash during crafting this shitty pipeline:
-
Damn
xargsjust "swallows" quotes (both single and double) in its (standard) input when passing values to commands! Use-d(or-0) flag to override this behavior. Compareecho "'test'" | xargs echovsecho "'test'" | xargs -d'\n' echo