Last active
July 31, 2025 14:06
-
-
Save jesperalmstrom/111c8ab187cdfe1a9a4e40f6e61308bd to your computer and use it in GitHub Desktop.
Generate AWS sso config file with profiles for all accounts in organization
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
import boto3 | |
import argparse | |
import os | |
import sys | |
import configparser | |
import logging | |
import shutil # newly added import | |
from datetime import datetime | |
# Constants | |
ROLES = ["Admin", "GodMode", "ReadOnly"] | |
# Configure logging | |
logging.basicConfig( | |
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" | |
) | |
""" | |
π AWS SSO Config Generator π | |
Tired of manually configuring AWS profiles for all your accounts? This script is here to help! | |
It automatically generates AWS SSO profiles based on your organization's accounts. | |
β¨ Features: | |
- Fetches all active accounts from your AWS Organization. | |
- Creates/updates profiles for different roles (Admin, GodMode, ReadOnly). | |
- Works with multiple SSO sessions for different organizations. | |
- Backs up your existing config file before making changes. | |
π Prerequisites: | |
1. Configure AWS SSO: | |
`aws configure sso` | |
2. Install boto3: | |
`pip install boto3` | |
π οΈ Usage: | |
--sso-session (str): The name of your SSO session (required). | |
--config-file (str): Path to your AWS config file (optional, defaults to ~/.aws/config). | |
π¬ Example: | |
`python generate_aws_sso_config.py --sso-session my-cool-org-sso` | |
""" | |
def list_accounts_with_sso(): | |
try: | |
sso_client = boto3.client("organizations") | |
paginator = sso_client.get_paginator("list_accounts") | |
iterator = paginator.paginate(PaginationConfig={"MaxResults": 20}) | |
accounts = [] | |
for page in iterator: | |
# Filter only ACTIVE accounts | |
active_accounts = [ | |
acc for acc in page["Accounts"] if acc["Status"] == "ACTIVE" | |
] | |
accounts.extend(active_accounts) | |
return accounts | |
except Exception as e: | |
logging.error(f"π Failed to list accounts: {e}") | |
sys.exit(1) | |
def read_config(config_path): | |
config = configparser.ConfigParser() | |
config.read(os.path.expanduser(config_path)) | |
return config | |
def find_sso_session_configs(config): | |
sso_sessions = {} | |
for section in config.sections(): | |
if section.startswith("sso-session "): | |
session_name = section.split(" ", 1)[1] | |
sso_sessions[session_name] = dict(config[section]) | |
return sso_sessions | |
def get_sso_session_details(config, sso_session_name): | |
section = f"sso-session {sso_session_name}" | |
if section not in config.sections(): | |
logging.error(f"β SSO session '{sso_session_name}' not found in config file.") | |
sys.exit(1) | |
return config[section] | |
def generate_aws_profiles(config, session_name, accounts, region): | |
for account in accounts: | |
account_name = account["Name"] | |
profile_name_base = account_name.replace(" ", "--") | |
account_id = account["Id"] | |
for role in ROLES: | |
profile_name = f"{profile_name_base}-{role}" | |
profile_section = f"profile {profile_name}" | |
if not config.has_section(profile_section): | |
config.add_section(profile_section) | |
logging.debug(f"β¨ Creating profile: {profile_name}") | |
else: | |
logging.debug(f"π Updating profile: {profile_name}") | |
config.set(profile_section, "sso_session", session_name) | |
config.set(profile_section, "sso_account_id", account_id) | |
config.set(profile_section, "sso_role_name", role) | |
config.set(profile_section, "region", region) | |
def write_config(config, config_path): | |
expanded_path = os.path.expanduser(config_path) | |
if os.path.exists(expanded_path): | |
timestamp = datetime.now().strftime("%Y%m%d%H%M%S") | |
backup_path = f"{expanded_path}.backup.{timestamp}" | |
shutil.copy(expanded_path, backup_path) | |
logging.info(f"π‘οΈ Config file backed up to {backup_path}") | |
with open(expanded_path, "w") as config_file: | |
config.write(config_file) | |
def main(): | |
parser = argparse.ArgumentParser(description="Generate AWS SSO Config") | |
parser.add_argument( | |
"--sso-session", required=True, help="The organization SSO session name" | |
) | |
parser.add_argument( | |
"--config-file", default="~/.aws/config", help="Path to AWS config file" | |
) | |
args = parser.parse_args() | |
sso_session_name = args.sso_session | |
config_file = args.config_file | |
config = read_config(config_file) | |
sso_session_details = get_sso_session_details(config, sso_session_name) | |
region = sso_session_details.get("sso_region") | |
if not region: | |
logging.error(f"β sso_region not found for SSO session '{sso_session_name}'") | |
sys.exit(1) | |
accounts = list_accounts_with_sso() | |
logging.info(f"π Found {len(accounts)} accounts") | |
generate_aws_profiles(config, sso_session_name, accounts, region) | |
write_config(config, config_file) | |
logging.info( | |
f"β AWS SSO configuration updated {config_file} ({len(accounts)} * {len(ROLES)} profiles) successfully!" | |
) | |
if __name__ == "__main__": | |
if "AWS_PROFILE" not in os.environ: | |
logging.error( | |
"π AWS_PROFILE is not set. Please set it to your management account profile." | |
) | |
sys.exit(1) | |
if "AWS_REGION" not in os.environ: | |
logging.error("π AWS_REGION must be set.") | |
sys.exit(1) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment