Skip to content

Instantly share code, notes, and snippets.

@blohr-hs
Last active August 18, 2017 16:38
Show Gist options
  • Save blohr-hs/adde6597c3556ca637917f84d2f4390a to your computer and use it in GitHub Desktop.
Save blohr-hs/adde6597c3556ca637917f84d2f4390a to your computer and use it in GitHub Desktop.
Example that shows how to access secure secret values using the EC2 Parameter Store service
#!/usr/bin/env python3
"""
Set environment variables to values from EC2 Parameter Store.
Works similarly to /usr/bin/env, except that the `key=value` pairs passed are a mapping from desired environment
variable name to EC2 Parameter Store parameter name. In the called process, each such environment variable will have the
value obtained from the Parameter Store. Encrypted secure variables will be decrypted before being stored in the
environment variables.
The AWS credentials used to run this script must have IAM ssm:GetParameters permission on each of the listed parameters.
The decryption only uses the key was used to encrypt the parameter in the first place, which may vary for each
parameter. Therefore, the current credentials must have kms:Decrypt permission on each KMS key used to encrypt each
secure parameter requested.
Example:
$ params2env.py DB_PASSWORD=/app/databasePassword API_KEY=/app/serviceSecretKey /path/to/my_application
"""
import os
import subprocess
import sys
from argparse import ArgumentParser
import boto3
def main():
args = parse_args()
requested_env_vars = parse_kv_pairs(args.kv_pairs)
ec2_params = get_ec2_parameters(requested_env_vars.values(), args.profile)
env_vars = match_env_to_params(ec2_params, requested_env_vars)
os.environ.update(env_vars)
run_result = subprocess.run(args.cmd_args, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, encoding="UTF-8")
return run_result.returncode
def parse_args():
arg_parser = ArgumentParser(description="Run command with environment variables set from EC2 Parameter Store",
usage="%(prog)s [-h] [name=value ...] [command [argument ...]]")
arg_parser.add_argument("all_args", nargs="+", metavar="[name=value ...] [command [argument ...]]")
arg_parser.add_argument("-p", "--profile",
help="AWS CLI profile to use for authentication")
cli_args = arg_parser.parse_args()
kv_pairs, cmd_args = partition_cli_args(cli_args.all_args)
cli_args.kv_pairs = kv_pairs
cli_args.cmd_args = cmd_args
return cli_args
def partition_cli_args(cli_args):
# TODO: This will not work if the command or its arguments have an equals sign. Not for production use...
kv_pairs = []
cmd_args = []
for arg in cli_args:
if "=" in arg:
kv_pairs.append(arg)
else:
cmd_args.append(arg)
return kv_pairs, cmd_args
def parse_kv_pairs(kv_list):
return dict(pair.split('=') for pair in kv_list)
def get_ec2_parameters(param_names, profile=None):
session_args = {'profile_name': profile} if profile else {}
session = boto3.session.Session(**session_args)
ssm_client = session.client("ssm")
ssm_response = ssm_client.get_parameters(Names=list(param_names), WithDecryption=True)
if len(ssm_response['InvalidParameters']):
raise Exception("The following SSM parameters were not successfully retrieved:", ssm_response['InvalidParameters'])
return {p['Name']: p['Value'] for p in ssm_response['Parameters']}
def match_env_to_params(ec2_params, requested_env_vars):
return {env_var: ec2_params[param_name] for env_var, param_name in requested_env_vars.items()}
if __name__ == "__main__":
return_code = main()
sys.exit(return_code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment