How to Create an IAM Role with Terraform
To create an IAM role in Terraform, use the
aws_iam_role resource with a name and an assume_role_policy JSON policy that defines who can assume the role. This lets you manage permissions securely and automatically with Terraform.Syntax
The aws_iam_role resource defines an IAM role. You must provide a name for the role and an assume_role_policy which is a JSON string that specifies who can use this role.
- name: The unique name of the IAM role.
- assume_role_policy: JSON policy that allows trusted entities (like EC2 or Lambda) to assume the role.
terraform
resource "aws_iam_role" "example" { name = "example-role" assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Principal = { Service = "ec2.amazonaws.com" }, Action = "sts:AssumeRole" } ] }) }
Example
This example creates an IAM role named example-role that EC2 instances can assume. The assume_role_policy allows EC2 service to use this role.
terraform
provider "aws" { region = "us-east-1" } resource "aws_iam_role" "example" { name = "example-role" assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Principal = { Service = "ec2.amazonaws.com" }, Action = "sts:AssumeRole" } ] }) }
Output
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Common Pitfalls
Common mistakes when creating IAM roles in Terraform include:
- Not providing a valid
assume_role_policyJSON, which causes errors or prevents the role from being assumed. - Using incorrect
Principalvalues, so the wrong services or users can assume the role. - Forgetting to attach policies to the role to grant permissions after creation.
Always validate your JSON policy and check AWS documentation for correct Principal values.
terraform
resource "aws_iam_role" "wrong" { name = "wrong-role" assume_role_policy = "invalid-json" } # Correct way: resource "aws_iam_role" "correct" { name = "correct-role" assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Principal = { Service = "lambda.amazonaws.com" }, Action = "sts:AssumeRole" } ] }) }
Quick Reference
| Field | Description |
|---|---|
| name | Unique name for the IAM role |
| assume_role_policy | JSON policy defining who can assume the role |
| jsonencode() | Terraform function to convert HCL map to JSON string |
| Principal | Entity allowed to assume the role (e.g., EC2, Lambda) |
| Action | Always sts:AssumeRole for IAM roles |
Key Takeaways
Use the aws_iam_role resource with a valid assume_role_policy JSON to create IAM roles.
The assume_role_policy defines which AWS services or users can assume the role.
Always use jsonencode() to convert your policy map to a JSON string in Terraform.
Check your Principal field carefully to avoid permission issues.
Attach policies separately to grant permissions after creating the role.