일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- route53
- clusterrolebinding
- Gateway
- node group
- saa-c03 #saa #aws certified solutions architect - associate
- aws-loadbalacner-controller
- 에이전트 구성
- 코드커버리지
- instances failed to join cluster
- 에이전트 유형
- helm_release
- fruition
- Amazon CloudWatch
- 클러스터 보안 그룹
- 추가 보안 그룹
- docker
- aws ses #aws lambda
- Terraform
- jenkins
- kubernetes
- 테라폼
- Pipeline
- Docker0
- s3
- httpasswd
- assumerole
- Service Account
- NAT
- IRSA
- ingestion
- Today
- Total
cloudwithbass
[Terraform] 테라폼 연습하기2: 퍼블릭 서브넷에 인터넷 연결 본문
지난 포스팅에서 VPC와 subnet을 생성해봤습니다. (https://cloudwithbass.tistory.com/43)
이번 포스팅에선 public subnet이 인터넷과 통신할 수 있도록 만들어보겠습니다.
인터넷과 통신하기 위해서 다음과 같은 리소스들이 필요합니다.
이름 클릭 시 해당 테라폼 문서로 이동합니다.
- IGW (Internet Gateway): VPC와 인터넷이 통신할 수 있게 해주는 모듈입니다.
- Route Table: 네트워크의 이동 경로를 정의하는 규칙입니다.
- Route table association: Route Table을 서브넷과 연결합니다.
모든 코드는 아래 github에서 확인할 수 있습니다.
https://github.com/Dminus251/practice-terraform/tree/main/demo02-igw_rt_rta
목차
1. IGW 구성하기
테라폼 문서를 따라 구성해줍니다.
간단하므로 코드만 보여드린 후 빠르게 넘어가겠습니다.
modules/t-aws-igw/main.tf
resource "aws_internet_gateway" "igw" {
vpc_id = var.vpc-id
tags = {
Name = var.igw-name
}
}
modules/t-aws-igw/variable.tf
variable "vpc-id"{
type = string
}
variable "igw-name"{
type = string
default = "practice-igw"
}
2. Route Table 구성하기
modules/t-aws-rt/main.tf
모든 IPv4 트래픽을 인터넷 게이트웨이로 보낼 것이므로 다음과 같이 작성합니다.
resource "aws_route_table" "internet" {
vpc_id = var.vpc-id
route { #route 1: 모든 트래픽을 igw로
cidr_block = "0.0.0.0/0" #from
gateway_id = var.igw-id #to
}
tags = {
Name = var.rt-name
}
}
인터넷 게이트웨이로 라우팅하기 위해 인터넷 게이트웨이의 id가 필요합니다. (line 6)
즉, 다른 모듈의 값이 필요하므로 igw 모듈에서 outputs.tf를 작성해줍니다.
modules/t-aws-igw/outputs.tf (route table 모듈이 아닙니다)
output "igw-id" {
value = aws_internet_gateway.igw.id
}
다시 route table 모듈로 돌아가서, vars.tf를 작성하겠습니다.
modules/t-aws-rt/vars.tf
variable "vpc-id" {
type = string
}
variable "igw-id" {
type = string
}
variable "rt-name" {
type = string
default = "practice-rt"
}
3. Route Table Association 구성하기
- Route Table Association은 어떤 route table을 어떤 subnet에 연결할 지 정의합니다.
- 따라서 route table의 id와 subnet의 id가 필요합니다.
하지만 여기서 문제가 생깁니다.
인터넷 트래픽은 private subnet에 접근해선 안 되는데, 기존 서브넷 모듈에선 public과 private 서브넷을 함께 생성하므로 subnet 모듈의 id가 private 서브넷의 id를 포함합니다.
(기존 서브넷 모듈 코드: https://github.com/Dminus251/practice-terraform/blob/main/demo01-vpc_subnet/modules/t-aws-subnet/main.tf)
따라서 subnet 모듈을 public과 private 용도로 분리할 필요가 생겼습니다.
3-1. private subnet
이번 포스팅에선 private subnet은 라우팅 대상이 아니기 때문에 기존 코드와 유사합니다.
modules/t-aws-private_subnet/main.tf
resource "aws_subnet" "private_subnets"{
vpc_id = var.vpc-id
for_each = var.private_subnets
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
tags = {
Name = each.key
}
}
modules/t-aws-private_subnet/main.tf
variable "vpc-id" {
type = string
}
variable "private_subnets" {
type = map(object({
cidr_block = string
availability_zone = string
}))
default = {
"private_subnet-1" = {
cidr_block = "10.0.2.0/24"
availability_zone = "ap-northeast-2a"
},
"private_subnet-2" = {
cidr_block = "10.0.4.0/24"
availability_zone = "ap-northeast-2a"
}
}
}
3-2 public subnet
modules/t-aws-public_subnet/main.tf
private subnet과의 차이점은 map_public_ip_on_launch attribute의 유무입니다.
default 값은 false인데, 이 속성을 true로 설정하면 이 서브넷에서 생성된 ec2 인스턴스에 자동으로 퍼블릭 ip가 할당됩니다.
resource "aws_subnet" "public_subnets"{
vpc_id = var.vpc-id
for_each = var.public_subnets
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
map_public_ip_on_launch = each.value.map_public_ip_on_launch
tags = {
Name = each.key
}
}
modules/t-aws-public_subnet/vars.tf
variable "vpc-id" {
type = string
}
variable "public_subnets" {
type = map(object({
cidr_block = string
availability_zone = string
map_public_ip_on_launch = bool
}))
default = {
"public_subnet-1" = {
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = true
},
"public_subnet-2" = {
cidr_block = "10.0.3.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = true
}
}
}
modules/t-aws-public_subnet/outputs.tf
두 개의 output을 추가했습니다.
output "public_subnet-length"{
value = length(var.public_subnets)
}
output "public_subnet-id" {
value = [for i in aws_subnet.public_subnets: i.id]
}
- public_subnet-length는 생성될 public subnet의 길이를 의미합니다.
- rta(route table association) 모듈에서 이 길이만큼 반복해서 라우팅 테이블을 연결할 것입니다.
- public_subnet-id 또한 rta에 사용됩니다. 각 퍼블릭 서브넷의 id가 리스트로 저장되어 있습니다.
4. rta(route table association) 구성하기
(24.08.27 추가) 이 코드는 모듈 내에서 반복문을 사용해서 코드 가독성이 좋지 않습니다. 따라서 테라폼 연습하기3 포스팅에서 반복문을 루트 모듈에서 사용하도록 수정했습니다. 따라서 해당 포스팅의 코드를 참고 바랍니다.
https://github.com/Dminus251/practice-terraform/tree/main/demo03-nat
modules/t-aws-rta/main.tf
resource "aws_route_table_association" "pulic" {
count = var.public_subnet-length
subnet_id = var.public_subnet-id[count.index]
route_table_id = var.rt-id
}
count는 반복문입니다.
count의 수만큼 이 리소스를 생성합니다.
modules/t-aws-rta/vars.tf
variable "public_subnet-id" {
type = list(string)
}
variable "rt-id" {
type = string
}
variable "public_subnet-length" {
type = number
}
rta는 라우팅 테이블과 서브넷을 연결하므로 각각의 id가 필요합니다.
public_subnet-length는 퍼블릭 서브넷의 길이를 할당할 변수입니다.
5. 루트 모듈 구성하기
최종적으로 완성된 루트 모듈의 main.tf입니다.
module "vpc" {
source = "./modules/t-aws-vpc"
}
module "public_subnet" {
source = "./modules/t-aws-public_subnet"
vpc-id = module.vpc.vpc-id
}
module "private_subnet" {
source = "./modules/t-aws-private_subnet"
vpc-id = module.vpc.vpc-id
}
module "igw" {
source = "./modules/t-aws-igw"
vpc-id = module.vpc.vpc-id
}
module "route_table" {
source = "./modules/t-aws-rt"
vpc-id = module.vpc.vpc-id
igw-id = module.igw.igw-id
}
module "rta-internet_to_public_subnet" {
source = "./modules/t-aws-rta"
public_subnet-length = module.public_subnet.public_subnet-length
public_subnet-id = module.public_subnet.public_subnet-id
rt-id = module.route_table.rt-id
}
main.tf에선 각 모듈에서 정의한 variable에 값을 할당해야 합니다.
rta-internet_to_public_subnet 모듈을 제외하곤 간단하니, 이 부분만 설명하겠습니다.
public_subnet-length = module.public_subnet.public_subnet-length
퍼블릭 서브넷 모듈의 output인 public_subnet-length를 할당합니다. (다홍색)이 다홍색 output은 퍼블릭 서브넷 리스트의 길이 ( = 퍼블릭 서브넷 개수)가 할당되어 있습니다.아래 코드인 modules/t-aws-public_subnet/outputs.tf를 참고해 주세요.
#modules/t-aws-public_subnet/outputs.tf 중 일부
output "public_subnet-length"{
value = length(var.public_subnets)
} #var.public_subnets에는 퍼블릭 서브넷들이 list(object)타입으로 default로 있음
public_subnet-id = module.public_subnet.public_subnet-id
좌측 다홍색은 rta 모듈의 variable이고, 우측 파란색은 public_subnet 모듈의 output입니다.modules/t-aws-public_subnet/outputs.tf의 public_subnet-id를 참조해주세요.
이 output은 list 타입이며, 각 인덱스에는 퍼블릭 서브넷의 id들이 할당되어 있습니다.따라서 public_subnet-id 변수에는 리스트가 할당됩니다.modules/t-aws-rta/main.tf의 코드 중 subnet_id = var.public_subnet-id[count.index] 코드가 인덱스를 반복하며 모든 퍼블릭 서브넷에 라우팅 테이블을 할당할 것입니다.즉, 이번 예제에서 count = 2니까 rta를 두 번 반복해서 생성합니다.public_subnet-id[0]과 라우팅 테이블을 연결하는 rtapublic_subnet-id[1]과 라우팅 테이블을 연결하는 rta
#modules/t-aws-rta/main.tf
resource "aws_route_table_association" "pulic" {
count = var.public_subnet-length
subnet_id = var.public_subnet-id[count.index] #이곳!
route_table_id = var.rt-id
}
terraform apply 명령 결과, 퍼블릭 서브넷에 라우팅 테이블이 잘 연결되어 있는 것을 확인할 수 있습니다.
코드를 모듈화하면 코드가 분산돼서 글로 설명하기엔 한계가 있는 것 같습니다.
최대한 자세히 작성했으나, 혹시 이해가 안 되거나 궁금한 점이 있다면 언제든 댓글로 남겨주세요!