Learn the subtle differences between Terraform's assume_role_policy and standard IAM policies, ensuring your infrastructure deployments are secure and efficient.
When defining IAM Assume Role Policies in Terraform, it's crucial to understand that they differ from regular IAM policies. Instead of using the aws_iam_policy
resource, you define Assume Role Policies directly within the aws_iam_role
resource using the assume_role_policy
argument. This argument requires a JSON string representing the policy, which you can either write directly in your Terraform code or load from a separate file using the file()
function. The JSON structure for an Assume Role Policy must include a "Statement" array, with each statement specifying the "Principal" allowed to assume the role and the conditions under which they can do so. For instance, to allow an EC2 instance to assume the role, you would specify "ec2.amazonaws.com" as the "Service" within the "Principal". Remember to keep your assume_role_policy
idempotent to prevent unintended updates. When granting cross-account access, include the external account ID in the "Principal" section. After implementing any changes, always test thoroughly to ensure the intended entities can successfully assume the role.
Understand the Difference: An IAM Assume Role Policy is not the same as a regular IAM policy. While they look similar, you cannot use the aws_iam_policy
resource for Assume Role Policies in Terraform.
Use the Right Resource: In Terraform, define Assume Role Policies directly within the aws_iam_role
resource using the assume_role_policy
argument.
JSON Format: The assume_role_policy
argument expects a JSON string. You can either write the JSON directly within your Terraform code or store it in a separate file and load it using the file()
function.
Structure: The JSON structure for an Assume Role Policy is specific. It should contain a "Statement" array, where each statement defines who (the "Principal") can assume this role and under what conditions.
Example: Here's a basic example of an assume_role_policy
allowing an EC2 instance to assume the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
trust-policy.json
) and load it in your Terraform code:resource "aws_iam_role" "example" {
name = "example-role"
assume_role_policy = file("trust-policy.json")
# ... other role configurations
}
Idempotency: Ensure your assume_role_policy
is idempotent. Avoid using placeholders or dynamically generated values that might change on each Terraform run, leading to unintended updates.
Cross-Account Access: To allow an IAM entity from a different AWS account to assume the role, specify the account ID within the "Principal" section of your Assume Role Policy.
Testing: After creating or modifying an IAM role and its Assume Role Policy, thoroughly test that the intended entities can successfully assume the role.
This code defines an AWS IAM role using Terraform. It sets up an Assume Role Policy that allows the root user of a specific AWS account (123456789012) to assume the role. The policy includes a condition requiring an external ID match for security. The Terraform code defines the role, loads the policy from a JSON file, and applies the configuration to create the IAM role in AWS.
This example demonstrates how to create an IAM role with an Assume Role Policy that allows EC2 instances in a specific account to assume the role.
1. Create trust-policy.json
:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "987654321012"
}
}
}
]
}
Explanation:
123456789012
.2. Create main.tf
:
resource "aws_iam_role" "example_role" {
name = "example-role"
assume_role_policy = file("trust-policy.json")
# ... other role configurations like inline policies or managed policy attachments
}
Explanation:
trust-policy.json
file using the file()
function.3. Apply the Terraform code:
terraform init
terraform apply
This will create the IAM role with the specified Assume Role Policy, allowing only the specified principal to assume the role under the defined conditions.
Important Considerations:
Principal
and Condition
sections to control access to your role.Policy Syntax and Validation:
assume_role_policy
requires strict JSON. Ensure proper quoting, commas, and data types within the JSON string. Online JSON validators can be helpful.Version
, Statement
, Effect
, Principal
, Action
, Resource
, and Condition
.Best Practices and Security:
*
) whenever possible.Troubleshooting:
assume_role_policy
. They often provide clues about syntax issues or incorrect key usage.Additional Resources:
aws_iam_role
resource for detailed explanations of all arguments and examples: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role
This table summarizes key points about managing IAM Assume Role Policies in Terraform:
Feature | Description |
---|---|
Resource Type | Use the assume_role_policy argument within the aws_iam_role resource. Do not use the aws_iam_policy resource. |
Format | The assume_role_policy argument requires a JSON string. |
JSON Structure | Must contain a "Statement" array. Each statement defines a "Principal" (who can assume the role) and the allowed "Action" (sts:AssumeRole ). |
Example | json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } |
External Files | Store the JSON in a separate file for better organization and load it using the file() function. |
Idempotency | Ensure the assume_role_policy remains the same across Terraform runs to avoid unintended updates. |
Cross-Account Access | Specify the external account ID within the "Principal" section to grant access from another AWS account. |
Testing | Always test that intended entities can successfully assume the role after any changes. |
By adhering to these principles and utilizing the provided examples, you can effectively manage IAM Assume Role Policies in Terraform, ensuring secure and controlled access to your AWS resources. Remember that proper IAM configuration is paramount for maintaining a secure and well-architected AWS environment.