Skip to content

Instantly share code, notes, and snippets.

@drvdana
Last active May 7, 2021 09:23
Show Gist options
  • Save drvdana/40b93bf5813fd6024bb9012948428b04 to your computer and use it in GitHub Desktop.
Save drvdana/40b93bf5813fd6024bb9012948428b04 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import os
import json
import argparse
import subprocess
import configparser
parser = argparse.ArgumentParser(description='Update your AWS CLI Token')
parser.add_argument('token', help='token from your MFA device')
parser.add_argument('--profile', help='aws profile to store the session token', default=os.getenv('AWS_PROFILE'))
parser.add_argument('--arn', help='AWS ARN from the IAM console (Security credentials -> Assigned MFA device). This is saved to your .aws/config file')
parser.add_argument('--credential-path', help='path to the aws credentials file', default=os.path.expanduser('~/.aws/credentials'))
parser.add_argument('--config-path', help='path to the aws config file', default=os.path.expanduser('~/.aws/config'))
parser.add_argument('--region', help='region to connect to use with your session token')
args = parser.parse_args()
if args.profile is None:
parser.error('Expecting --profile or profile set in environment AWS_PROFILE. e.g. "stage"')
config = configparser.ConfigParser()
config.read(args.config_path)
aws_profile = 'profile ' + args.profile
if aws_profile not in config.sections():
config[aws_profile] = {}
if args.arn is None:
if 'aws_arn_mfa' not in config['default']:
parser.error('ARN is not provided. Specify via --arn')
args.arn = config['default']['aws_arn_mfa']
else:
# Update the arn with user supplied one
config['default'] = {}
config['default']['aws_arn_mfa'] = args.arn
# Generate the session token from the default profile based on the environment. We do not want to overwrite these profiles as we wouldn't
# be able to generate another token
curr_env = os.environ.copy()
if 'AWS_PROFILE' in curr_env:
del curr_env['AWS_PROFILE']
result = subprocess.run(['aws', 'sts', 'get-session-token', '--profile', 'default', '--serial-number', args.arn, '--token-code', args.token], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=curr_env)
if result.returncode != 0:
parser.error(result.stderr.decode('utf-8').strip('\n'))
credentials = json.loads(result.stdout.decode('utf-8'))['Credentials']
config[aws_profile]['aws_access_key_id'] = credentials['AccessKeyId']
config[aws_profile]['aws_secret_access_key'] = credentials['SecretAccessKey']
config[aws_profile]['aws_session_token'] = credentials['SessionToken']
config[aws_profile]['source_profile'] = 'default'
if args.region:
config[aws_profile]['region'] = args.region
# Save the changes back to the file
with open(args.config_path, 'w') as configFile:
config.write(configFile)
print('Saved {} credentials to {}'.format(args.profile, args.config_path))
@drvdana
Copy link
Author

drvdana commented Jul 17, 2018

This script will generate a temporary AWS IAM access key and session token given a token code for the mfa device associated with your account, and store it for you in ~/.aws/config.

To use this script:

  1. Install aws-cli
  2. Run aws configure, retrieving your AWS key and secret from IAM
  3. While you're there, note your mfa arn - it will look like arn:aws:iam::123456789012:mfa/user
  4. Run this script aws-update-token --arn <mfa_arn> --profile <staging|prod> --region <aws-region-1> <TOKEN> using your TOKEN from your mfa device (profile can be any name you want to associate with this session token, region is optional and limits the specified profile to that region)
  5. Set an environment variable of AWS_PROFILE matching what you set your profile to above
  6. Test with aws s3 ls

Notes:

  • After the first time running this, your arn will be stored in ~/.aws/config
  • Your session will expire after 12 hours
  • You can setup multiple profiles, and can manage them by setting AWS_PROFILE, or specifying --profile <profile> with most aws cli commands.

Modified for my use from: https://gist.github.com/incognick/c121038dbd2180c683fda6ae5e30cba3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment