Skip to content

Instantly share code, notes, and snippets.

@Danesz
Forked from rob1256/aws-configure.py
Created November 12, 2024 23:36
Show Gist options
  • Save Danesz/41d3e1943b471d93d49cbfc2367c2fdd to your computer and use it in GitHub Desktop.
Save Danesz/41d3e1943b471d93d49cbfc2367c2fdd to your computer and use it in GitHub Desktop.
Auto-populate aws config with SSO roles using Python
import os.path
import subprocess
import glob
import boto3
import json
SSO_START_URL = "https://XXXX.awsapps.com/start/"
SSO_SESSION_CONFIG_NAME = "XXX"
def getAccessTokenFromSsoSession():
accessToken = None
ssoCacheDir = os.path.expanduser('~/.aws/sso/cache/')
json_files = list(filter(os.path.isfile, glob.glob(ssoCacheDir + "*")))
json_files.sort(key=lambda x: os.path.getmtime(x))
json_file = json_files[-1]
with open(json_file) as file:
data = json.load(file)
if 'accessToken' in data:
accessToken = data['accessToken']
if accessToken is None:
raise Exception("No access token found")
return accessToken
def getIsLoggedInViaSso():
try:
getListOfSsoAccounts()
return True
except Exception as e:
return False
def getListOfSsoAccounts():
accessToken = getAccessTokenFromSsoSession()
ssoClient = boto3.client('sso', region_name='eu-west-2')
return ssoClient.list_accounts(accessToken=accessToken, maxResults=100)['accountList']
def getListOfSsoAccountRolesForAccount(accountId):
accessToken = getAccessTokenFromSsoSession()
ssoClient = boto3.client('sso', region_name='eu-west-2')
return ssoClient.list_account_roles(accessToken=accessToken, maxResults=100, accountId=accountId)['roleList']
def getCombinedListOfSsoAccountsAndRoles():
roles = []
accounts = getListOfSsoAccounts()
for account in accounts:
rolesForAccount = getListOfSsoAccountRolesForAccount(account['accountId'])
for role in rolesForAccount:
roles.append({'accountId': account['accountId'], 'roleName': role['roleName'], 'accountName': account['accountName']})
return roles
def configureSsoSessionConfig():
ssoSessionConfigExists = subprocess.run(["grep", "sso-session BPP", os.path.expanduser("~/.aws/config")], stdout=subprocess.PIPE)
if ssoSessionConfigExists.stdout.decode() == "":
cprint("Configuring AWS config session for SSO", "blue")
echoSsoConfig = subprocess.run(
["echo", SSO_SESSION_CONFIG_NAME, "\n" + SSO_START_URL, "\neu-west-2", "\nsso:account:access"],
check=True, capture_output=True)
subprocess.run(["aws", "configure", "sso-session"], input=echoSsoConfig.stdout)
def getProfileNameFromRole(role):
return role['accountId'] + "-" + role['roleName']
def configureSsoProfiles():
cprint("Configuring AWS profiles for SSO", "blue")
roles = getCombinedListOfSsoAccountsAndRoles()
for role in roles:
profileName = getProfileNameFromRole(role)
profileExists = subprocess.run(["grep", "profile " + profileName, os.path.expanduser("~/.aws/config")], stdout=subprocess.PIPE)
if profileExists.stdout.decode() == "":
subprocess.run(["aws", "configure", "--profile", profileName, "set", "sso_session", SSO_SESSION_CONFIG_NAME], check=True)
subprocess.run(["aws", "configure", "--profile", profileName, "set", "sso_account_id", role['accountId']], check=True)
subprocess.run(["aws", "configure", "--profile", profileName, "set", "sso_role_name", role['roleName']], check=True)
subprocess.run(["aws", "configure", "--profile", profileName, "set", "region", "eu-west-2"], check=True)
subprocess.run(["aws", "configure", "--profile", profileName, "set", "output", "json"], check=True)
def login():
configureSsoSessionConfig()
isAlreadyLoggedIn = getIsLoggedInViaSso()
if not isAlreadyLoggedIn:
input("AWS SSO login requires you to authorise via a browser, a window will open on pressing enter for you to login and authorise")
subprocess.run(["aws", "sso", "login", "--sso-session", SSO_SESSION_CONFIG_NAME], check=True)
configureSsoProfiles()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment