본문 바로가기

개발하자

Terraform CIDR 블록 변수 유효성 검사

반응형

Terraform CIDR 블록 변수 유효성 검사

CIDR에 대한 테라폼 변수 검증, 정규 모델에 대한 대안 모색

아래는 테라폼 버전 13.0에서 테스트된 코드로 regex를 사용하지 않는 것과 동일한 것을 달성할 수 있는 대안이 있습니까?

cidr 블록 - 172.28.0.0.0/16 시작

    variable "vpc_cidr" {
      description = "Kubernetes cluster CIDR notation for vpc."
      validation {
        condition     = can(regex("^([0-9]{1,3}\\.){3}[0-9]{1,3}($|/(16))$", var.pod_cidr))
        error_message = "Vpc_cidr value must be greater than 172.0.0.0/16."
      }
    }

cidrsubnet 기능으로 CIDR 블록 172.28.x.x/16을 검증하는 방법은 무엇인가?

유효성 검사 조건 - IP 범위가 172.28.x.x/16을 벗어나는 경우 유효성 검사에 실패합니다




여러 개가 있고 172.0.0.0/16보다 커야 합니다. 예를 들어 다음과 같습니다:

172.1.0.0/16

없음:

172.0.0.0.0/16



오늘날의 Terraform의 기능으로 원하는 것을 직접적으로 달성할 수 있는 방법은 생각할 수 없지만, 이 점검을 두 가지 조건으로 나누어 동일한 효과를 도출할 수 있다고 생각합니다:

  1. 서브넷의 0번째 주소는 다음과 같아야 합니다.
  2. 범위의 넷마스크는 다음과 같아야 한다.

다음 두 가지 식을 사용하여 이 두 가지 규칙을 테스트할 수 있습니다:

  1. cidrhost(var.vpc_cidr, 0) == "172.28.0.0"
  2. cidrnetmask(var.vpc_cidr) == "255.255.0.0"

이 두 함수 모두 유효하지 않은 CIDR 블록 구문이 주어지면 실패할 수 있으며 IPv6 주소가 주어지면 추가적으로 실패하므로 두 함수 모두에 가드를 추가하여 오류를 예상대로 잘못된 결과로 바꿀 수 있습니다:

  1. try(cidrhost(var.vpc_cidr, 0), null) == "172.28.0.0"
  2. try(cidrnetmask(var.vpc_cidr), null) == "255.255.0.0"

함수는 동적 오류를 생성하지 않는 첫 번째 식의 결과를 반환하므로 위의 예제에서 또는 함수에 대한 잘못된 입력은 와 같은 식을 야기할 것이며, 이는 항상 거짓이므로 조건은 여전히 충족되지 않을 것이다.

마지막으로 연산자를 사용하여 이들을 결합하여 완전한 표현을 얻을 수 있습니다:

  condition = (
    try(cidrhost(var.vpc_cidr, 0), null) == "172.28.0.0" &&
    try(cidrnetmask(var.vpc_cidr), null) == "255.255.0.0"
  )



약간의 해킹이 있긴 하지만, 그래도:

variable "vpc_cidr" {
  validation {
    condition = cidrsubnet("${var.pod_cidr}/16", 0, 0) == "172.28.0.0/16"
  }
}



나는 그 해결책을 선호한다

variable "string_like_valid_ipv4_cidr" {
  type    = string
  default = "10.0.0.0/16"

  validation {
    condition     = can(cidrhost(var.string_like_valid_ipv4_cidr, 32))
    error_message = "Must be valid IPv4 CIDR."
  }
}

또한 여기에 언급된 것처럼 /32 주소에 대해 작동하려면 조건을 수정해야 합니다.




이 코드를 많이 기반으로 하면 CIDR이 정확한 형식의 값일 뿐만 아니라, 접두사가 크기에 대해 유효하다는 것을 확인할 수 있습니다. 즉, 범위의 첫 번째 IP가 잘못된 것이며, 이는 접두사 자체 이전의 것입니다.

variable "demoIpv4Cidr" {
  type    = string
  default = "10.0.0.1/16" # try "10.0.0.0/16" for a valid value 
                          # or "10.0.0.x/16" for an invalidly formatted cidr

  validation {
    condition     = (
      can(cidrhost(var.demoIpv4Cidr, 0)) &&
      try(cidrhost(var.demoIpv4Cidr, 0), null) == split("/", var.demoIpv4Cidr)[0]
    )
    # the above could be simplified to:
    # condition = cidrhost(var.demoIpv4Cidr, 0) == split("/", var.demoIpv4Cidr)[0]
    # ...though that would throw "Error in function call" instead of "Invalid 
    # value for variable" were an invalid cidr (10.0.0.x/16) were used.
  
    error_message = "InvalidCIDRNotation: The CIDR is not correctly formatted, or the address prefix is invalid for the CIDR's size"
    # InvalidCIDRNotation is an existing error code; so may be helpful if anyone googles it.
  }
}

반응형