Created
November 5, 2024 11:01
-
-
Save rob1256/977bb8d59304700cf12d29573f1736f8 to your computer and use it in GitHub Desktop.
Auto-populate aws config with SSO roles using Python
This file contains 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
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