Last active
August 18, 2017 16:38
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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