Introduction
When deploying resources with Terraform or OpenTofu, you commonly need to provide a significant amount of privilege to your AWS accounts in order to deploy resources. The most secure way to do this is through automation and the use of roles and an AWS service, such as CodeDeploy. Unfortunately, this isn't always practical, especially when developing your IaC for the first time. In this tutorial, you’ll learn how to authenticate Terraform with the AWS Security Token Service (STS) using a role-based access approach. We'll set up IAM roles and policies using a CloudFormation template from the provided gist and then deploy an S3 bucket using Terraform. This method enhances security by using temporary credentials provided by STS instead of static keys.
Why AWS STS is Important
AWS Security Token Service (STS) is critical for ensuring secure access to AWS resources. It allows for the issuance of temporary, dynamically managed limited-privilege credentials. Here’s why STS is invaluable:
Minimized Credential Exposure: If stored improperly, static IAM credentials can be leaked or misused. STS eliminates this risk by using temporary credentials that expire automatically.
Improved Security Posture: STS allows you to enforce the principle of least privilege dynamically, granting roles tailored to specific tasks.
Flexibility Across Workloads: Temporary credentials allow for secure interactions across automated workflows, multi-account setups, and CI/CD pipelines.
Ease of Rotation: Since STS credentials are temporary, they don’t require manual rotation like static keys.
This tutorial will demonstrate how to implement STS for Terraform, ensuring a secure and scalable configuration process.
Step 1: Configure the AWS CLI
Install the AWS CLI
If you haven’t already installed the AWS CLI, follow the installation guide for your operating system.
Use Temporary or Existing IAM Credentials
If you do not have CLI credentials configured, you will need to use an existing IAM user with sufficient permissions (e.g., AdministratorAccess) to create the required resources. Configure the CLI with these credentials:
aws configure
Provide the following details:
AWS Access Key ID: Use the access key for the initial user.
AWS Secret Access Key: Use the corresponding secret key.
Default region name: Specify the region (e.g., us-west-2).
Default output format: Choose JSON or leave it blank.
Verify Configuration
Run the following command to confirm the configuration:
aws sts get-caller-identity
This will display the account and user information for the configured credentials. .
Step 2: Deploy the CloudFormation Stack
Prepare the Template
Use the CloudFormation template from the repository: Repository. Download and save it locally as role.yaml.
Carefully read the template and modify the username as you see fit. It is currently "SuperUser".
Deploy the Stack
Use the AWS CLI to deploy the stack. the CAPABILITY_NAMED_IAM capability indicates that you are allowing CloudFormation to create IAM resources on your behalf:
aws cloudformation create-stack \ --stack-name TerraformAuthStack \ --template-body file://role.yaml \ --capabilities CAPABILITY_NAMED_IAM
Create Access Keys for the New User
After the stack is created, generate access keys for the SuperUser created in the stack:
aws iam create-access-key --user-name SuperUser
The command will return an AccessKeyId and SecretAccessKey. Securely store these credentials as they will be used to configure the CLI. Honestly, you don't even need to store them. Keep them in the window and perform the next step to get them set. You can also set them as environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, respectively. Remember, this is in your bash history, so if you're on a shared terminal, it's a good idea to clear that.
Configure CLI for the New User
Update the AWS CLI to use the newly created access keys:
aws configure
Provide the AccessKeyId and SecretAccessKey from the previous step.
Verify the New Configuration
Run:
aws sts get-caller-identity
Ensure that the user returned is the SuperUser. If the correct user is not returned, you may need to unset your previous credential environment variables using the unset command.
Step 3: Configure Terraform for STS
Set Up Provider Configuration
Create a provider.tf file:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~>4.0"
}
}
}
provider "aws"{
region = "us-west-2"
assume_role {
role_arn = "arn:aws:iam::ACCOUNT_ID:role/AssumingRole" # ReplacewithARN
session_name = "terraform-session" # any session name will do
}
}
Step 4: Deploy an S3 Bucket Using Terraform
Create the Terraform Configuration
Create a main.tf file:
resource "aws_s3_bucket" "example_bucket" {
bucket = "example-bucket-${random_id.s3_id.dec}"
tags = {
Environment = "dev"
Project = "TerraformSTS"
}
}
resource "random_id" "s3_id" {
byte_length = 2
}
Initialize and Deploy
Run the following commands to deploy the bucket:
terraform init
terraform apply -auto-approve
Verify the Deployment
Check the AWS Console or run: aws s3 ls to confirm that the S3 bucket has been created.
Step 5: Cleanup Resources
Destroy Terraform Resources
Run:
terraform destroy -auto-approve
Delete the CloudFormation Stack
aws cloudformation delete-stack --stack-name TerraformAuthStack
Conclusion
Following this tutorial, you've set up a secure and efficient way to authenticate Terraform with AWS STS using IAM roles and deployed an S3 bucket. Leveraging STS ensures that your AWS environment adheres to modern security best practices by utilizing temporary credentials, reducing risks, and increasing flexibility. This approach is ideal for scalable, secure infrastructure management.