[#AWS] Authentication made easy !

Security is one of the most important matters when it comes to cloud infrastructure. 

Especially when it comes to large infrastructure created with IaC such as terraform where many developers are involved. 

In these large projects, dealing with multiple AWS accounts, MFA, Roles, chained roles can make the code complex, hard to maintain and slows down the development. 

1 –  AWS Profiles 

An AWS profile is basically a credential file that is located here : ~/.aws/credentials

on linux and mac, and in this path for windows : %USERPROFILE%\.aws\credentials

the file will contain your AWS credentials : 

aws_access_key_id = DVRZNJSZLDEKQAZ
aws_secret_access_key = Y7vdvdYRYR9ckomzc8WHcndndcn6vfzpa

here we created a profile called pisquare, this profile can be used in terraform for configuring a resource provider :

provider "aws" {
profile = "pisquare

By providing the name of the AWS profile to be used, AWS will get the information required for the authentification. 

2 – Assuming roles and multi-environments : 

As described by AWS :

“An IAM role is an IAM identity that you can create in your account that has specific permissions. An IAM role is similar to an IAM user, in that it is an AWS identity with permission policies that determine what the identity can and cannot do in AWS.” 

So when we give a profile an assumed role, we give that profile the right to perform operations on specific components in an AWS account.

When creating AWS infrastructure on large projects, we often have separate environments (staging and production for example). 

In order to be able to perform operations on staging and production environments, you need to have a separate authentication process, for example in the production environment, you will need MFA, which is not mandatory for the staging environment. 

In order to make the authentication easier, less painful and more maintainable. We will create other profiles in our credential file. 

These new profiles will have different roles in different AWS accounts. 

aws_access_key_id = DVRZNJSZLDEKQAZ
aws_secret_access_key = Y7vdvdYRYR9ckomzc8WHcndndcn6vfzpa

source_profile = pisquare
role_arn = arn:aws:iam::2233554466:role/my-role

source_profile = pisquare
role_arn = arn:aws:iam::1122334455:role/my-role

in the new profiles : [pisquare_staging] and [pisquare_production] we specify the source_profile which allows us to authenticate, then we specify the role_arn, which basically gives us certain permissions and allows us to operate on specific resources in a specific account. 

The [pisquare_staging] will have a role in AWS account id 2233554466. 

The [pisquare_production] will have a role in AWS account id 1122334455. 

This has created several profiles with several purposes and roles, that we can easily use anywhere in order to easily change whenever I need access and perform tasks to a specific environment. 

I can use these profiles in bash script : 

export AWS_PROFILE=pisquare_staging

or in Terraform :

provider "aws" {
      profile = "pisquare_production"

3 – Profiles and MFA 

When dealing with production environments, we usually have MFA setted up. 

This can be a bit painful to use especially when our infrastructure is automated with terraform. 

When MFA is required, we must add the MFA serial and seed in our pisquare profile :

aws_access_key_id = DVRZNJSZLDEKQAZ
aws_secret_access_key = Y7vdvdYRYR9ckomzc8WHcndndcn6vfzpa
mfa_serial = arn:aws:iam::1213141516:mfa/user-test

than we add our MFA profile, that will contain information required for the authentification : 

aws_access_key_id = DZDKLQKDKQDKQ
aws_secret_access_key = DDJEJDAECNDNCND
aws_session_token = a/very/long/token/string

N.B : in order to fill the pisquare MFA profile, either you will create a script that will compute, get the credentials from AWS and then fill the required fields. 

Or you will manually execute the get token command using the pisquare profile, get the id and access_key and manually fill the information.   

In order to use the mfa profile by the production profile, you use the assume role property : 

source_profile = pisquare_mfa
role_arn = arn:aws:iam::1122334455:role/my-role

These patterns helps to have a maintainable IaC code and a productive Cloud Engineering teams.

Do you have a cloud project?