Terraform

How to Create AWS IAM Role with Terraform [Step-by-Step]

Create IAM Role Using Terraform

In this article, we will look at what an IAM (Identity and Access Management) role in AWS (Amazon Web Services) is, and show a step-by-step example of how to create one using Terraform. Buckle up!

We will cover:

  1. What is an IAM Role?
  2. Prerequisites
  3. Steps to Create IAM Role in AWS using Terraform

What is an IAM Role?

An IAM role is an IAM identity that you can create in your account that has specific permissions. This security principal enables you to delegate permissions to AWS resources to entities within your AWS account. It is a way to manage access to AWS services and resources without the need to share long-term credentials, such as access keys or passwords.

IAM roles are typically used to grant permissions to AWS services, applications, or other AWS accounts. By assuming an IAM role, an entity can temporarily acquire the permissions associated with that role.

For example, IAM roles are commonly used in scenarios like EC2 instances accessing other AWS services, allowing AWS Lambda functions to access specific resources, or granting cross-account access.

When creating an IAM role, you can define the set of permissions and policies that specify what actions are allowed or denied. These policies can be based on AWS-managed policies, customer-managed policies, or inline policies. IAM roles can be assigned to entities such as IAM users, AWS services, or even external identities federated through identity providers like Active Directory or SAML. Note that when you first create your AWS account, no roles are created by default.

Check out our detailed guide to AWS IAM Roles and AWS IAM best practices.

Prerequisites

Let’s see what we need before we start:

  • An Amazon Web Service (AWS) account. You can get a free-tier account if you don’t have one. The free tier includes 750 hours of Linux and Windows t2.micro instances (t3.micro for the regions in which t2.micro is unavailable) each month for one year. To stay within the Free Tier, use only EC2 Micro instances. The example in the article uses t2.micro.
  • Terraform — the step-by-step guide below will use the latest Terraform version available, (v1.52 at the time of writing).
  • A code editor such as VSCode.

Steps to Create IAM Role in AWS using Terraform

In this example, we will use the Amazon Web Services (AWS) Terraform provider to interact with the many resources supported by AWS. We will create an IAM role and assign it to a newly created EC2 instance that will allow it read-only access to a newly created S3 storage bucket.

Step 1: Configure the AWS provider

You must configure the provider with the proper credentials before you can use it. To authenticate with AWS, you can use one of several methods.

  1. Credentials can be provided by adding an access_key, secret_key, and optionally token, to the AWS provider block. Hard-coded credentials are not recommended in any Terraform configuration and risk secret leakage should this file ever be committed to a public version control system.
provider "aws" {
  region     = "us-east-1"
  access_key = "my-access-key"
  secret_key = "my-secret-key"
}
  1. Arguably a better way to authenticate when testing locally is to use environment variables.
$ export AWS_ACCESS_KEY_ID="my-access-key"
$ export AWS_SECRET_ACCESS_KEY="my-secret-key"
$ export AWS_REGION="us-east-1"
  1. If you have the AWS Command Line Interface (CLI) installed, you can run aws configure and enter the access key ID, secret access key, and default region. Terraform will automatically use these credentials. I will use this method in my example.

Step 2: Obtain your Access key ID and secret access key for your AWS user

Next, obtain your Access key ID and secret access key for your AWS user.

If you don’t have one, follow the steps below to retrieve one:

  1. Sign in to the AWS Management Console using your AWS account credentials.
  2. Open the IAM (Identity and Access Management) service from the console.
  3. In the IAM dashboard, navigate to “Users” in the left-hand navigation pane.
  4. Select the IAM user for which you want to generate or retrieve the Access Key ID and Secret Access Key.
  5. Under the “Security credentials” tab for the selected user, you will find a section labeled “Access keys.”
  6. If the user doesn’t have any access keys, you can click on the “Create access key” button to generate a new pair of access keys.
  7. After creating or selecting an existing access key, you will be able to view the Access Key ID. To view the Secret Access Key, click on the “Show” button in the “Secret access key” column.

Make sure to record the Secret Access Key immediately, as AWS will only show it once. If you lose the Secret Access Key, you will need to generate a new one.

Note: Your user will need permission to put the S3 access policy on the bucket — to check those in place, check the link here.

Step 3: Run aws configure

Run aws configure in the console to authenticate. Enter your AWS Access key ID and secret access key when prompted.

Step 4: Create a new main.tf file

Open your code editor and create a new file called main.tf.

Step 5: Set the IAM role

Copy and paste the following code into the file and save it.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_iam_role" "example_role" {
  name = "examplerole"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "example_attachment" {
  role       = aws_iam_role.example_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}

resource "aws_iam_instance_profile" "example_profile" {
  name = "example_profile"
  role = aws_iam_role.example_role.name
}

resource "aws_instance" "example_instance" {
  ami           = "ami-06ca3ca175f37dd66"
  instance_type = "t2.micro"
  
  iam_instance_profile = aws_iam_instance_profile.example_profile.name

  tags = {
    Name = "exampleinstance"
  }
}

resource "aws_s3_bucket_policy" "example_bucket_policy" {
  bucket = "example-bucket"

  policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${aws_iam_role.example_role.name}"
        },
        "Action": [
          "s3:GetObject",
          "s3:ListBucket"
        ],
        "Resource": [
          "arn:aws:s3:::example-bucket",
          "arn:aws:s3:::example-bucket/*"
        ]
      }
    ]
  })
}

data "aws_caller_identity" "current" {}

What this will do:

  1. Add the provider block to declare we will use the AWS provider and set the region (us-east-1 in the example is North Virginia).
  2. Create an IAM role named “example-role” using the aws_iam_role resource. The assume_role_policy attribute specifies the trust policy, allowing EC2 instances to assume this role.
  3. Attach an AWS-managed policy, “AmazonS3ReadOnlyAccess,” to the role using the aws_iam_role_policy_attachment resource.
  4. Create the EC2 instance using the aws_instance resource. The ami attribute is set to the desired Amazon Machine Image (AMI) ID. The AMI used in the example is an Amazon Linux 2023 AMI eligible for the free tier at the time of writing.To check available AMIs, log into the console at https://console.aws.amazon.com/ec2/ and click on ‘AMI Catlog’ under the Instances section.
iam role terraform example
  1. To associate the IAM role with the EC2 instance, we use the iam_instance_profile attribute and provide the name of the IAM role created earlier, aws_iam_role.example_role.name.

Step 6: Run terraform init

With the configuration files created, open a console and type terraform init to initialize the Terraform code.

terraform iam role policy attachment

Step 7: Run terraform validate

Run terraform validate to check the syntax of your configuration is valid.

terraform import iam role

Step 8: Run terraform plan

In the console type terraform plan to generate the plan. Review it and check you are happy the plan matches what you expect to happen.

aws terraform iam role

Step 9: Run terraform apply

Run terraform apply to apply the configuration to AWS.

apply aws iam role terraform

Step 10: See the new resources in AWS

Check the AWS for the newly created resources. You should see the IAM role, S3 bucket, and EC2 instance.

aws iam role terraform
terraform iam example

Under the EC2 instance security tab, you can see the role has been assigned.

terraform iam role security

Step 11: Clean up

To clean up, run terraform destroy to remove all the resources in your Terraform configuration.

Check out also how to create AWS IAM policy using Terraform.

Key points

An IAM role is a secure way to manage and delegate permissions in AWS, allowing you to control access to resources without sharing long-term credentials and providing a mechanism for temporary permissions for trusted entities.

IAM roles can be created using Terraform and assigned to resources as shown in the step-by-step tutorial.

We encourage you also to explore how Spacelift makes it easy to work with Terraform. If you need any help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine, Spacelift is a fantastic tool for this. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box.

Note: New versions of Terraform will be placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that will expand on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6. OpenTofu retained all the features and functionalities that had made Terraform popular among developers while also introducing improvements and enhancements. OpenTofu is not going to have its own providers and modules, but it is going to use its own registry for them.

Manage Terraform Better with Spacelift

Build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization and many more.

Start free trial