Terraform 다단계지도

Aug 27 2020

다단계지도 (3 개 이상의 수준)를 사용하려고 할 때 "테라 폼 계획"에서 오류가 발생하고 정확한 문제를 파악할 수없는 것 같습니다. 오류 : "주어진 값이 변수"secgroups "에 유효하지 않습니다."bastion "요소 :"direction "속성이 필요합니다." 내 variables.tf가 secgroups.auto.tf에 매핑 된대로 정확합니까? ports_min 및 ports_max는 보안 그룹 이름에 대해 열 포트의 포괄적 인 목록입니다.

버전 :

Terraform v0.13.0
+ provider registry.terraform.io/hashicorp/local v1.4.0
+ provider registry.terraform.io/hashicorp/null v2.1.2
+ provider registry.terraform.io/hashicorp/tls v2.2.0
+ provider registry.terraform.io/terraform-providers/openstack v1.26.0

variables.tf

variable "secgroups" {
  type = map(object({
  direction = (map(object({
    protocols = (map(object({
      name              = string
      description       = string
      ports_min         = list(number)
      ports_max         = list(number)
      remote_ip_prefix  = list(string)
      remote_group_id   = list(string)
      security_group_id = list(string)
    })))
  })))
 }))
}

secgroups.auto.tfvars (스 니펫)

  ssh_from_bastion = {
    ingress = {
      tcp = {
        ports_min         = [22]
        ports_max         = [22]
        remote_group_id   = ["openstack_networking_secgroup_v2.bastion.id"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      },
      udp = {
        ports_min         = [0]
        ports_max         = [0]
        remote_group_id   = ["openstack_networking_secgroup_v2.bastion.id"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      }
    },
    egress = {
      tcp = {
        ports_min         = [0]
        ports_max         = [0]
        remote_ip_prefix  = ["0.0.0.0/0"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      },
      udp = {
        ports_min         = [0]
        ports_max         = [0]
        remote_ip_prefix  = ["0.0.0.0/0"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      }
    }
  },

Main.tf

 locals {
   security_groups = flatten({
   for secgroup_name,direction in var.secgroups : {
     name        = each.secgroup_name
     description = "Security group for ${each.secgroup_name}"
       for protocol,config in each.direction : {
         direction = each.direction
         protocol  = each.protocol
           for config_value in config : {
             ports_min         = each.config_value.ports_min
             ports_max         = each.config_value.ports_max
             remote_ip_prefix  = each.config_value.remote_ip_prefix
             security_group_id = each.config_value.security_group_id
           }
         }
       }
   })
 } 

답변

Marcin Aug 27 2020 at 08:00

정의에 몇 가지 문제가 있습니다.

귀하의 전체 secgroups.auto.tfvars가 다음과 같다고 가정합니다 .

secgroups = {
 ssh_from_bastion = {
    ingress = {
      tcp = {
        ports_min         = [22]
        ports_max         = [22]
        remote_group_id   = ["openstack_networking_secgroup_v2.bastion.id"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      },
      udp = {
        ports_min         = [0]
        ports_max         = [0]
        remote_group_id   = ["openstack_networking_secgroup_v2.bastion.id"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      }
    },
    egress = {
      tcp = {
        ports_min         = [0]
        ports_max         = [0]
        remote_ip_prefix  = ["0.0.0.0/0"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      },
      udp = {
        ports_min         = [0]
        ports_max         = [0]
        remote_ip_prefix  = ["0.0.0.0/0"]
        security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
      }
    }
  }
}

해당 정의는 다음과 같아야합니다.

variable "secgroups" {
  type = map(map(map(object({
        ports_min         = list(number)
        ports_max         = list(number)
        security_group_id = list(string)
      }))))
}

그러나 위의 내부 개체는 remote_ip_prefix개체가 일치하지 않기 때문에 모든 추가 속성을 삭제합니다 . 그러나 이후 ingress, egress, tcpudp일치하는 것, 당신은 아마 다음을 사용할 수 있습니다 :

variable "secgroups" {
  type = map(object({
            ingress = object({tcp = map(any), udp = map(any)})
            egress =  object({tcp = map(any), udp = map(any)})
        }))
}

마지막 리소스로 일관성이없는 경우 다음을 사용할 수 있습니다.

variable "secgroups" {
  type = map(map(map(map(any))))
}

업데이트 : 테스트 출력

output "test" {
  value = var.secgroups.ssh_from_bastion.ingress.tcp.ports_min
}