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:
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.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:::role/
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:::mfa/
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-mfa
Enter 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 =
aws_secret_access_key =
aws_session_token =
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.
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.