(Optional) VPC Peering

VPC 간 통신을 위한 peering 작업

VPC Peering

VPC 간 통신

  • VPC 간 내부 통신을 위해서는 Peering을 맺어야 합니다.

  • 단, 주의해야할 점은 peering하는 두 VPC의 CIDR가 겹치지 않아야 합니다.

  • 최근에는 Transit Gateway도 유용하게 쓰이지만, 본 실습에서는 종단 간 VPC Peering을 맺도록 하겠습니다.

  • VPC Peering을 맺기 위해서는 Requester는 Peering 요청을 하고, Acceptor는 요청을 승인해야 합니다. 이후에는 해당 peering ID를 destination IP range와 Route 테이블에 저장합니다.

    • Requester : artp VPC

    • Acceptor : artd VPC

Requester는 Peering을 가장 많이 맺는 VPC로 정하시면 편리합니다.

Requester 생성

먼저 peering.tf 파일을 생성(수정)해서 peering request 코드를 작성합니다. Peering request는 어느 계정에서 해도 상관 없지만, 관리의 편의성을 위해서 peering connection이 많은 VPC를 기준으로 설계하면 좋습니다.

이번에는 devartd VPC에서 devartp VPC로 요청을 보내는 시나리오로 구성해보겠습니다.

peering.tf
resource "aws_vpc_peering_connection" "peering_connection" {
  for_each      = { for entry in var.vpc_peering_list : entry.peer_vpc_name => entry }
  peer_vpc_id   = each.value.peer_vpc_id
  peer_owner_id = each.value.peer_owner_id
  peer_region   = each.value.peer_region
  vpc_id        = aws_vpc.default.id

  tags = {
    Name          = "${var.shard_id}-with-${each.value.peer_vpc_name}"
    peer_vpc_name = each.value.peer_vpc_name
    Side          = "Requester"
  }
}

위 코드에 들어가는 변수를 variables.tf 에 추가합니다.

variables.tf
variable "vpc_peering_list" {
  type = list(object({
    peer_vpc_id   = string
    peer_vpc_name = string
    peer_region   = string
    vpc_cidrs     = list(string)
    peer_owner_id = string
  }))
  description = "A list of maps containing key/value pairs that define vpc peering."
}

변수가 들어갈 값을 terraform.tfvars에 추가합니다.

terraform.tfvars
# (...생략...)

# Peering List
vpc_peering_list = [
  {
    peer_vpc_id   = "vpc-0acb7d87bcbd212f0"
    peer_owner_id = "816736805842"
    peer_region   = "ap-northeast-2"
    peer_vpc_name = "devartp_apnortheast2"
    vpc_cidrs     = [ "10.11.0.0/16" ]
  }
]

그 다음, 해당 Peering을 사용하기 위한 라우팅 설정을 추가합니다.

peering_routes.tf
locals {
  private_peering_route_list = flatten([
    for pair in setproduct(var.vpc_peering_list, aws_route_table.private.*.id) : [
      for cidr in pair[0].vpc_cidrs : {
        peer_vpc_name  = pair[0].peer_vpc_name
        vpc_cidr       = cidr
        route_table_id = pair[1]
      }
    ]
  ])
}

resource "aws_route" "private_peering_with_request" {
  for_each                  = { for entry in local.private_peering_route_list : "${entry.peer_vpc_name}_${entry.vpc_cidr}_${entry.route_table_id}" => entry }
  route_table_id            = each.value.route_table_id
  destination_cidr_block    = each.value.vpc_cidr
  vpc_peering_connection_id = aws_vpc_peering_connection.peering_connection[each.value.peer_vpc_name].id
}

이제 terraform plan, apply를 통해서 request 요청을 보냅니다.

$ terraform plan -parallelism=30

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_route.private_peering_with_request["devartp_apnortheast2_10.11.0.0/16_rtb-0a1f84db0139d73f6"] will be created
  + resource "aws_route" "private_peering_with_request" {
      + destination_cidr_block    = "10.11.0.0/16"
      + id                        = (known after apply)
      + instance_id               = (known after apply)
      + instance_owner_id         = (known after apply)
      + network_interface_id      = (known after apply)
      + origin                    = (known after apply)
      + route_table_id            = "rtb-0a1f84db0139d73f6"
      + state                     = (known after apply)
      + vpc_peering_connection_id = "pcx-025501a85c5371c20"
    }

  # aws_route.private_peering_with_request["devartp_apnortheast2_10.11.0.0/16_rtb-0d76e08459db46366"] will be created
  + resource "aws_route" "private_peering_with_request" {
      + destination_cidr_block    = "10.11.0.0/16"
      + id                        = (known after apply)
      + instance_id               = (known after apply)
      + instance_owner_id         = (known after apply)
      + network_interface_id      = (known after apply)
      + origin                    = (known after apply)
      + route_table_id            = "rtb-0d76e08459db46366"
      + state                     = (known after apply)
      + vpc_peering_connection_id = "pcx-025501a85c5371c20"
    }

  # aws_vpc_peering_connection.peering_connection["devpartp_apnortheast2"] will be created
  + resource "aws_vpc_peering_connection" "peering_connection" {
      + accept_status = (known after apply)
      + id            = (known after apply)
      + peer_owner_id = "816736805842"
      + peer_region   = "ap-northeast-2"
      + peer_vpc_id   = "vpc-0acb7d87bcbd212f0"
      + tags          = {
          + "Name"          = "devartdapne2-with-devartp_apnortheast2"
          + "Side"          = "Requester"
          + "peer_vpc_name" = "devartp_apnortheast2"
        }
      + tags_all      = {
          + "Name"          = "devartdapne2-with-devartp_apnortheast2"
          + "Side"          = "Requester"
          + "peer_vpc_name" = "devartp_apnortheast2"
        }
      + vpc_id        = "vpc-0f1c1a1cfad0ac154"
    }

Plan: 3 to add, 0 to change, 0 to destroy.
$ terraform apply -parallelism=30
...

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

콘솔에서 확인해보시면 Request가 생성된 것을 확인하실 수 있습니다.

Accepter 생성

이제 devartp VPC 에서 Accepter를 생성하도록 하겠습니다.

peering.tf
resource "aws_vpc_peering_connection_accepter" "peering_accepter" {
  for_each                  = { for entry in var.peering_requests : entry.id => entry }
  vpc_peering_connection_id = each.value.id
  auto_accept               = true
  tags = {
    Name = "vpc-peering-${var.shard_id}-with-${each.value.vpc_name}"
  }

  lifecycle {
    ignore_changes = [tags]
  }
}

추가한 변수를 variables.tf에 추가합니다.

variables.tf
variable "peering_requests" {
  type = list(object({
    id         = string
    vpc_name   = string
    cidr_block = string
  }))
  description = "peering connection id for accepting the peering connection "
}

변수에 대한 값을 terraform.tfvars에 추가합니다. 이때 Peering ID에는 이전 단계에서 생성한 request에서 peering connection ID(pcx-xxx)를 넣어주시면 됩니다.

terraform.tfvars
peering_requests = [
  {
    "id"         = "pcx-025501a85c5371c20"
    "vpc_name"   = "devartd_apnortheast2"
    "cidr_block" = "10.10.0.0/16"
  },
]

추가로, Peering을 사용할 Subnet에 라우팅을 연결합니다.

peering_routes.tf
locals {
  private_subnet_peerings = flatten([
    for pair in setproduct(aws_route_table.private.*.id, var.peering_requests) : {
      route_table_id = pair[0]
      cidr_block     = pair[1].cidr_block
      vpc_name       = pair[1].vpc_name
      peering_id     = pair[1].id
    }
  ])
}

resource "aws_route" "private_peering" {
  for_each                  = { for entry in local.private_subnet_peerings : "${entry.vpc_name}_${entry.route_table_id}" => entry }
  route_table_id            = each.value.route_table_id
  destination_cidr_block    = each.value.cidr_block
  vpc_peering_connection_id = each.value.peering_id
}

이제 terraform plan, apply를 통해서 accept를 적용합니다.

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_route.private_peering["devartd_apnortheast2_rtb-0061eee04f6d3089d"] will be created
  + resource "aws_route" "private_peering" {
      + destination_cidr_block    = "10.10.0.0/16"
      + id                        = (known after apply)
      + instance_id               = (known after apply)
      + instance_owner_id         = (known after apply)
      + network_interface_id      = (known after apply)
      + origin                    = (known after apply)
      + route_table_id            = "rtb-0061eee04f6d3089d"
      + state                     = (known after apply)
      + vpc_peering_connection_id = "pcx-025501a85c5371c20"
    }

  # aws_route.private_peering["devartd_apnortheast2_rtb-0232754f8aeab7d2d"] will be created
  + resource "aws_route" "private_peering" {
      + destination_cidr_block    = "10.10.0.0/16"
      + id                        = (known after apply)
      + instance_id               = (known after apply)
      + instance_owner_id         = (known after apply)
      + network_interface_id      = (known after apply)
      + origin                    = (known after apply)
      + route_table_id            = "rtb-0232754f8aeab7d2d"
      + state                     = (known after apply)
      + vpc_peering_connection_id = "pcx-025501a85c5371c20"
    }

  # aws_vpc_peering_connection_accepter.peering_accepter["pcx-025501a85c5371c20"] will be created
  + resource "aws_vpc_peering_connection_accepter" "peering_accepter" {
      + accept_status             = (known after apply)
      + auto_accept               = true
      + id                        = (known after apply)
      + peer_owner_id             = (known after apply)
      + peer_region               = (known after apply)
      + peer_vpc_id               = (known after apply)
      + tags                      = {
          + "Name" = "vpc-peering-devartpapne2-with-devartd_apnortheast2"
        }
      + tags_all                  = {
          + "Name" = "vpc-peering-devartpapne2-with-devartd_apnortheast2"
        }
      + vpc_id                    = (known after apply)
      + vpc_peering_connection_id = "pcx-025501a85c5371c20"
    }

Plan: 3 to add, 0 to change, 0 to destroy.

콘솔에서 확인해보시면 해당 connection이 Active로 변경된 것을 확인하실 수 있습니다.

Last updated