Terraform Advanced — Least Privilege IAM

1 minute read

Give Terraform only the permissions it needs — nothing more.


The Anti-Pattern

# ❌ Anti-pattern: admin access for Terraform
resource "aws_iam_role_policy_attachment" "terraform" {
  role       = aws_iam_role.terraform.name
  policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}

Scoped Permissions

# ✅ Best practice: scoped to what Terraform actually manages
resource "aws_iam_policy" "terraform" {
  name = "terraform-deploy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "ManageVPC"
        Effect = "Allow"
        Action = [
          "ec2:CreateVpc", "ec2:DeleteVpc", "ec2:DescribeVpcs",
          "ec2:CreateSubnet", "ec2:DeleteSubnet", "ec2:DescribeSubnets",
          "ec2:CreateSecurityGroup", "ec2:DeleteSecurityGroup",
        ]
        Resource = "*"
        Condition = {
          StringEquals = {
            "aws:RequestedRegion" = ["us-east-1", "us-west-2"]
          }
        }
      },
      {
        Sid    = "ManageState"
        Effect = "Allow"
        Action = [
          "s3:GetObject", "s3:PutObject", "s3:ListBucket",
          "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:DeleteItem",
        ]
        Resource = [
          "arn:aws:s3:::my-tf-state/*",
          "arn:aws:dynamodb:us-east-1:*:table/tf-locks",
        ]
      }
    ]
  })
}

Separate Roles Per Environment

terraform-dev    → only manage resources in dev account
terraform-staging → only manage resources in staging account
terraform-prod   → only manage resources in prod account

Use iamlive to Discover Permissions

# Record actual API calls during terraform apply
iamlive --mode proxy --output-file policy.json

# Use as HTTP proxy
HTTPS_PROXY=http://127.0.0.1:10080 terraform apply

# iamlive generates the minimal IAM policy

💡 Production Tip: Run iamlive during a full apply cycle in dev, then use the generated policy as your baseline for production.


What’s Next?

Practice security patterns.

← OPA & Conftest Practice Exercises →

Updated: