[TF] Terraform으로 VPC 구성 NAT Gateway 구성 -6

제이브로·2024년 7월 3일

Terraform

목록 보기
10/10
post-thumbnail

0. 기본 구성

Terraform으로 VPC 구성 Private Subnet 구성 -5 에서 이어지는 내용이 포함되어 있습니다.

주의!
NAT GatewayAWS에서 비용이 많이 발생하는 서비스이므로, 연습용으로 사용하신다면, 잠깐 생성하고 지우셔야 됩니다. 시간단위로 과금되기 때문에 실습이 끝나면 반드시 삭제하시기 바랍니다.

1. Nat Gateway 생성

Nat GatewayPrivate subnet에서 외부와 통신하기 위해서 필요한 일종의 게이트웨이입니다.

Nat GatewayPrivate subnet에서 외부와 통신하기 위해서 필요한 일종의 게이트웨이입니다.외부에서 Private subnet으로는 접근이 불가능하고, 사실 외부에서 접근하지 말아야하는 서비스는 Private subnet에 들어가는 것이 좋습니다.

하지만, Private subnet에 있는 서버에서는 외부와 통신해야하는 경우가 발생합니다.

ex) 필요한 패키지를 다운로드 받거나, 써드파티 API를 사용하는 경우에는 반드시 인터넷으로 요청을 보내야 합니다.

이럴 때 필요한 것이 바로 NAT Gateway입니다. Nat Gateway는 반드시 고정 IP(Elastic IP)를 가지고 있어야 하고, private subnet에서 보내는 모든 요청이 외부로 나갈 때는 내부IP가 아닌 고정 IP를 사용합니다.

ex) 고정IP13.1.1.1 이라면 외부로 나가는 모든 요청13.1.1.1에서 보낸 요청으로 표시됩니다.

10.0.4.1(내부 IP) → 13.1.1.1(고정 IP) → (외부 IP)

따라서, Nat Gateway를 만들 때는 AWS Elastic IP도 함께 생성해야 합니다. Nat GatewayPublic subnet에 위치하지만, 연결은 private subnet과 합니다. Public subnet에 위치하는 이유는 Nat Gateway 자체는 인터넷과 통신이 되어야 하기 때문입니다.

2. provider.tf

기본 구성에서 작성한 provider.tf 사용

2.1 전체 코드

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

3. resource.tf

기본 구성에서 작성한 resource.tf에 이어서 작성

...

resource "aws_eip" "nat" {
  vpc   = true

  lifecycle {
    create_before_destroy = true
  }
}

...

resource "aws_nat_gateway" "nat_gateway" {
  allocation_id = aws_eip.nat.id

  # Private subnet이 아니라 public subnet을 연결 주의!
  subnet_id = aws_subnet.public_subnet.id

  tags = {
    Name = "terraform-NAT-GW"
  }
}

...

resource "aws_route" "private_nat" {
  route_table_id              = aws_route_table.route_table_private.id
  destination_cidr_block      = "0.0.0.0/0"
  nat_gateway_id              = aws_nat_gateway.nat_gateway.id
}

3.1 전체 코드

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

  tags = {
    Name = "terraform-101"
  }
}

resource "aws_subnet" "public_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.0.0/24"

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "terraform-101-public-subnet"
  }
}

resource "aws_subnet" "private_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.10.0/24"

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "terraform-101-private-subnet"
  }
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "terraform-101-igw"
  }
}

resource "aws_eip" "nat" {
  vpc   = true

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_nat_gateway" "nat_gateway" {
  allocation_id = aws_eip.nat.id

  # Private subnet이 아니라 public subnet을 연결 주의!
  subnet_id = aws_subnet.public_subnet.id

  tags = {
    Name = "terraform-NAT-GW"
  }
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "terraform-rt-public"
  }
}

resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "terraform-rt-private"
  }
}

resource "aws_route_table_association" "route_table_association_public" {
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "route_table_association_private" {
  subnet_id      = aws_subnet.private_subnet.id
  route_table_id = aws_route_table.private.id
}

resource "aws_route" "private_nat" {
  route_table_id              = aws_route_table.route_table_private.id
  destination_cidr_block      = "0.0.0.0/0"
  nat_gateway_id              = aws_nat_gateway.nat_gateway.id
}

p.s. resource에 맞게 이름을 매칭시켜줘야 한다.

4. References

  1. 처음 시작하는 Infrastructure as Code: AWS & 테라폼
profile
기록하지 않으면 기록되지 않는다.

0개의 댓글