AWS SSO ❤️ Terraform

In a previous post (Identity management in AWS), Łukasz wrote about various methods of managing access and users in AWS. One of the methods mentioned is to use AWS Single Sing-On as a way to access AWS.

3 minutes of reading

What is AWS Single Sing-On (SSO)?

This is how we work on our AWS accounts on a daily basis, we also use it quite often in clients’ projects. At the beginning of the year, we also received a new version of AWS CLI. One of the key features brought by the new version of CLI is the ability to authenticate activities using AWS SSO.

The solution significantly increases comfort and improves work in an environment that requires regular account switching and where we do not want to operate on IAM Users and keys at the same time.

What about other tools?

In the case of logging in to the console and authentication for AWS CLI commands, this method of logging in works very well. However, the problem arises when working with so-called “third” tools – in this case, it is Terraform.

Since we often use this tool in our clients’ projects, a solution was needed.

Looking at what is happening in the official repo, the topic is still in “development”

AWS Single Sing-ON + Terraform

So I decided to look for a solution. Below I will show you how to generate a pair of keys in a few steps that can be used when working with Terraform.

Let’s start by logging in (assuming you’re doing it for the first time) from AWS CLI to your AWS account. For this purpose, I call a command that will allow me to configure the CLI to work with an AWS account using AWS SSO. In the terminal I type:

– aws configure sso

Next, I fill in the data that is required to confirm my identity and additional parameters, such as the default region in which I work:

– SSO start URL : https://****.awsapps.com/start ( URL to your AWS SSO),

– SSO Region : eu-west-1 (it is about indicating the region in which your SSO is configured),

– confirmation of Single Sign-On in the browser,

– return to the CLI console,

– Now choose the environment (AWS account) which you want to access,

CLI default client Region: eu-west-1 (here choose your default region in which you work every day),

CLI default output format: json (dependent on preferences)

CLI profile name: default.

I assume that if you use AWS SSO, it means that you have more than one AWS account. In this step, you simply enter the name of the profile (here is the “default” example). With more AWS accounts, it’s a good idea to distinguish profiles to know which one you’re referring to at the moment.

Time for Terraform

For this purpose, I have prepared a script (downloadable file) that will generate a credentials file based on the role obtained during SSO authentication.

The script takes into account entering the profile as a parameter, otherwise it will look for this so-called “default”:

if [ -z "$1" ];
then
  echo "No aws cli profile name provided (default profile will be used). You can add the name after space: aws_credentials profilename"
  profile=${VARIABLE:-default}
else
  profile=$1
fi
role_arn=$(aws iam list-roles --profile $profile | grep /aws-reserved/sso.amazonaws.com/ | grep arn:aws | sed -r 's/^.{20}//' | sed -r 's/.{2}$//')
user_name=$(git config user.name | sed 's/[^A-Za-z0-9+=,.@-]/-/g')
request_credentials() {
  credentials=$(
    aws sts assume-role 
      --profile $profile 
      --role-arn $role_arn 
      --role-session-name $user_name
  )
}
request_credentials

if [ $? -ne 0 ]; then
  aws sso login --profile "$profile"

  if [ $? -ne 0 ]; then
    exit 1
  fi

  request_credentials
fi

access_key_id=$(echo $credentials | perl -n -e'/"AccessKeyId": "([^,]+)"/ && print $1')
secret_key_id=$(echo $credentials | perl -n -e'/"SecretAccessKey": "([^,]+)"/ && print $1')
session_token=$(echo $credentials | perl -n -e'/"SessionToken": "([^,]+)"/ && print $1')

aws configure set --profile "$profile" aws_access_key_id "$access_key_id"
aws configure set --profile "$profile" aws_secret_access_key "$secret_key_id"
aws configure set --profile "$profile" aws_session_token "$session_token"

I call the script using the command:

./aws_credentials.sh <optional profile name>

After the correct execution, you can preview the contents of the created credentials file using the following command (applies to Mac OS / Linux):

cat ~/.aws/credentials

With the keys generated in this way, check how Terraform behaves:

As you can see, it is much better.

Summarizing

AWS SSO, especially in integration with AWS CLI, is still a new approach to providing access to AWS.

At the moment when there is a need to use tools that were based on the current approach of IAM Users, key pairs, etc., you need to look for some alternative solutions.

In the above post, I shared with you my quick idea and solution to the problem with Terraform. I hope you find it useful.