Terraform Challenges: Use Nested Loops to Secure and Scale IAM Role Assignments
As cloud infrastructure grows in complexity, managing IAM (Identity and Access Management) roles effectively becomes a critical concern. One powerful but underutilized feature in Terraform is nested for loops, especially when applied to IAM role assignments at scale. This guide walks you through practical use cases, implementation strategies, and optimization tips for using nested loops to efficiently secure and scale your IAM role provisioning.
Why Use Nested Loops in Terraform?
Nested loops in Terraform (for expressions within another for) provide a clean, scalable way to iterate over combinations of entities—such as roles and policies, users and roles, or roles and resources.
Key Benefits:
Scalability: Easily scale across multiple teams, environments, or AWS accounts.
Modularity: Pair nested loops with modules for reusable and maintainable code.
Security: Reduce human error by programmatically assigning permissions.
Typical Use Case: Assigning Policies to IAM Roles Across Environments
Let’s say you have:
Multiple environments: dev, staging, prod
Multiple IAM roles: admin, developer, viewer
A set of managed policies for each role
You can represent these as nested maps in Terraform and loop through them to assign policies dynamically.
Step-by-Step Implementation
1. Define the Role-to-Policy Mapping
variable "iam_roles" {
default = {
dev = {
admin = ["arn:aws:iam::aws:policy/AdministratorAccess"]
developer = ["arn:aws:iam::aws:policy/PowerUserAccess"]
},
prod = {
admin = ["arn:aws:iam::aws:policy/AdministratorAccess"]
viewer = ["arn:aws:iam::aws:policy/ReadOnlyAccess"]
}
}
}
2. Use Nested Loops to Create IAM Roles and Attach Policies
resource "aws_iam_role" "roles" {
for_each = {
for env, roles in var.iam_roles :
for role_name, _ in roles :
"${env}-${role_name}" => {
env = env
role_name = role_name
}
}
name = each.key
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
3. Attach Policies Using Nested Loops
resource "aws_iam_role_policy_attachment" "attachments" {
for_each = {
for env, roles in var.iam_roles :
for role_name, policies in roles :
for policy in policies :
"${env}-${role_name}-${replace(policy, "/", "-")}" => {
role = "${env}-${role_name}"
policy = policy
}
}
role = aws_iam_role.roles[each.value.role].name
policy_arn = each.value.policy
}
Security Best Practices
Use terraform validate and terraform plan to review changes before applying.
Pair loops with conditionals (if statements) for role-specific logic.
Store IAM policy ARNs in a centralized variable file to reduce duplication.
Always apply the least privilege principle when assigning policies.
Scaling Tips
Externalize role definitions into YAML or JSON and use yamldecode() or jsondecode() in Terraform.
Use workspaces for environment-specific configurations.
Combine with Terragrunt for multi-environment orchestration.

Comments
Post a Comment