이번엔 Terraform의 꽃으로 불리는, 처음에는 조금 이해하기 어려운 개념인 Module을 알아보도록 한다.
Module
Terraform 코드들을 관련되어있는 것끼리 그룹으로 모아서 하나의 패키지 형태로 구성한 것
이때, 하나의 그룹으로 묶이는 단위는 '폴더'가 되며, 이 폴더 내의 테라폼 코드들이 모듈이 된다.
개발을 해본 사람이면 쉽게 라이브러리 개념으로 바라볼 수 있다. 정의해둔 라이브러리를 다른 프로젝트나 코드에서 import해서 사용하는 것같은 느낌이다.
Module의 장점
재사용성
Module은 코드의 재사용성을 높일 수 있다. 한번 작성해놓은 인프라 리소스 모듈을 다른 인프라나 프로젝트에서 호출함을 통해 개발비용을 줄이고 일관된 구조를 유지할 수 있다.
구조화와 가독성
본래 Terraform은 하나의 .tf 파일에 모든 리소스를 작성해도 동작한다. 하지만 구조가 거대해지면 관리하기 어려워지고, 가독성도 떨어지며, 휴먼 에러와 같은 오류가 발생할 확률이 높아지게 된다. Module을 적용함으로써 각 리소스들을 묶어 분리하게 되면 코드들이 구조화되고 관리의 용이성을 높일 수 있다.
캡슐화
각 모듈은 연관되어있는 리소스끼리 논리적으로 묶여 캡슐화된다. 이를 통해 의도하지 않은 문제가 발생하는 것을 막을 수 있다.
Module의 구조
앞서 이야기했듯이 Module은 폴더 단위로 묶이게된다. Module은 Root Module과 Child Module로 나누어 볼 수 있다.
- Root Module : Terraform command(apply, destroy 등)가 실행되는 모듈로, 필수적인 모듈이다.
- Child Module : 다른 Module에 호출되어 사용되는 Module
일반적으로 Module로 구분시켜둔 Terraform 프로젝트 구조는 아래와 같이 구성되어 있다고 한다.
Module 작성은 아래와 같다.
module "tf_test_vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "tf_test_vpc"
cidr = "192.168.10.0/24"
...
}
VPC 생성을 Module을 이용해서 생성하는 모습이다.
source에는 Module을 어디서 가져올 것인지를 명시해주는 부분으로, 이 source 구문으로 가져올 수 있는 Module은 여러 종류가 존재한다. 대표적으로 사용되는 3가지를 알아보도록 한다.
Local
local에 저장된 module을 가져온다. 호출하는 위치로부터 module까지의 상대경로로 작성한다. (Terraform은 Source 호출에 절대경로를 지원하지 않는다고 한다.)
Github
Github repository에 올라간 module을 가져온다. github URL을 인식해서 해당 주소의 Repository에서 자동으로 가져온다.
# HTTPS를 통해서 Clone
module "consul" {
source = "github.com/hashicorp/example"
}
# SSH를 통해서 Clone
module "consul" {
source = "git@github.com:hashicorp/example.git"
}
Registry
Terraform registry에 올라간 module을 가져온다. Terraform은 docker hub와 같은 registry를 제공한다.
사용방법도 docker hub와 마찬가지로, 각 모듈별로 할당된 모듈 이름을 가져오는 것이다.
Source 주소의 포맷은 <네임스페이스>/<이름>/<Provider>로 각 Registry의 페이지 별로 사용방법이 적혀있다.
Module 사용해보기
간단하게 VPC와 서브넷을 생성하는 Terraform 코드를 Module을 이용해서 작성해보도록 하자.
vpc 폴더를 생성해, Module로 정의하고
vpc/variables.tf
variable "moduletest_vpc_cidr" {
type = string
default = "192.168.10.0/24"
description = "CIDR of VPC"
}
moduletest_vpc_cidr 변수를 생성해 VPC의 CIDR 값을 저장하도록 했다.
vpc/main.tf
resource "aws_vpc" "tf_modulestudy_vpc" {
cidr_block = var.moduletest_vpc_cidr
}
VPC 리소스를 생성한다. 여기서 위에서 생성해주었던 변수(moduletest_vpc_cidr)를 cidr_block 값으로 넣어준다.
main.tf
module "tf_test_vpc" {
source = "./vpc"
moduletest_vpc_cidr = "192.168.11.0/24"
}
local에 존재하는 vpc 모듈을 불러오고, 변수(moduletest_vpc_cidr)에 값을 지정해주었다.
output.tf
output "moduletest_vpc_id" {
value = aws_vpc.tf_modulestudy_vpc.id
description = "VPC ID"
}
생성된 리소스(VPC)의 ID값을 output으로써 출력하도록한다.