본문 바로가기

DevOps/Terraform

[T102 4주차] (13) 테라폼 모듈(1)

cloudNet@ 팀의 가시다 님이 진행하는 테라폼 102 스터디 4주차 정리입니다.
4주차 내용:  테라폼 모듈

😃  테라폼 모듈? 

 

  •  테라폼으로 인프라와 서비스를 관리하면 시간이 지날수록 구성이 복잡해지고 관리하는 리소스가 늘어나게 된다. 테라폼의 구성 파일과 디렉터리 구성에는 제약이 없기 때문에 단일 파일 구조상에서 지속적으로 업데이트할 수 있지만, 다음과 같은 문제가 발생한다.
    • ❌  테라폼 구성에서 원하는 항목을 찾고 수정하는 것이 점점 어려워짐
    • ❌  리소스들 간의 연관 관계가 복잡해질수록 변경 작업의 영향도를 분석하기 위한 노력이 늘어남
    •  개발/스테이징/프로덕션 환경으로 구분된 경우 비슷한 형태의 구성이 반복되어 업무 효율이 줄어듦
    • ❌  새로운 프로젝트를 구성하는 경우 기존 구성에서 취해야 할 리소스 구성과 종속성 파악이 어려움
따라서 모듈이란 개념을 통해 관리한다.


 

😃  테라폼 모듈 구분 ?

 

루트 모듈과 자식 모듈

  • 루트 모듈 ( Root Module ): 테라폼을 실행하고 프로비저닝 하는 최상위 디렉토리 
  • 자식 모듈 ( Child Module ) : 루트 모듈이 호출 하는 외부 구성 집합

✅ 모듈은 테라폼 구성의 집합

 

모듈 사용의 장점

  • 관리성 : 모듈은 서로 연관있는 구성의 묶음이다. 원하는 구성요소를 단위별로 쉽게 찾고 업데이트할 수 있다. 모듈은 다른 구성에서 쉽게 하나의 덩어리로 추가하거나 삭제할 수 있다. 또한 모듈이 업데이트되면 이 모듈을 사용하는 모든 구성에서 일관된 변경 작업을 진행할 수 있다.
  • 캡슐화 : 테라폼 구성 내에서 각 모듈은 논리적으로 묶여져 독립적으로 프로비저닝 및 관리되며, 그 결과는 은닉성을 갖춰 필요한 항목만을 외부에 노출시킨다.
  • 재사용성 : 구성을 처음부터 작성하는 것에는 시간과 노력이 필요하고 작성 중간에 디버깅과 오류를 수정하는 반복 작업이 발생한다. 테라폼 구성을 모듈화하면 이후에 비슷한 프로비저닝에 이미 검증된 구성을 바로 사용할 수 있다.
  • 일관성과 표준화 : 테라폼 구성 시 모듈을 활용하는 워크플로는 구성의 일관성을 제공하고 서로 다른 환경과 프로젝트에도 이미 검증한 모듈을 적용해 복잡한 구성과 보안 사고를 방지할 수 있다.

 


😃  모듈 작성의 원칙 ?

 

  기본원칙 : 모듈은 대부분의 프로그래밍 언어에서 사용하는 라이브러리나 패키지와 역할이 비슷하다.

  • 모듈 디렉터리 형식을 terraform-<프로바이더 이름>-<모듈 이름> 형식을 제안한다. 이 형식은 Terraform Cloud, Terraform Enterprise에서도 사용되는 방식으로  디렉터리 또는 레지스트리 이름이 테라폼을 위한 것이고,  어떤 프로바이더의 리소스를 포함하고 있으며,  부여된 이름이 무엇인지 판별할 수 있도록 한다.
  • 테라폼 구성은 궁극적으로 모듈화가 가능한 구조로 작성할 것을 제안한다. 처음부터 모듈화를 가정하고 구성파일을 작성하면 단일 루트 모듈이라도 후에 다른 모듈이 호출할 것을 예상하고 구조화할 수 있다. 또한 작성자는 의도한 리소스 묶음을 구상한 대로 논리적인 구조로 그룹화할 수 있다.
  • 공개된 테라폼 레지스트리의 모듈을 참고하기를 제안한다. 대다수의 테라폼 모듈은 공개된 모듈이 존재하고 거의 모든 인수에 대한 변수 처리, 반복문 적용 리소스, 조건에 따른 리소스 활성/비활성 등을 모범 사례로 공개해두었다. 물론 그대로 가져다 사용하는 것보다는 프로비저닝하려는 상황에 맞게 참고하는 것을 권장한다.
  • 작성된 모듈은 공개 또는 비공개로 게시해 팀 또는 커뮤니티와 공유하기를 제안한다. 모듈의 사용성을 높이고 피드백을 통해 더 발전된 모듈을 구성할 수 있는 자극이 된다.
  • 모듈을 독립적으로 관리하기 위해 디렉터리 구조를 생성할 때 모듈을 위한 별도 공간을 생성하는 방식으로 진행한다. 특정 루트 모듈 하위에 자식 모듈을 구성하는 경우 단순히 복잡한 코드를 분리하는 요도로 명시되며 종속성이 발생하므로 루트 모듈 사이에 모듈 디렉터리를 지정한다. 

😃  모듈 실습 해보기

✅ 디렉토리 생성

mkdir -p 06-module-traning/modules/terraform-random-pwgen
✅ main.tf 생성

cat <<EOT > 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 = "!#$%*?"
}
EOT


✅ variable.tf 생성

cat <<EOT > variable.tf
# variable.tf
variable "isDB" {
  type        = bool
  default     = false
  description = "패스워드 대상의 DB 여부"
}
EOT

✅ output.tf 생성

cat <<EOT > output.tf
# output.tf
output "id" {
  value = random_pet.name.id
}

output "pw" {
  value = nonsensitive(random_password.password.result) 
}
EOT
✅ 실행 및 확인
#
cd 06-module-traning/modules/terraform-random-pwgen

#
ls *.tf
terraform init && terraform plan

# 테스트를 위해 apply 시 변수 지정
terraform apply -auto-approve -var=isDB=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

 

  • 리소스를 module 사용 없이 배포한 경우 다음과 같이 tfstate에 module 관련 상태값이 없음

 

  • 반대로 module 사용하여 자식 모듈 구성 해보고 비교해보자
✅ 자식 모듈 디렉토리 생성
mkdir -p 06-module-traning/06-01-basic
✅ 모듈을 활용하여 리소스 배포 ( 반복적으로 사용하기 좋음 )

#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
}
#
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#"
}

# 확인
terraform state list

# tfstate에 모듈 정보 확인
cat terraform.tfstate | grep module

# 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

 

 

 

  • 자식 모듈 사용시 tfstate에 모듈 관련 State가 생성된것을 볼수 있음