다양한 구성으로 여러 보안 그룹을 테라포밍하는 방법

4663 단어 terraformsecurityaws
최근에 일부 서버의 보안 구성을 표준화하는 작업을 해야 했습니다. 이들은 관련된 모든 보안 그룹과 마찬가지로 수동으로 생성되었습니다.

우리는 어떤 서버에 어떤 포트가 열려 있는지 정확히 알고 싶었고, 이전 보안 그룹을 제거하고 Terraform 변경 사항을 적용하여 새 보안 그룹을 만들기 위해 보안 그룹의 구성을 Terraform으로 포팅했습니다.

이 블로그 게시물에서는 다양한 구성으로 여러 보안 그룹을 생성하는 방법을 설명합니다.

먼저 모든 구성을 variables.tf 파일에 넣습니다.

variable "config" {
   default = {
    "server1" = {
       ports  = [
        {
          from = 3000
          to = 3000
          destination ="0.0.0.0/0"
        },
        {
          from = 3000
          to = 3000
          destination ="::/0"
        },
         {
          from = 25
          to = 25
          destination ="0.0.0.0/0"
        },
        {
          from = 587
          to = 587
          destination ="0.0.0.0/0"
        },
        {
          from = 1433
          to = 1433
          destination ="sg-1234"
        },
        {       
          from = 0
          to = 65535
          destination = "1.2.3.4/32"
        }
      ]
    },
     "server2" = {
      ports = [       
         {
          from = 2001
          to = 2001
          destination ="0.0.0.0/0"
        },
        {
          from = 2001
          to = 2001
          destination ="::/0"
        },
         {
          from = 24001
          to = 24001
          destination ="0.0.0.0/0"
        },
        {
          from = 24001
          to = 24001
          destination ="::/0"
        },
        {
          from = 1433
          to = 1433
          destination ="sg-1234"
        }
      ]
    }
     "server3" = {
        ports = null
    }, 
     "server4" = {
        ports = {
          from = 1433
          to = 1433
          destination ="sg-1234"
        },
     },
     "server5" = {
      ports = null
     }
   } 
 }


이 변수에는 일부 인스턴스에서만 열려 있는 포트/범위가 포함됩니다.
포트 1433의 대상에는 이미 존재하는 보안 그룹의 ID가 포함됩니다.

처음에는 맵에 두 가지 유형의 요소를 만들려고 했습니다. 하나는 포트용이고 다른 하나는 포트 범위용이지만 한 가지 유형의 요소에 모든 것을 넣는 것이 더 쉽다는 것을 깨달았습니다.

기본적으로 각 서버에는 모든 트래픽에 대해 열려 있는 포트 80 및 443과 특정 IP에서 열려 있는 포트 3389(원격 데스크톱)가 있습니다.

각 서버에 대한 구성으로 변수를 생성한 후 Terraformfor_each meta argument을 사용하여 각 서버에 대한 보안 그룹을 정의했습니다. 이러한 방식으로 생성된 각 보안 그룹의 이름과 태그에는 쉽게 식별할 수 있도록 서버 이름이 포함됩니다.

resource "aws_security_group" "server_access_sg" {
  for_each = var.config
  name = "${each.key}-sg"
  description = "The security group for ${each.key}"
  vpc_id = data.aws_vpc.default.id

  tags = {
    "Server" = "${each.key}"
    "Provider" = "Terraform"
  }


또한 각 보안 그룹 내에서 인라인 수신 블록을 사용하여 보안 그룹 규칙을 생성했습니다.

ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "http"
    cidr_blocks = ["0.0.0.0/0", "::/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "https"
    cidr_blocks = ["0.0.0.0/0", "::/0"]
  }


다음으로 각 포트에 대해 기본적으로 for_each 루프의 단순화된 버전인 splat expression을 사용하여 동적 수신 블록을 생성했습니다.

dynamic "ingress" {
  for_each = each.value.ports[*]
  content {
    from_port   =  ingress.value.from
    to_port     =  ingress.value.to
    protocol    = "tcp"
    cidr_blocks = ingress.value.from != 1433 ? [ ingress.value.destination  ] : null 
    security_groups =   ingress.value.from != 1433 ? [ ingress.value.destination ] : null 
  }
}


이것은 중첩된 루프이며 첫 번째 루프의 each.value 요소에 대해 반복됩니다. 예를 들어, server1의 구불구불한 괄호 안의 모든 구성이 값입니다.

"server1" = {
      ports = [...]
}


중첩 루프이고 "각"은 상위 루프의 요소를 참조하는 데 사용되기 때문에 값을 채우기 위해 "ingress"를 사용합니다.

지적할 가치가 있는 또 다른 사항은 cidr_blocks/security_groups 속성의 조건부 생성입니다. 이 경우 security_groups 인수는 포트 1433에 대한 규칙이 정의될 때만 생성되어야 합니다. 따라서 인수 중 하나가 필요하지 않은 경우 속성을 null로 설정했습니다.

마지막으로 각 보안 그룹에 대한 모든 발신 트래픽을 허용하는 송신 규칙을 생성했습니다.

egress {
    from_port   = 0
    to_port     = 0
    protocol    = -1
    cidr_blocks = ["0.0.0.0/0", "::/0"]
  } 


즐거운 학습이 되셨고 위의 코드를 개선하기 위한 제안이 있으시면 언제든지 의견을 남겨주세요 :)

좋은 웹페이지 즐겨찾기