Reputation: 8107
I have terraform script that creates N security groups:
variable "security_groups" {
default = {
"sg1" = "Security group 1"
"sg2" = "Security group 2"
}
}
resource "aws_security_group" "example" {
for_each = var.security_groups
name = each.key
description = each.value
vpc_id = aws_vpc.example.id
revoke_rules_on_delete = false
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
..and I have another Terraform script that creates IAM policy,
this one has to reference N Security groups created by first script in Resource section:
resource "aws_iam_policy" "operator_policy" {
name = "${var.iam_prefix}-operator"
path = "/"
description = "Policy for operator"
policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress"
],
"Effect": "Allow",
"Resource": [
"sg1 ARN",
"sgN ARN"
]
}
]
}
EOF
}
Is it feasible somehow?
Upvotes: 0
Views: 136
Reputation: 74064
Rather than using string templates to generate JSON, it's more robust to generate the entire value using the jsonencode
function, because then Terraform can evaluate the argument as a normal expression and be sure to generate a valid JSON representation of the result:
resource "aws_iam_policy" "operator_policy" {
name = "${var.iam_prefix}-operator"
path = "/"
description = "Policy for operator"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
]
Effect = "Allow"
Resource = [
"sg1 ARN",
"sgN ARN",
]
},
]
})
}
As well as guaranteeing that the result will always be valid JSON syntax, using Terraform's expression language to build your policy value also means you can use all of Terraform's expression operators, including for
expressions to read the arn
attribute from each of your security groups:
resource "aws_iam_policy" "operator_policy" {
name = "${var.iam_prefix}-operator"
path = "/"
description = "Policy for operator"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
]
Effect = "Allow"
Resource = [
for sg in aws_security_group.example : sg.arn
],
},
]
})
}
Upvotes: 1
Reputation: 238081
You can use a combo of jsonencode with values and spat expression:
resource "aws_iam_policy" "operator_policy" {
name = "${var.iam_prefix}-operator"
path = "/"
description = "Policy for operator"
policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress"
],
"Effect": "Allow",
"Resource": ${jsonencode(values(aws_security_group.example)[*].arn)}
}
]
}
EOF
}
Upvotes: 1