/ DEVOPS, AWS, TERRAFORM

3-Tier VPC Architecture with Terraform

본 글은 Configure and Deploying VPCs with Multiple Subnets에서 다루는 Production-Ready: The 3-Tier VPC 강의를 바탕으로, 테라폼으로 구축하는 3계층 VPC 아키텍처에 대한 글입니다.


Multi-Tier VPC 란?


VPC를 구축할 때 단일 계층 VPC에 모든 자원을 넣는다면, 네트워크에 접근할 수 있는 잠재적 공격자에게 자원이 노출됩니다. 이를 보완하기 위해 서브넷으로 다중 계층 VPC 아키텍처를 만들어 방어 계층을 이룰 수 있습니다.

multiTier


디자인 패턴 : 3 Tier VPC Architecture

테라폼 코드는 모듈로 관리하는 것을 권장하지만, 이번 포스팅에서는 3-tier 아키텍처 중 네트워크와 관련된 부분만을 다뤄 하나의 파일에서 코드를 관리합니다.


Step 0 (테라폼을 활용하실 줄 안다면 넘어가세요)

Step 0

아키텍처를 구성할 폴더를 만들고 provider를 주입합니다.

mkdir architecture
cd architecture
terraform init
touch threeTierVPC.tf

threeTierVPC.tf에 벤더 정보를 작성합니다.

provider "aws" {
  region = "ap-northeast-2"
}

명령어terraform plan, terraform apply를 통해, 오류 없이 통과하는 화면을 확인하고 다음 단계로 🚀

terraform apply로 인프라를 반영 할때, -auto-approve옵션을 주면 yes입력 없이 진행 할 수 있습니다. 그러나 yes를 입력하기 전, 한번 더 검토할 수 있는 기회가 있으므로 권장하지 않습니다.


💡각 소제목 링크에 첨부된 코드를 활용해 Step 0 에서 만든 threeTierVPC.tf에 이어서 작성하거나, 따로 새로운 파일을 만들어 terraform plan, terraform apply 명령어를 차례로 작성하며 계층을 쌓아 올립니다.


Step 1

Layer 1️⃣ : Public subnet

하나의 VPC에 2개의 AZ를 만들고 각각의 Public 서브넷을 위치시킵니다.

step1

퍼블릭 서브넷은 프라이빗 서브넷 보다 적은 수의 IP 예약하는 것이 좋습니다.

Step 1 코드를 적용 후, 명령어로 인프라 상태를 점검해 아래와 같다면 다음 단계로 🚀

$ terraform state list
data.aws_availability_zones.available
aws_internet_gateway.igw
aws_subnet.pub_sub_1
aws_subnet.pub_sub_2
aws_vpc.main
생성한 인프라가 위와 같지 않을 경우

실수로 의도치 않은 인프라가 프로비저닝 되었다면 2가지 방법을 통해 원 상태로 복구 할 수 있습니다.

  1. terraform destroy 명령어로 특정 인프라만 되돌리거나 프로비저닝 하고싶은 경우, -target 옵션과 함께 resource 명으로 명령어를 작성합니다.
    예시) terraform destory -target aws_vpc.main
  2. 잘못 작성한 코드를 수정 후, terraform apply명령어를 적용하여 최신 상태의 인프라를 반영합니다.


Step 2

Layer 1️⃣ : Internet access resources

외부 인터넷과의 노출을 제한하고 나가는 트래픽을 위해 NAT Gateway를 활용합니다. 또한 들어오는 트래픽을 위해 ALB를 위치시켰습니다. 로드밸런서와 NAT Gateway는 가용성이 높은 관리형 서비스로 병목 현상에 대해 걱정할 필요가 없습니다.

💡Nat Gateway 알아보기


NAT(네트워크 주소 변환) 게이트웨이를 사용하면 프라이빗 서브넷의 인스턴스를 인터넷 또는 기타 AWS 서비스에 연결하는 한편, 인터넷에서 해당 인스턴스와의 연결을 시작하지 못하게 할 수 있습니다. NAT 게이트웨이를 만들려면 NAT 게이트웨이가 속할 퍼블릭 서브넷을 지정해야 하기 때문에 Step2에서 우선적으로 생성합니다.

도큐먼트로 더 알아보기

step2

그림에서는 보이지 않지만, VPC에는 암시적 라우터가 있으며 라우팅 테이블을 사용하여 네트워크 트래픽이 전달되는 위치를 제어합니다. VPC의 각 서브넷을 라우팅 테이블에 연결해야 합니다. 테이블에서는 서브넷에 대한 라우팅을 제어합니다.

Step 2 코드를 적용 후, 명령어로 인프라 상태를 점검해 아래와 같다면 다음 단계로 🚀

$ terraform state list
data.aws_availability_zones.available
aws_eip.nat_1
aws_eip.nat_2
aws_internet_gateway.igw
aws_nat_gateway.nat_gateway_1
aws_nat_gateway.nat_gateway_2
aws_route_table.route_table_pub
aws_route_table_association.route_table_association_1
aws_route_table_association.route_table_association_2
aws_subnet.pub_sub_1
aws_subnet.pub_sub_2
aws_vpc.main

이번 포스팅에서 ALB와 인스턴스는 다루지 않습니다. 추후, 모듈로 테라폼을 관리하는 방법에서 학습하겠습니다.

Step 3

Layer 2️⃣️ : Apps in a private subnet

2개의 프라이빗 서브넷에 각각의 인스턴스를 놓습니다. 이후, 두 퍼블릭 서브넷에 연결된 ALB는 프라이빗 서브넷 리소스 간의 트래픽을 분산시킵니다.

❗️예제 그림에서는 Private subnet의 cidr block을 10.0.2.0/22로 가이드 하지만, 이는 앞서 만든 서브넷과 범위가 겹치므로 10.0.4.0/22로 바꿔 진행합니다. CIDR 계산기 에서 정확하게 확인해 볼 수 있습니다.

step3

Step3에서도 Step2와 같이 그림에서는 보이지 않는 라우트 테이블을 만들고 NAT 게이트웨이와 프라이빗 서브넷을 연결해 줍니다. 프라이빗 서브넷의 요청이 외부로 나갈때는 NAT 게이트웨이의 고정 IP를 사용합니다. (프라이빗 서브넷의 라우트 테이블은 퍼블릭과 달리 2개를 만들어 각각 연결해 주었습니다.)

Step 3 코드를 적용 후, 명령어로 인프라 상태를 점검해 아래와 같다면 다음 단계로 🚀

$ terraform state list
data.aws_availability_zones.available
aws_eip.nat_1
aws_eip.nat_2
aws_internet_gateway.igw
aws_nat_gateway.nat_gateway_1
aws_nat_gateway.nat_gateway_2
aws_route.private_nat_1
aws_route.private_nat_2
aws_route_table.route_table_pri_1
aws_route_table.route_table_pri_2
aws_route_table.route_table_pub
aws_route_table_association.route_table_association_1
aws_route_table_association.route_table_association_2
aws_route_table_association.route_table_pri_association_1
aws_route_table_association.route_table_pri_association_2
aws_subnet.pri_sub_1
aws_subnet.pri_sub_2
aws_subnet.pub_sub_1
aws_subnet.pub_sub_2
aws_vpc.main

이번 포스팅에서 DB와 인스턴스 연결은 다루지 않습니다. 추후, 모듈로 테라폼을 관리하는 방법에서 학습하겠습니다.

Step 4

Layer 3️⃣ : Data in a second private subnet

첫 번째 프라이빗 서브넷 뒤에 두 번째 프라이빗 서브넷을 배치합니다. (코드 생략)
장애가 발생할 경우를 대비해 read-replica 혹은 standby 구성으로 배치합니다.

❗Step4의 서브넷 작성법은 Step3의 방법과 동일합니다. 아래 사진은 CIDR의 범위가 겹치므로, Private subnet의 cidr block을 10.0.8.0/2310.0.12.0/23로, 10.0.10.0/2310.0.14.0/23으로 바꿔 진행하세요.

step4

데이터 리소스(/23)보다를 앱 리소스(/22)를 확장할 가능성이 커, 더 큰 서브넷 마스크를 할당합니다.


Step 5

Leave extra IPs available

배포된 인프라가 확장되어 아키텍처가 변경될 때 사용할 수 있는 여유분의 IP를 예약을 할 수도 있습니다. (코드 생략)

step5


위와 같은 단계들을 통해 3 Tier VPC Architecture를 학습해보았습니다. Terraform으로 생성된 자원들은 terraform destory명령어를 통해 학습을 시작하기 전 상태로 되돌리세요. 다음 포스팅에서는 이번 포스팅에서 생략했던 인스턴스, DB, LB 등을 모듈로 관리하며 다뤄 보겠습니다.


Terraform Courses

-->