Defining IAM Policies with Terraform safely

Defining IAM Policies with Terraform

Are you still defining IAM policies using heredoc syntax (<<EOF ... EOF) or jsonencode()? You can do better! As a result, terraform validate can tell you about typos before you apply them, and you get better auto-complete support from your IDE. Read on to learn how to define IAM policies in Terraform safely.

[wpcc-element _tag=”source” type=”image/webp” srcset=”/images/2021/03/productivity@730w.webp 730w, /images/2021/03/productivity@730w2x.webp 1460w, /images/2021/03/productivity@610w.webp 610w, /images/2021/03/productivity@610w2x.webp 1220w, /images/2021/03/productivity@450w.webp 450w, /images/2021/03/productivity@450w2x.webp 900w, /images/2021/03/productivity@330w.webp 330w, /images/2021/03/productivity@330w2x.webp 660w, /images/2021/03/productivity@545w.webp 545w, /images/2021/03/productivity@545w2x.webp 1090w” sizes=”(min-width: 1200px) 730px, (min-width: 992px) 610px, (min-width: 768px) 450px, (min-width: 576px) 330px, 545px” _close=”0″]

When looking at Terraform code I still see the following two ways to define IAM policies:

resource "aws_iam_policy" "inline" {
name = "tf-inline"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "${aws_s3_bucket.example.arn}/*"
}
]
}
EOF
}

The second approach looks like this:

resource "aws_iam_policy" "jsonencode" {
name = "tf-jsonencode"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject"
]
Resource = [
"${aws_s3_bucket.example.arn}/*"
]
}
]
})
}

The problem with both approaches: If your policy is malformed, you have to terraform apply before you realize the mistake. Besides that, your IDE’s auto-complete can not help you much when using those approaches.

How can we do better? The following video demonstrates using the data source aws_iam_policy_document. This way, Terraform can validate your IAM policy (at least from a structural perspective), and your IDE can do a much better job of increasing your productivity.

[wpcc-iframe class=”embed-responsive-item lozad” data-src=”https://www.youtube-nocookie.com/embed/cI9yoJ0qV8Q” allow=”accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture” allowfullscreen=””]
resource "aws_iam_policy" "policydocument" {
name = "tf-policydocument"
policy = data.aws_iam_policy_document.example.json
}

data "aws_iam_policy_document" "example" {
statement {
effect = "Allow"
actions = [
"s3:ListBucket"
]
resources = [
aws_s3_bucket.example.arn
]
}
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:PutObject"
]
resources = [
"${aws_s3_bucket.example.arn}/*"
]
}
}