I faced 2 scenarios where terraform did not point out an error during the execution of terraform plan and I am wondering if is this a bug or if this is how bucket/iam policies work ( i.e determined at the time of terraform apply )
scenario 1 : when there was an error in condition for s3 bucket policy Bool
was written as bool
data "aws_iam_policy_document" "alb_log" {
statement {
effect = "Allow"
actions = ["s3:PutObject"]
resources = ["${aws_s3_bucket.alb_log.arn}/*"]
principals {
type = "AWS"
identifiers = [data.aws_elb_service_account.main.arn]
}
}
statement {
sid = "AllowSSLRequestsOnly"
effect = "Deny"
actions = ["s3:*"]
resources = [
aws_s3_bucket.alb_log.arn,
"${aws_s3_bucket.alb_log.arn}/*"
]
condition {
test = "bool"
values = [
"false"
]
variable = "aws:SecureTransport"
}
principals {
type = "*"
identifiers = ["*"]
}
}
}
resource "aws_s3_bucket_policy" "alb_log" {
bucket = aws_s3_bucket.alb_log.id
policy = data.aws_iam_policy_document.alb_log.json
}
scenario 2 : I added principals to iam policy, terraform plan should point this but the fact principals cannot be added in iam policy is told during terraform apply
data "aws_iam_policy_document" "artifact2" {
statement {
sid = "AllowSSLRequestsOnly"
effect = "Deny"
actions = ["s3:*"]
resources = [
"arn:aws:s3:::${aws_s3_bucket.artifact2.id}",
"arn:aws:s3:::${aws_s3_bucket.artifact2.id}/*"
]
condition {
test = "Bool"
values = [
"false"
]
variable = "aws:SecureTransport"
}
principals {
type = "*"
identifiers = ["*"]
}
}
}
resource "aws_iam_policy" "firehose" {
policy = data.aws_iam_policy_document.artifact2.json
}
2
Answers
Based on the comments.
Terraform does not check much apart from its syntax and basic argument formats. Many errors can be only detected after actually trying to deploy them to AWS. Its the same with CloudFormation or boto3.
You could report this as an issue for terraform aws provider here. Maybe developers of the provider will be able to shed more light on that.
You might want to try out building your own test environment to test your own terraform code. Often people will create a small self contained examples folder to dry run a terraform module to make sure its all valid on the AWS side.
This might be the only real way to ensure your terraform code won’t fail on an apply. Like others have already pointed out, terraform only checks the terraform syntax and restraints, it would be a lot for terraform to maintain all the restraints on the AWS side.
It might be overkill, but you can also check out Terratest: https://terratest.gruntwork.io/docs/getting-started/introduction/
It lets you test your terraform code by spinning it up and destroying it. But its a complicated tool and its written in Go