Keep your AWS CLI config fresh with Cog

ajkerrigan

AJ Kerrigan

Posted on March 28, 2024

Keep your AWS CLI config fresh with Cog

The Problem

I have...

  • Access to an ever-shifting set of AWS accounts and permissions sets, courtesy of IAM Identity Center (formerly AWS SSO).
  • Undying fondness for aws-vault to securely cache my session credentials.

I want...

  • A set of AWS CLI profiles automatically defined in ~/.aws/config, based on all of the permission sets available to me through IAM Identity Center.
  • Those profiles to "just work", in that:
    • They transparently refresh short-lived credentials or launch a browser-based SSO login window as needed.
    • They don't trip up external utilities that read an AWS CLI configuration.
  • The ability to add profiles manually for special cases, without interfering with the autogenerated profiles.

An Opinionated Solution

For a long time, I solved this problem with custom scripts. And that was fine! My workflow felt so specific to my tastes that it wasn't worth packaging.

But then a couple things happened:

  • I saw some of Cog's use cases and realized my custom scripts were just a low budget reimplementation of what Cog already did well.
  • I was exploring different Python packaging tools, but none of my previous work or personal experience gave me a reason to use Hatch.

So I decided to convert my custom nonsense into a Hatch-based package that would play nicely with Cog:

https://pypi.org/project/aws-sso-config-builder/

Bird.
Bird.
Stone.

How I Use It

The aws-sso-config-builder tool doesn't require this workflow - the usage section of the README includes alternatives. But this is how I work:

Install Cog and aws-sso-config-builder

Use pipx to install Cog and my aws-sso-config-builder tool in the same environment:

pipx install --verbose cogapp
pipx inject --verbose cogapp aws-sso-config-builder
Enter fullscreen mode Exit fullscreen mode

Update the AWS CLI config file

Add a block like this to the ~/.aws/config file:

# [[[cog
# import cog
# from aws_sso_config_builder.gen_config import generate_config_blocks
#
# cog.outl(generate_config_blocks(
#     sso_directories=["home", "work"],
#     profile_template="""
#         [profile {profile_name}-sso]
#         sso_session = {sso_session}
#         sso_account_id = {account_id}
#         sso_role_name = {role_name}
#         output = json
#         region = us-east-2
#
#         [profile {profile_name}]
#         credential_process = {aws_vault_path} exec --json {profile_name}-sso
#         output = json
#         region = us-east-2
#     """,
#     regex_replacements={
#         "Production": "prod",
#         "Sandbox": "sbx"
#     },
#     aws_vault_path="/home/aj/go/bin/aws-vault",
# ))
# ]]]
# [[[end]]]
Enter fullscreen mode Exit fullscreen mode

Which defines:

  • IAM Identity Center directory names / organizations that I have access to
  • The skeleton of a config block that should be generated for each account/permission set
  • A few regular expressions to customize / normalize profile names
  • The path to my aws-vault binary

Refresh my config file

Now I have:

  • Cog available
  • aws-sso-config-builder providing a mechanism for looking up permission sets
  • A template block in my config file

So when I run:

cog -r ~/.aws/config
Enter fullscreen mode Exit fullscreen mode

It replaces everything between ]]] and [[[end]]] with one rendered profile_template block per permission set:

...template block from above...
]]]
...many other profiles...

[profile sbx-AJ-AWSReadOnlyAccess-sso]
sso_session = stacklet
sso_account_id = 111111111111
sso_role_name = AWSReadOnlyAccess
output = json
region = us-east-2

[profile sbx-AJ-AWSReadOnlyAccess]
credential_process = /home/aj/go/bin/aws-vault exec --json sbx-AJ-AWSReadOnlyAccess-sso
output = json
region = us-east-2

[profile sbx-AJ-AWSAdministratorAccess-sso]
sso_session = stacklet
sso_account_id = 111111111111
sso_role_name = AWSAdministratorAccess
output = json
region = us-east-2

[profile sbx-AJ-AWSAdministratorAccess]
credential_process = /home/aj/go/bin/aws-vault exec --json sbx-AJ-AWSAdministratorAccess-sso
output = json
region = us-east-2
[[[end]]]
Enter fullscreen mode Exit fullscreen mode

And from there, it's easy for me to switch among any CLI profiles I have. The profile names are verbose enough that it's very clear which account/permissions I have, and through some shell helpers it's still friendly to bounce around:

❯ asp sbx-AJ-AWSReadOnlyAccess

~ via 🐍v3.12.2 (cogapp) on ☁️  sbx-AJ-AWSReadOnlyAccess (us-east-2)
❯
Enter fullscreen mode Exit fullscreen mode

Should you use this?

Probably not. But if you got this far in the post... maybe? Thanks for reading in any case, you deserve some kanelbullar. Boy those things are delicious.

💖 💪 🙅 🚩
ajkerrigan
AJ Kerrigan

Posted on March 28, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related