Terraform для цикла для создания правил группы безопасности

#amazon-web-services #terraform

Вопрос:

Я пытаюсь создать правила группы безопасности в Terraform для передачи в aws_security_group в качестве входного блока. Я не использую aws_security_group_rule, потому что я хочу, чтобы модуль был гибким, если у него есть собственный источник и т. Д.

Пример извлечения cidr_блока частной подсети и описание правила в качестве зоны доступности.

упрощенный пример: я на самом деле выхожу из состояния терраформирования и т. Д.

Окружающая среда

Терраформа v1.0.8

Источник

список карт

 locals {
  subnets = [
    {
      availability_zone = "us-east-1a"
      cidr_block = "10.0.0.0/23"
    },
    {
      availability_zone = "us-east-1b"
      cidr_block = "10.0.2.0/23"
    },
    {
      availability_zone = "us-east-1c"
      cidr_block = "10.0.4.0/23"
    }
  ]
}
 

Ожидаемые Результаты

список карт

 [
    {
      description               = "us-east-1a"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.0.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    },
    {
      description               = "us-east-1b"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.2.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    },
    {
      description               = "us-east-1c"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.4.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
]
 

Нет рабочего проекта (Нужна помощь здесь)

 ingress_rules = flatten([
    for subnets, values in local.subnets : [
      for key in values: {
        description               = key.availability_zone
        type                      = "ingress"
        from_port                 = "0"
        to_port                   = "0"
        protocol                  = "-1"
        cidr_blocks               = [key.cidr_block]
        ipv6_cidr_blocks          = []
        prefix_list_ids           = []
        security_groups           = []
        self                      = false
      }
    ]
  ])
 

Ответ №1:

У тебя их for слишком много. Это должно быть:

   ingress_rules = [
    for subnets, values in local.subnets : {
        description               = values.availability_zone
        type                      = "ingress"
        from_port                 = "0"
        to_port                   = "0"
        protocol                  = "-1"
        cidr_blocks               = [values.cidr_block]
        ipv6_cidr_blocks          = []
        prefix_list_ids           = []
        security_groups           = []
        self                      = false
    }
  ] 
 

Комментарии:

1. Идеально, миллион раз спасибо!

2. @Levon Без проблем. Если бы ответ был полезным, мы были бы признательны за его принятие.

3. Ой, забыл. бум, готово! Вы меня разблокировали, а затем я использовал этот пример в нескольких разных шаблонах. Спасибо!

4. @Levon Без проблем. Рад, что смог помочь.

Ответ №2:

Примеры создания Правил Группы Безопасности AWS

Примеры для других, основанные на справке @Marcin

VPC и удаленный доступ по глобальной сети IP

списки доступа.tfvars

 access_lists = {
  office = {
    hq                    = "102.55.22.34/32"
  },
  remote = {
    first_last            = "12.32.211.243/32"
  }
}
 

local.tf

 locals {
  cidr_list_office              = var.access_lists.office
  cidr_list_remote              = var.access_lists.remote

  public_access_cidrs           = merge(
    local.cidr_list_office,
    local.cidr_list_remote
  )

  ingress_rule_vpc = [
    {
      description               = "vpc - Managed by Terraform"
      type                      = "ingress"
      from_port                 = 0
      to_port                   = 0
      protocol                  = "-1"
      cidr_blocks               = [data.terraform_remote_state.network.outputs.vpc.cidr_block]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  ingress_rules_public = [
    for desc, cidr in local.public_access_cidrs : {
      description               = "${desc} - Managed by Terraform"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = [cidr]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  ingress_rules                 = concat(local.ingress_rule_vpc, local.ingress_rules_public)
}
 

EFS (2 Варианта)

Вложенные вызовы for_each. Можно было бы добавить больше в tfvar, а затем настроить правила sg в локальном режиме, которые сопоставляются с express_rules.xyz/ingress_rules.xyz

efs.tfvars

 efs = {
  jenkins = {
    encrypted                 = "false"
    performance_mode          = "generalPurpose"
    throughput_mode           = "bursting"
    throughput_in_mibps       = "0"
  }
}
 

local.tf (Вариант 1 — Частные подсети)

 locals {
  # Allow all Private Subnets
  jenkins_ingress_rules = [
    for subnets, values in data.terraform_remote_state.network.outputs.subnets.private : {
      description               = values.availability_zone
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = [values.cidr_block]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  # VPC Private Subnets Only
  jenkins_egress_rules = [
    {
      description               = "Managed by Terraform"
      type                      = "egress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["0.0.0.0/0"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  egress_rules = {
    jenkins                     = local.jenkins_egress_rules
  }

  ingress_rules = {
    jenkins                     = local.jenkins_ingress_rules
  }
}
 

local.tf (Вариант 2 — Самостоятельный источник)

 locals {
  # Self sourced security group. Have to be in the SG for access.
  jenkins_ingress_rules = [
    {
      description               = "Managed by Terraform"
      from_port                 = 0
      to_port                   = 0
      protocol                  = "-1"
      self                      = true
      cidr_blocks               = []
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
    }
  ]

  # VPC Private Subnets Only
  jenkins_egress_rules = [
    {
      description               = "Managed by Terraform"
      type                      = "egress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["0.0.0.0/0"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  egress_rules = {
    jenkins                     = local.jenkins_egress_rules
  }

  ingress_rules = {
    jenkins                     = local.jenkins_ingress_rules
  }
}
 

main.tf

 module "security_groups" {
  for_each                      = var.efs
  base_aws_tags                 = module.aws_tags.aws_tags
  name_suffix                   = "efs-${each.key}"
  egress_rules                  = lookup(local.egress_rules, each.key)
  ingress_rules                 = lookup(local.ingress_rules, each.key)
  source                        = "../../../modules/security_group"
  vpc                           = data.terraform_remote_state.network.outputs.vpc
}
 

Надеюсь, это поможет некоторым другим!
-=Левон