Skip to content

Instantly share code, notes, and snippets.

@ruanbekker
Last active March 1, 2023 05:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ruanbekker/6ed2cdae4ee119a7cf7a1ae609065b82 to your computer and use it in GitHub Desktop.
Save ruanbekker/6ed2cdae4ee119a7cf7a1ae609065b82 to your computer and use it in GitHub Desktop.
Python Script to Rotate AWS Access Keys and Update them in their Credential Provider
#!/usr/local/bin/python
"""
Requires Boto3 and AWSCLI configured
- accepts argument of profile name that needs to be rotated
- updates config upon aws access key rotation
"""
import boto3
import argparse
import os
import sys
import ConfigParser
from shutil import copyfile
def make_connection(profile):
client = boto3.Session(profile_name=profile, region_name='eu-west-1').client('iam')
return client
def backup_config():
copyfile(os.path.expanduser('~/.aws/credentials'), os.path.expanduser('~/.aws/credentials') + '.bak')
def get_user():
username = client.get_user().get('User').get('UserName')
return username
def create_access_key(username):
access_key = client.create_access_key(UserName=username)
return access_key
def read_config(profile):
old_access_key = {}
config = ConfigParser.RawConfigParser(allow_no_value=True)
config.read(os.path.expanduser('~/.aws/credentials'))
aws_access_key_id = config.get(profile, 'aws_access_key_id')
aws_secret_access_key = config.get(profile, 'aws_secret_access_key')
old_access_key['aws_access_key_id'] = aws_access_key_id
old_access_key['aws_secret_access_key'] = aws_secret_access_key
return old_access_key
def update_config(old_aws_access_key_id, old_aws_secret_access_key, new_aws_access_key_id , new_aws_secret_access_key):
rawconfig = open(os.path.expanduser('~/.aws/credentials'))
rc = rawconfig.read()
rc = rc.replace(old_aws_access_key_id, new_aws_access_key_id)
rc = rc.replace(old_aws_secret_access_key, new_aws_secret_access_key)
rcf = open(os.path.expanduser('~/.aws/credentials'), 'w')
rcf.write(rc)
rcf.flush()
rcf.close()
return 'config updated'
def delete_key(username, aws_access_key_id):
delete_key = client.delete_access_key(UserName=username, AccessKeyId=aws_access_key_id)
return 'key deleted'
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Rotate Access Keys.")
parser.add_argument('-p', '--profile', help='the profile to rotate the key for')
args = parser.parse_args()
local_profiles = ConfigParser.RawConfigParser(allow_no_value=True)
local_profiles.read(os.path.expanduser('~/.aws/credentials'))
if args.profile not in local_profiles.sections():
print('Chosen profile does not exist')
sys.exit(1)
if args.profile != None:
client = make_connection(args.profile)
if len(client.list_access_keys().get('AccessKeyMetadata')) == 0:
print('No access keys configured')
sys.exit(1)
if len(client.list_access_keys().get('AccessKeyMetadata')) == 2:
print('Reached maximum number of access keys for account. Please delete one key before continuing')
sys.exit(1)
backup = backup_config()
username = get_user()
new_access_key = create_access_key(username)
old_access_key = read_config(args.profile)
update = update_config(
old_access_key.get('aws_access_key_id'),
old_access_key.get('aws_secret_access_key'),
new_access_key.get('AccessKey').get('AccessKeyId'),
new_access_key.get('AccessKey').get('SecretAccessKey')
)
delete = delete_key(username, old_access_key.get('aws_access_key_id'))
print('Access key for profile {} has been rotated'.format(args.profile))
else:
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment