1
기본 원칙 : 모듈은 대부분의 프로그래밍 언어에서 쓰이는 라이브러리나 패키지와 역할이 비슷하다
2
모듈 디렉터리 형식을 terraform-<프로바이더 이름>-<모듈 이름> 형식을 제안한다.
예) terraform-aws-module
디렉토리 또는 레지스트리 이름 - 어떤 프로바이더 - 모듈 이름
1
구성 ?
random_pet는 이름을 자동으로 생성
random_password는 사용자의 패스워드를 설정
https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet
2
자식 모듈을 만든다.
root 모듈을 만들어 자식모듈을 불러 쓴다.
3
mkdir -p 06-module-traning/modules/terraform-random-pwgen
cd 06-module-traning/modules/terraform-random-pwgen
4
자식 모듈 만든다 ?
main.tf , variable.tf , output.tf 파일 3개를 만든다.
vi main.tf
resource "random_pet" "name" {
keepers = {
ami_id = timestamp()
}
}
resource "random_password" "password" {
length = var.isDB ? 16 : 10
special = var.isDB ? true : false
override_special = "!#$%*?"
}
5
vi variable.tf
variable "isDB" {
type = bool
default = false
description = "패스워드 대상의 DB 여부"
}
6
vi output.tf
output "id" {
value = random_pet.name.id
}
output "pw" {
value = nonsensitive(random_password.password.result)
}
7
자식 모듈 테스트
#
cd 06-module-traning/modules/terraform-random-pwgen
#
ls *.tf
terraform init && terraform plan
# 테스트를 위해 apply 시 변수 지정
terraform apply -auto-approve -var=isDB=true
// 변수를 true로 해서 실행!!!
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
id = "knowing-aardvark"
pw = "Y5eeP0i2KLLE9gBa"
# 확인
terraform state list
terraform state show random_pet.name
terraform state show random_password.password
# tfstate에 모듈 정보 확인
cat terraform.tfstate | grep module
# graph 확인
terraform graph > graph.dot
8
자식 모듈 호출 실습
mkdir -p 06-module-traning/06-01-basic
vi main.tf
module "mypw1" {
source = "../modules/terraform-random-pwgen"
}
module "mypw2" {
source = "../modules/terraform-random-pwgen"
isDB = true
}
output "mypw1" {
value = module.mypw1
}
output "mypw2" {
value = module.mypw2
}
9
실행 : 자식 모듈을 호출해 반복 재사용하는 루트 모듈의 결과
#
cd 06-module-traning/06-01-basic
#
terraform init && terraform plan && terraform apply -auto-approve
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
mypw1 = {
"id" = "equipped-mustang"
"pw" = "OXST1EYqQc"
}
mypw2 = {
"id" = "diverse-impala"
"pw" = "y8mEbOJhS6dCTiK#"
}
// 반복문처럼 Output이 나온다. 자식모듈을 호출해서 반복 사용을 했다.
// 패스워드 길이가 다르다. 10자리, 16자리
# 확인
terraform state list
10
# tfstate에 모듈 정보 확인
cat terraform.tfstate | grep module
테라폼 root 모듈 state 파일의 resources 부분에 module 내용이 생긴다.
11
# terraform init 시 생성되는 modules.json 파일 확인
tree .terraform
.terraform
├── modules
│ └── modules.json
...
## 모듈로 묶여진 리소스는 module이라는 정의를 통해 단순하게 재활용하고 반복 사용할 수 있다.
## 모듈의 결과 참조 형식은 module.<모듈 이름>.<output 이름>으로 정의된다.
cat .terraform/modules/modules.json | jq
{
"Modules": [
{
"Key": "",
"Source": "",
"Dir": "."
},
{
"Key": "mypw1",
"Source": "../modules/terraform-random-pwgen",
"Dir": "../modules/terraform-random-pwgen"
},
{
"Key": "mypw2",
"Source": "../modules/terraform-random-pwgen",
"Dir": "../modules/terraform-random-pwgen"
}
]
}
# graph 확인
terraform graph > graph.dot
1
Root module에 공통적으로 프로바이더를 설정하라.
Child module에 설정하면 문제가 될수 있다.
자식모듈은 루트 모듈의 프로바이더에 종속된다.
모듈에는 다수의 프로바이더가 사용될 가능성이 있으므로 map타입으로 구성하는 provider로 정의한다.
문제 ?
Root와 자식 모듈간에 조건 합의가 안되면 오류가 발생한다.
Child module에서 프로바이더를 쓰면, 반복문을 쓸수 없다.
2
실습을 위한 디렉터리 구성의 예
06-module-traning
├─ modules # child
│ └── terraform-aws-ec2
│ └──main.tf
└─ multi_provider_for_module #root
└──main.tf
3
# child
mkdir -p 06-module-traning/modules/terraform-aws-ec2/
4
# ec2 배포하는 내용 - 디폴트 vpc 사용 예제.
vi main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
resource "aws_default_vpc" "default" {}
data "aws_ami" "default" {
most_recent = true
owners = ["amazon"]
filter {
name = "owner-alias"
values = ["amazon"]
}
filter {
name = "name"
values = ["amzn2-ami-hvm*"]
}
}
resource "aws_instance" "default" {
depends_on = [aws_default_vpc.default]
ami = data.aws_ami.default.id
instance_type = var.instance_type
tags = {
Name = var.instance_name
}
}
// depends_on = [aws_default_vpc.default]
디폴트 vpc가 있는지 디펜트온을 걸어 놓는다.
ami = data.aws_ami.default.id
// ami은 data에서 가져온다.
instance_type = var.instance_type
// 인스턴스는 var 변수에서 가져온다.
5
vi variable.tf
variable "instance_type" {
description = "vm 인스턴스 타입 정의"
default = "t2.micro"
}
variable "instance_name" {
description = "vm 인스턴스 이름 정의"
default = "my_ec2"
}
6
vi output.tf
output "private_ip" {
value = aws_instance.default.private_ip
}
1
06-module-traning/multi_provider_for_module/main.tf 과 output.tf 파일 생성
mkdir -p 06-module-traning/multi_provider_for_module/
cd 06-module-traning/multi_provider_for_module/
2
vi main.tf
provider "aws" {
region = "ap-southeast-1"
}
provider "aws" {
alias = "seoul"
region = "ap-northeast-2"
}
module "ec2_singapore" {
source = "../modules/terraform-aws-ec2"
}
module "ec2_seoul" {
source = "../modules/terraform-aws-ec2"
providers = {
aws = aws.seoul
}
instance_type = "t3.small"
}
// 디폴트는 싱가포르로 생성된다.
// 서울은 프로바이더에 값을 주어, 서버 타입을 t3로 변경한다.
3
vi output.tf
output "module_output_singapore" {
value = module.ec2_singapore.private_ip
}
output "module_output_seoul" {
value = module.ec2_seoul.private_ip
}
4
실행 : 프로바이더 구성을 테스트
cd 06-module-traning/multi_provider_for_module/
terraform init
cat .terraform/modules/modules.json | jq
// key라는 이름으로 싱가포르와 서울이 구분된다.
#
terraform apply -auto-approve
terraform output
terraform state list
terraform state show module.ec2_seoul.data.aws_ami.default
terraform state show module.ec2_singapore.data.aws_ami.default
cat terraform.tfstate | grep module
# graph 확인
terraform graph > graph.dot
# aws cli로 ec2 확인
aws ec2 describe-instances --region ap-northeast-2 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
aws ec2 describe-instances --region ap-southeast-1 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
// 콘솔에서 확인
서울 리전에서 확인
싱가포르 리전에서 확인
# 실습 완료 후 리소스 삭제
terraform destroy -auto-approve
모듈내에서도 반복문을 사용할 수 있다.
1
디렉터리 생성 및 06-module-traning/module_loop_count/main.tf 파일 생성
2
mkdir -p 06-module-traning/module_loop_count/
3
vi main.tf
provider "aws" {
region = "ap-northeast-2"
}
module "ec2_seoul" {
count = 2
source = "../modules/terraform-aws-ec2"
instance_type = "t3.small"
}
output "module_output" {
value = module.ec2_seoul[*].private_ip
}
4
실행 : 모듈의 반복문 테스트
cd 06-module-traning/module_loop_count/
terraform init
cat .terraform/modules/modules.json | jq
terraform apply -auto-approve
콘솔에서 ec2 생성 확인
terraform output
terraform state list
cat terraform.tfstate | grep module
# graph 확인
terraform graph > graph.dot
# aws cli로 ec2 확인
aws ec2 describe-instances --region ap-northeast-2 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
# 실습 완료 후 리소스 삭제
terraform destroy -auto-approve
모듈 묶음에 일관된 구성과 구조로 프로비저닝이 되는 경우라면 count가 간편한 방안이지만,
동일한 모듈 구성에 필요한 인수 값이 다르다면 for_each를 활용한다.
1
06-module-traning/module_loop_count/main.tf 파일 수정
cd 06-module-traning/module_loop_count
2
vi main.tf
locals {
env = {
dev = {
type = "t3.micro"
name = "dev_ec2"
}
prod = {
type = "t3.medium"
name = "prod_ec2"
}
}
}
module "ec2_seoul" {
for_each = local.env
source = "../modules/terraform-aws-ec2"
instance_type = each.value.type
instance_name = each.value.name
}
output "module_output" {
value = [
for k in module.ec2_seoul: k.private_ip
]
}
3
#
terraform plan
terraform apply -auto-approve
terraform output
terraform state list
cat terraform.tfstate | grep module
# graph 확인
terraform graph > graph.dot
# aws cli로 ec2 확인
aws ec2 describe-instances --region ap-northeast-2 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
# 실습 완료 후 리소스 삭제
terraform destroy -auto-approve
1
https://developer.hashicorp.com/terraform/language/modules/sources
https://developer.hashicorp.com/terraform/language/modules/sources#terraform-registry
https://registry.terraform.io/?product_intent=terraform
2
테라폼 레지스트리 사용해보자.
테라폼 레지스트리 > 브라우저 모듈 사용할수 있다.
https://registry.terraform.io/browse/modules
https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest
3
aws vpc 모듈 실습 해보자~
https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest
https://github.com/terraform-aws-modules/terraform-aws-vpc
예제 )
https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/simple
mkdir work
cd work
git clone https://github.com/terraform-aws-modules/terraform-aws-vpc/
tree terraform-aws-vpc/examples -L 1
tree terraform-aws-vpc/examples -L 2
cd terraform-aws-vpc/examples/simple
ls *.tf
cat main.tf
4
코드 수정 : 서울 리전 변경, main.tf 파일 내용 확인
# 서울 리전 변경
grep 'eu-west-1' main.tf
sed -i -e 's/eu-west-1/ap-northeast-2/g' main.tf
# VPC CIDR 변경
grep '10.0.0.0' main.tf
sed -i -e 's/10.0.0.0/10.10.0.0/g' main.tf
# main.tf 파일 내용 확인
cat main.tf
...
module "vpc" {
source = "../../"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
tags = local.tags
}
5
# 모듈 확인 - 여기 내용을 참고한다. 자식모듈이다.
tree ../../modules
6
terraform init
cat .terraform/modules/modules.json| jq
# 생성된 리소스들 확인해보자!
terraform apply -auto-approve
// vpc가 만들어진다!!!!
terraform output
// 아웃풋이 많다. 재활용하자!!!
terraform state list
7
콘솔에서 VPC 확인하자!!!
# 실습 완료 후 리소스 삭제
terraform destroy -auto-approve
1
- 깃의 원격 저장소로 널리 알려진 깃허브는 테라폼 구성에 대한 CI 용도로 사용할 수 있고, 저장된 구성을 테라폼 모듈의 소스로 선언할 수도 있다
- 6.3에서 사용한 06-module-traning/modules/terraform-aws-ec2/ 를 깃허브에 업로드하는 과정
1. 깃허브에 로그인
2. 새로운 깃허브 저장소 생성 [New repository]
- Owner : 원하는 소유자 선택
- Repository name : 예시) **terraform-module-repo**
- Public 선택
- Add .gitignore의 드롭박스에서 [Terraform]을 선택
3. 맨 아래 [Create repository] 클릭
4. 해당 저장소에 예시) ‘**terraform-aws-ec2**’ 디렉터리 생성 후 main.tf , variable.tf, output.tf 추가 후 업로드
2
디렉터리 생성 후 main.tf 파일 생성
mkdir module-source-mygithub
3
# main.tf
provider "aws" {
region = "ap-southeast-1"
}
module "ec2_seoul" {
source = "github.com/<Owner Name>/terraform-module-repo/terraform-aws-ec2"
instance_type = "t3.small"
}
4
실행
#
cd module-source-mygithub
terraform init
# 아래 디렉터리에 깃허브에 있던 파일이 다운로드 되어 있음을 확인
tree .terraform/modules
# 배포
terraform apply -auto-approve
terraform state list
# 실습 완료 후 삭제
terraform destroy -auto-approve
https://brunch.co.kr/@topasvga/3395
전체 보기
https://brunch.co.kr/@topasvga/3347
https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863
감사합니다.