Read our newest book, Fundamentals of DevOps and Software Delivery, for free!

Authenticating to AWS with the Credentials File

Headshot of Yevgeniy Brikman

Yevgeniy Brikman

AUG 6, 2018 | 12 min read
Featured Image of Authenticating to AWS with the Credentials File
This is Part 1 of the Comprehensive Guide to Authenticating to AWS on the Command Line. In the intro to the series, we went over the basics of AWS Authentication, including IAM Users, IAM Roles, and Access Keys. In this post, we’re going to present the first option for authenticating to AWS on the Command Line: the Credentials File.

You can store your AWS Access Keys in a Credentials File which lives in ~/.aws/credentials (or %UserProfile%\.aws\credentials on Windows). Normally, the way you create this file is by installing the AWS CLI and running the aws configure command:
$ aws configure AWS Access Key ID: AKIAIOSFODNN7EXAMPLE AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY Default region name [None]: us-west-2 Default output format [None]: json
AWS prompts you to enter your Access Key ID and Secret Access Key and stores them in ~/.aws/credentials:
[default] aws_access_key_id=AKIAIOSFODNN7EXAMPLE aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
It also stores the other settings you entered in ~/.aws/config:
[default] region=us-west-2 output=json
Once these files exist, you can run any CLI or SDK tool that talks to AWS, and it will automatically find and use this credentials file and settings.

If you have multiple sets of Access Keys (e.g., for multiple IAM Users in different AWS accounts), you can create a separate Named Profile for each one in your Credentials File in ~/.aws/credentials:
[default] aws_access_key_id=AKIAIOSFODNN7EXAMPLE aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY[user2] aws_access_key_id=AKIAI44QH8DHBEXAMPLE aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
And similarly, you can have multiple Named Profiles in your Config File in ~/.aws/config:
[default] region=us-west-2 output=json[profile user2] region=us-east-1 output=text
Note that the Named Profile called default is used, as you might guess, by default. To tell your CLI tools to use something other than the default profile, you have to do one of the following:
  • 1.Set the AWS_PROFILE environment variable. For example, in Linux, you’d run export AWS_PROFILE=user2. After that, you can run any AWS CLI tool (e.g., terraform apply), and it should use your Named Profile.
  • 2.Some tools let you specify the profile as a command-line parameter or an argument in code. For example, the aws CLI lets you specify --profile: aws ec2 describe-instances --profile user2. In Terraform, you can set the profile parameter in a provider block:
provider "aws" { profile = "user2" }

If you want to assume IAM Roles — for example, you have an IAM User in the security account and want to assume an IAM Role in your dev account—you have two options. The first option depends on the CLI tool you’re using. Some CLI tools allow you to specify the IAM Role to assume via a command-line argument or in the code. For example, with Terraform, you can specify the assume_role setting in your provider configuration:
provider "aws" { assume_role { role_arn = "arn:aws:iam::123456789012:role/dev-full-access" } }
The second option is to specify the role_arn parameter in your Config File in ~/.aws/config:
[profile dev-full-access] role_arn = arn:aws:iam::123456789012:role/dev-full-access
With either option, the value you specify for role_arn is the Amazon Resource Name (ARN) of the IAM Role in the dev account, which will have the format:
arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>
Next time you run any CLI command that uses the dev-full-access Named Profile, the AWS SDK will automatically assume the IAM Role specified in role_arn.

If you’re using the aws CLI, using MFA with a Credentials Profile is fairly straight forward. You just need to add the mfa_serial to your Config File in ~/.aws/config:
[profile with-mfa] mfa_serial = arn:aws:iam::123456789012:mfa/jon-doe
The mfa_serial parameter should be set to the ARN of your MFA device, which you can get from the IAM User page of the AWS Web Console. It should be of the format:
arn:aws:iam::<ACCOUNT_ID>:mfa/<USERNAME>
Once you’ve added the mfa_serial parameter, the next time you run the aws CLI with that Named Profile, it will prompt you for an MFA token:
$ aws s3 ls --profile with-mfaEnter MFA code:
But what if you’re running something that isn’t aws, such as terraform or packer? In that case, things get a bit hairy, as most other tools will not automatically prompt you for an MFA token. Instead, you have to do the MFA authentication process outside of that tool, which is a bit of a tedious process.First, you configure your Credentials File with your normal (permanent) AWS Access Keys (e.g. by running aws configure). Next, you run the aws sts get-session-token command, passing it the ARN of your MFA device and an MFA token from the Google Authenticator App or your key fob:
aws sts get-session-token \ --serial-number arn:aws:iam::123456789012:mfa/jon-doe \ --token-code 123456 \ --duration-seconds 43200
This will return a blob of JSON that contains Temporary Access Keys (note the --duration-seconds argument in the earlier command, which specifies when these Temporary Access Keys will expire):
{ "Credentials": { "SecretAccessKey": "secret-access-key", "SessionToken": "temporary-session-token", "Expiration": "expiration-date-time", "AccessKeyId": "access-key-id" } }
You will need to take these Temporary Access Keys and copy them into a Named Profile in your Credentials File in ~/.aws/credentials:
[with-mfa] aws_access_key_id = <Access-key-as-in-returned-output> aws_secret_access_key = <Secret-access-key-as-in-returned-output> aws_session_token = <Session-Token-as-in-returned-output>
Note that with Temporary Access Keys, you set not only aws_access_key_id and aws_secret_access_key in your Credentials File, but also aws_session_token.Now you can run those other CLI tools with this Named Profile:
export AWS_PROFILE=with-mfa terraform apply
Note that the Temporary Access Keys expire after a certain period of time (typically 12 hours), so you’ll have to do this over and over again. Not fun.

  • Basic authentication is easy.
  • Using IAM Roles is easy.
  • Named Profiles make it easy to manage multiple sets of credentials and settings.

  • Your Access Keys are stored in plaintext on disk. This is NOT secure.
  • You’re always using permanent Access Keys for auth rather than Temporary Access Keys that are rotated.
  • Using MFA is complicated and error prone.
  • Your credentials sit around on disk forever and the default Named Profile gets used for all commands if you forget to specify a different one, which is error prone.
  • It’s tempting to specify Named Profiles in your code (e.g., in your Terraform code) to ensure the proper credentials are used, but that requires all of your team members to use the same names for your Named Profiles, which can be hard to enforce.

Although many AWS tutorials use the Credentials File, we usually recommend against it, as storing your permanent AWS credentials on disk, in plaintext, is not safe. To make matters worse, MFA usage is so complicated with the Credentials File, that most users don’t bother with it.To see a better alternative, head on to the next part of the series, Authenticating to AWS with Environment Variables.Get your DevOps superpowers at Gruntwork.io.
Share
Grunty
Resources

Explore our latest blog

Get the most up-to-date information and trends from our DevOps community.
TerraformResouces Image

Promotion Workflows with Terraform

How to configure GitOps-driven, immutable infrastructure workflows for Terraform using Gruntwork Patcher.
avatar

Jason Griffin

October 3, 2023 7 min read
TerraformResouces Image

The Impact of the HashiCorp License Change on Gruntwork Customers

How to configure GitOps-driven, immutable infrastructure workflows for Terraform using Gruntwork Patcher.
avatar

Josh Padnick

October 3, 2023 7 min read