일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Gateway
- Service Account
- httpasswd
- Terraform
- Docker0
- aws-loadbalacner-controller
- 추가 보안 그룹
- route53
- NAT
- assumerole
- clusterrolebinding
- 클러스터 보안 그룹
- IRSA
- jenkins
- s3
- 에이전트 구성
- helm_release
- Amazon CloudWatch
- 테라폼
- fruition
- saa-c03 #saa #aws certified solutions architect - associate
- ingestion
- 코드커버리지
- aws ses #aws lambda
- kubernetes
- 에이전트 유형
- node group
- Pipeline
- instances failed to join cluster
- docker
- Today
- Total
cloudwithbass
[Terraform] 모듈화 연습하기1: VPC와 Subnet, 모듈화 본문
목차
이번 포스팅에선 모듈화 연습을 위해 간단한 데모를 만들어볼 것입니다.
vpc와 subnet을 이용합니다. 클릭 시 관련 테라폼 문서로 이동할 수 있습니다.
혹시 포스팅에 잘못된 점이나 개선점이 있을 경우, 댓글로 알려주시면 정말 감사드리겠습니다.
전체 코드는 다음 주소에서 확인 가능합니다.
https://github.com/Dminus251/practice-terraform/tree/main/demo01-vpc_subnet
resource 블록을 제외한 블록들입니다.
1. vpc와 subnet 생성
모듈화를 하기 전에, main.tf의 초기 코드를 보겠습니다.
테라폼의 vpc, subnet 문서를 참조해서 main.tf에 다음 코드를 작성합니다.
이 코드는 cidr이 10.0.0.0/16인 VPC와, 그 안에서 public subnet과 private subnet을 각각 하나씩 프로비저닝합니다.
main.tf
# main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "practice"
}
}
resource "aws_subnet" "subnet-public-1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = "true" #퍼블릭 ip 자동 할당 기능 활성화
#이 subnet에서 생성되는 instance에는 자동으로 publci ip가 할당된다.
tags = {
Name = "practice-public-1"
}
}
resource "aws_subnet" "subnet-private-1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.3.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "practice-priavte-1"
}
}
2. 모듈로 만들기
다음 디렉터리 구조를 참고해서 modules 디렉터리와 그 하위 요소들을 생성합니다.
이제 1번에서 main.tf에 작성한 vpc와 subnet 코드를 각각 modules/t-aws-vpc/main.tf와 modules/t-aws-subnet/main.tf로 옮길 건데, 코드가 조금 바뀔 것입니다.
먼저 t-aws-vpc/ 디렉터리입니다.
modules/t-aws-vpc/main.tf
# modules/t-aws-vpc/main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "practice"
}
}
modules/t-aws-vpc/outputs.tf
# modules/t-aws-vpc/outputs.tf
output "vpc-id" {
value = aws_vpc.main.id
}
- modules/t-aws-vpc/에는 outputs.tf 파일이 추가됐습니다.
- output 블록을 이용하면 해당 내용을 사용자에게 보여주거나, 다른 모듈로 값을 전달할 수 있습니다.
- 추후에 subnet은 vpc의 id가 필요하므로 이 값을 subnet 모듈에 전달할 것입니다.
다음으로 t-aws-subnet 디렉터리를 확인해보겠습니다.
modules/t-aws-subnet/main.tf
# modules/t-aws-subnet/main.tf
resource "aws_subnet" "subnet-public-1" {
vpc_id = var.vpc-id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = "true" #퍼블릭 ip 자동 할당 기능 활성화
#이 subnet에서 생성되는 instance에는 자동으로 publci ip가 할당된다.
tags = {
Name = "practice-public-1"
}
}
resource "aws_subnet" "subnet-private-1" {
vpc_id = var.vpc-id
cidr_block = "10.0.3.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "practice-priavte-1"
}
}
modules/t-aws-subnet/vars.tf
# modules/t-aws-subnet/vars.tf
variable "vpc-id" {
type = string
}
- 서브넷은 vpc 내에 생성되므로 aws_subnet 리소스는 vpc_id를 요구합니다.
- 하지만 subnet 모듈 내에는 vpc 리소스가 없으므로 이곳에선 vpc의 id도 알 수가 없습니다.
- 따라서 일단 변수를 사용한다고 정의만 해놓고(vpc_id = var.vpc-id), t-aws-vpc/ 디렉터리에서 작성한 output을 루트 모듈에서 사용할 것입니다.
마지막으로 루트 디렉터리의 main.tf 내용입니다.
main.tf
module "vpc" {
source = "./modules/t-aws-vpc"
}
module "subnet" {
source = "./modules/t-aws-subnet"
vpc-id = module.vpc.vpc-id
}
- source는 모듈의 위치를 나타냅니다.
- subnet 모듈의 vpc-id는, subnet 모듈 내의 variable입니다.
- 서브넷의 vpc_id에 vpc-id라는 변수를 할당했으니 이곳에서 그 값을 정의해야 합니다.
- 이 때 그 값은 vpc 모듈의 output인 vpc-id를 사용합니다.
3. variable 이용하기
모듈화의 목적 중 하나는 코드 재사용성을 향상시키는 것입니다.
현재는 cidr, az 등이 하드코딩되어 있으므로 코드를 재사용하기 힘듭니다.
vpc 모듈부터 수정하겠습니다.
modules/t-aws-vpc/main.tf
#modules/t-aws-vpc/main.tf
resource "aws_vpc" "main" {
cidr_block = var.vpc-cidr
instance_tenancy = "default"
tags = {
Name = var.vpc-name
}
}
다음과 같이 변수를 사용해 수정했습니다.
- cidr_block: "10.0.0.0/16" → var.vpc-cidr
- tags.Name: "practice" → var.vpc-name
변수는 아래 처럼 vars.tf 파일에 정의합니다.
modules/t-aws-vpc/vars.tf
#modules/t-aws-vpc/vars.tf
variable "vpc-cidr" {
type = string
default = "10.0.0.0/16"
}
variable "vpc-name" {
type = string
default = "practice"
}
이렇게 하면, 변경 사항이 있을 때 vars.tf만 변경하면 되므로 코드의 재사용성이 향상됐습니다.
다음으로 subnet 모듈을 보겠습니다.
modules/t-aws-subnet/vars.tf
variable "subnets" {
type = map(object({
cidr_block = string
availability_zone = string
map_public_ip_on_launch = bool
}))
default = {
"practice-public-1" = {
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = true
},
"practice-private-1" = {
cidr_block = "10.0.3.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = false
}
}
}
subnets을 변수로 선언했습니다.
subnets는 map(object) 타입이며, default 값으론 기존 main.tf의 값들이 들어가 있습니다.
(참고) Object
- object도 map처럼 '{'와 '}'를 사용합니다.
- map은 map(string)이나 map(list)와 같이 key-value 쌍에서 value의 타입이 강제됩니다.
- 하지만 object는 string, bool 등 여러 타입을 사용할 수 있습니다.
- object는 주로 리소스의 attribute( cidr_block, availability_zone과 같은)를 나타내기 위한 데이터 구조이기 때문입니다.
이제 이 map(object) 타입의 변수인 subnets를 사용하면 다음과 같이 main.tf를 간소화할 수 있습니다.
modules/t-aws-subnet/main.tf
#modules/t-aws-subnet/main.tf
resource "aws_subnet" "subnets" {
for_each = var.subnets
vpc_id = var.vpc-id
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
}
}
for_each는 반복문입니다.
for_each = var.subnets이므로 var.subnets의 각 요소에 대해 반복합니다.
ar.subnets은 길이가 2인 리스트이므로 두 번 반복해서 aws_subnet 리소스를 생성할 것입니다.
참고 문서
'Terraform' 카테고리의 다른 글
[Terraform] ★ 테라폼 연습하기 6: eks cluster 구성과 Assume Role, kubeconfig (0) | 2024.09.01 |
---|---|
[Terraform] 테라폼 연습하기 5: security group (0) | 2024.08.31 |
[Terraform] 테라폼 연습하기 4: ec2 instance (0) | 2024.08.29 |
[Terraform] 테라폼 연습하기3: NAT gateway (0) | 2024.08.27 |
[Terraform] 공부 내용 정리 (1) | 2024.08.22 |