본문 바로가기

DevOps/Terraform

[T102 4주차] (14) 테라폼 모듈 (2)

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

 

4주차 내용:  테라폼 모듈 

😎 모듈과 프로바이더 

  • 모듈에서 사용되는 모든 리소스는 관련 프로바이더의 정의가 필요함
  • 프로바이더 정의 ( inner vs outer ) 

✔️ 유형 1 . 자식 모듈에서 프로바이더 정의 

  • 모듈에서 사용하는 프로바이더 버전과 구성 상세를 자식 모듈에서 정의 하는 방법이다.
  • 프로바이더 버전과 구성에 민감하거나, 루트 모듈에서 프로바이더 정의 없이 자식 모듈이 독립적인 구조 일때 사용
  • 하지만 동일한 프로바이더가 루트와 자식 양쪽에 또는 서로 다른 자식 모듈에 버전 조건 합의가 안 되면, 오류가 발생하고 모듈에 반복문을 사용할 수 없다는 단점이 있으므로 잘 사용하지 않는다.

 

✔️ 유형 2. 루트 모듈에서 프로바이더 정의 

  • 자식 모듈루트 모듈프로바이더 구성에 종속되는 방식이다
  • 디렉터리 구조로는 분리되어 있지만 테라폼 실행 단계에서 동일 계층으로 해석되므로 프로바이더 버전과 구성은 루트 모듈의 설정이 적용된다.
  • 프로바이더를 모듈 내 리소스와 데이터 소스에 일괄 적용하고, 자식 모듈에 대한 반복문 사용에 자유로운 것이 장점이다.
  • 자식 모듈에 특정 프로바이더 구성의 종속성은 반영할 수 없으므로 자식 모듈을 프로바이더 조건에 대해 기록하고, 자식 모듈을 사용하는 루트 모듈에서 정의하는 프로바이더에 맞게 업데이트 해야 한다.
# ✅ 디렉터리 생성
mkdir -p 06-module-traning/multi_provider_for_module/

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

# ✅ 테라폼 실행 및 확인
cd 06-module-traning/multi_provider_for_module/
terraform init
cat .terraform/modules/modules.json | jq

#
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
자식 모듈에서 필요로 하는 프로바이더의 버전이 루트 모듈의 정의와 다른 경우, 테라폼 구성에서 정의한 내용이 서로 호환되지 않아 오류가 발생할 수 있다.

😎 모듈 반복문 ? 

✔️ 모듈의 반복문  (count )

  • 모듈 또한 리소스에서 반복문을 사용하듯 구성할수 있다.
  • 모듈이라는 리소스 정의 묶음을 원하는 수량으로 로비저닝할 수 있으므로 모듈 없이 구성하는 것과 대비해 리소스 종속성 관리와 유지 보수에 장점이 있다.
  • count를 사용한 반복문 사용은 리소스에서의 사용 방식처럼 module 블록 내에 선언한다.
# ✅ 디렉터리 생성
mkdir -p 06-module-traning/module_loop_count/

# ✅ 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   
}
# ✅ 테라폼 실행 및 확인

#
cd 06-module-traning/module_loop_count/
terraform init
cat .terraform/modules/modules.json | jq

#
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
  • count를 통한 반복문 실행

✔️ 모듈의 반복문 ( for_each )

  • 동일한 모듈에 입력 변수를 다르게 처리하는 방식으로 count 대신 for_each를 사용

 

# ✅ 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
  ]
}
# ✅ 테라폼 실행 및 확인
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

✔️ 인스턴스 유형을 입력변수로 각각 다르게 배포