devops

Terraform으로 AWS VPC, Private Subnet, NAT Gateway 구성 본문

DevOps/Terraform

Terraform으로 AWS VPC, Private Subnet, NAT Gateway 구성

vata500 2022. 6. 28. 22:13
반응형

간단한 기본 개념 복습

EC2, RDS, ALB, Auto Scaling Group 제외하고 구성

  • VPC : 사용자의 AWS 계정 전용의 가상 네트워크
  • 서브넷(Subnet) : VPC의 IP 주소 범위
  • 라우팅 테이블(Route Table) : 네트워크 트래픽을 전달할 위치 결정
  • 인터넷 게이트웨이(Internet Gateway) : VPC의 리소스와 인터넷의 통신을 위해 사용되므로 VPC에 연결

Internet Gateway vs Nat Gateway

  • IGW : VPC와 인터넷간의 통신을 활성화
  • NAT : 프라이빗 서브넷의 인스턴스가 인터넷에 연결할 수 있도록 해줌, 인터넷에서 원치않는 인바운드 연결 수신 차단

NAT는 위치가 Public Subnet에 있어야하며, 연결을 Private Subnet과 한다. EIP 생성이 필요하며 생성 및 삭제에 시간이 소요되는 편이다.

*서브넷은 IGW, NAT 중 어느 것이 설정되었느냐에 따라 퍼블릭과 프라이빗이 결정된다.

VPC / Subnet 생성

서브넷은 특정 Availability zone에 속한 네트워크 그룹으로, VPC에서도 나눠진 독립적인 네트워크 구역이다.

subnet 생성에는 aws_subnet 리소스를 사용하고 필요한 설정은 연결한 VPC와 해당 서브넷의 cidr block이다. 서브넷의 cidr block은 반드시 VPC의 cidr block안에 속해 있어야 한다.

resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "test_sprint-vpc"
  }
}

resource "aws_subnet" "publicSubnet1" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = "10.0.0.0/24"
  availability_zone = "ap-northeast-2a"
  tags = {
    "Name" = "test-public-subnet-01"
  }
}

resource "aws_subnet" "publicSubnet2" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-2c"
  tags = {
    "Name" = "test-public-subnet-02"
  }
}

resource "aws_subnet" "privateSubnet1" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = "10.0.4.0/24"
  availability_zone = "ap-northeast-2a"
  tags = {
    "Name" = "test-private-subnet-01"
  }
}

resource "aws_subnet" "privateSubnet2" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = "10.0.5.0/24"
  availability_zone = "ap-northeast-2c"
  tags = {
    "Name" = "test-private-subnet-02"
  }
}
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "test_sprint-vpc"
  }
}

인터넷 게이트웨이 생성

VPC 내부와 외부 인터넷이 통신하기 위해 사용되는 게이트웨이다. 인터넷 게이트웨이가 연결된 서브넷은 public 서브넷으로 분류한다.

resource "aws_internet_gateway" "testIGW" {
  vpc_id = aws_vpc.vpc.id
  tags = {
    "Name" = "testIGW"
  }
}

라우팅 테이블 생성

라우팅 테이블은 트래픽을 규칙에 맞게 전달해주기 위한 일종의 테이블이다. 여러 서브넷에서 동시에 사용할 수 있으며 이 연결 작업을 Assocation이라고 한다. (VPC와 Subnet)

테이블은 aws_route_table을 사용하고, 서브넷과 연결 시 에는 aws_route_table_assocation을 사용한다. 

  • 퍼블릭 서브넷 : vpc ㅡ route_table(public) ㅡ Internet_gateway
                                        route_table(public) ㅡ  route-table_assocation ㅡ subnet(public)
  • 프라이빗 서브넷 : vpc ㅡ route_table(private) ㅡ Nat_gateway
                                            route_table(private) ㅡ route-table_assocation ㅡ subnet(private)
resource "aws_route_table" "testPublicRTb" {
  vpc_id = aws_vpc.vpc.id


  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.testIGW.id
  }

  tags = {
    "Name" = "test-public-rtb"
  }
}

resource "aws_route_table" "testPrivateRTb" {
  vpc_id = aws_vpc.vpc.id
  
    route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.nat_gateway.id
  }
  
  tags = {
    "Name" = "test-private-rtb"
  }
}

EIP 생성

resource "aws_eip" "eip_nat" {
  vpc = true

  lifecycle {
    create_before_destroy = true
  }
}

NAT 게이트웨이 생성

Nat Gateway는 Private 서브넷에서 외부와 통신하기 위해 사용하는 게이트웨이다. Private 서브넷에 있는 서버는 외부와 통신해야하는 경우가 발생한다. (필요 패키지 다운 및 써드파티 API 사용)

이때 Nat gateway가 외부와 연결시켜주는 역할을 하며, 고정 IP를 가지고 있어야하기 때문에 EIP를 통해서 발급받는다. 모든 요청이 외부로 나갈 때는 고정 IP로 사용된다.

resource "aws_nat_gateway" "nat_gateway" {
  allocation_id = aws_eip.eip_nat.id // EIP 설정
  subnet_id     = aws_subnet.publicSubnet1.id // 퍼블릭서브넷 입력

  tags = {
    Name = "gw NAT"
  }
}

Nat gateway의 배치는 public subnet에 하고, 연결은 route_table_association으로 private subnet과 연결한다. 이유는 Nat gateway 자체는 인터넷과 통신해야하기 때문이다.

라우팅 테이블 연결

resource "aws_route_table_association" "publicRTbAssociation01" {
  subnet_id      = aws_subnet.publicSubnet1.id
  route_table_id = aws_route_table.testPublicRTb.id
}

resource "aws_route_table_association" "publicRTbAssociation02" {
  subnet_id      = aws_subnet.publicSubnet2.id
  route_table_id = aws_route_table.testPublicRTb.id
}

resource "aws_route_table_association" "privateRTbAssociation01" {
  subnet_id      = aws_subnet.privateSubnet1.id
  route_table_id = aws_route_table.testPrivateRTb.id
}

resource "aws_route_table_association" "privateRTbAssociation02" {
  subnet_id      = aws_subnet.privateSubnet2.id
  route_table_id = aws_route_table.testPrivateRTb.id
}

 

반응형
Comments