【问题标题】:Terraform resources created with `for_each` - use in other Terraform scripts使用 `for_each` 创建的 Terraform 资源 - 在其他 Terraform 脚本中使用
【发布时间】:2020-12-08 06:59:59
【问题描述】:

我有创建 N 个安全组的 terraform 脚本:

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"]
    }
}

..我还有另一个创建 IAM 策略的 Terraform 脚本,

这个必须引用资源部分中第一个脚本创建的 N 个安全组:

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
}

是否可行?

【问题讨论】:

    标签: amazon-web-services terraform


    【解决方案1】:

    您可以将jsonencodevaluesspat 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
    }
    

    【讨论】:

      【解决方案2】:

      与使用字符串模板生成 JSON 相比,使用 the jsonencode function 生成整个值更加健壮,因为 Terraform 可以将参数作为普通表达式进行评估,并确保生成结果的有效 JSON 表示:

      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",
              ]
            },
          ]
        })
      }
      

      除了保证结果始终是有效的 JSON 语法外,使用 Terraform 的表达式语言来构建您的策略值还意味着您可以使用所有 Terraform's expression operators,包括 for expressions 来读取每个 arn 属性您的安全组:

      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
              ],
            },
          ]
        })
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-09
        • 1970-01-01
        • 2021-04-15
        • 2019-12-16
        • 2020-12-17
        • 2021-10-06
        • 2020-12-23
        • 2021-01-21
        相关资源
        最近更新 更多