Skip to content

Instantly share code, notes, and snippets.

@pwillis-els
Last active June 23, 2023 07:05
Show Gist options
  • Save pwillis-els/44c8b93c64f810622e8516d7ba93d680 to your computer and use it in GitHub Desktop.
Save pwillis-els/44c8b93c64f810622e8516d7ba93d680 to your computer and use it in GitHub Desktop.
How to set up AWS CLI profiles to switch between roles while using Federated SAML authentication

Using profiles, assume-role, and Federated SAML authentication with AWS CLI

Let's say you use a Federated authentication method for AWS (like ADFS), and by default you have access to multiple roles and accounts. You want to be able to easily switch between accounts, roles, and even assume a second role after assuming a first one. The following guide explains how this works using aws-adfs and the AWS CLI.

Background info about profiles

Profiles are how AWS CLI configures the settings for individual credentials, and allows you to switch between them. You can specify a profile either by passing the --profile NAME option to AWS CLI, or with an environment variable AWS_PROFILE=name.

The problem with using AWS_PROFILE is that the boto library will attempt to load a profile with that name, and if it can't, it will immediately die. This makes it hard to use a profile if (for example) it hasn't been created by a program like aws-adfs yet.

So in general you should pass --profile to AWS CLI and aws-adfs to avoid these failures. If you're sure the profile has been created, you can use AWS_PROFILE.

(Note: I don't run this from Windows, so I had to also pass --no-sspi for these commands to work) (Also note: for ADFS, the proper user format is usually DOMAIN\user; authentication may fail if it's not in this format)

Step 1. Install prerequisites

Step 2. Collect role names by authenticating with ADFS

  • Run the following command:
    $ aws-adfs login --region us-east-1 --adfs-host my-adfs-federation-host.example.com
    If you have access to multiple roles/accounts, you should be prompted to select one. Write down the ARN of each account and role. You don't need to continue authenticating during this step.

Step 3. Decide which roles will use which profiles

  • For each role you saw before, come up with a profile name, like product-environment-role. These will become useful later.

Step 4. Authenticate using a profile

  • Pick a role and profile name. Say there is a role arn:aws:iam::0123456789:role/MyAdminRole and we want to create a profile called product-prod-admin. Run the following command:
    $ aws-adfs login \
        --profile product-prod-admin \
        --role-arn arn:aws:iam::0123456789:role/MyAdminRole \
        --region us-east-1 \
        --adfs-host my-adfs-federation-host.example.com
    Now you should have an AWS profile called product-prod-admin. Test it with the following command:
    $ aws sts get-caller-identity --profile product-prod-admin
    If this profile's STS session expires, you can re-authenticate with the following simple command:
    $ aws-adfs login --profile product-prod-admin

Step 5. Setting up a new assume-role profile

  • Once you are logged in with product-prod-admin, you might want to assume a new role and use it transparently from AWS CLI. Let's say the role you want to assume is arn:aws:iam::7654321:role/WebDeploy, and we'll call the profile product-prod-web-deploy.

    Note that this is different AWS account and role, but as long as you set up your roles to allow cross-account role switching, this will work fine.

  • Edit the ~/.aws/config file. Add the following lines:

      [profile product-prod-web-deploy]
      region = us-east-1
      role_arn = arn:aws:iam::7654321:role/WebDeploy
      source_profile = product-prod-admin
    

    This new profile will automatically assume-role into the new role from the product-prod-admin profile.

  • Run a command to confirm it worked:

    $ aws sts get-caller-identity --profile product-prod-web-deploy

    You should see a role like arn:aws:iam::7654321:assumed-role/WebDeploy.

To use these profiles, authenticate first to your primary ADFS-linked profile (aws-adfs login --profile product-prod-admin), and then you can immediately use any AWS CLI command with the second role (aws s3 ls --profile product-prod-web-deploy). If your primary profile's session expires you'll need to login again to use the second role.

You can also now set the AWS_PROFILE environment variable to any of the above profiles and pass it to other commands that use the AWS SDK, like Terraform.

However, tools like Terraform may need extra options to use advanced features like source_profile. In particular you need to set the environment variable AWS_SDK_LOAD_CONFIG=1, and you may also need to set your AWS region with AWS_DEFAULT_REGION=<region name> (though the profile should already have the region stored in it).

Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment