Ssoon

Chapter (06) Module - 사용 형식 / 소스 관리 본문

Terraform 101 Study 2기

Chapter (06) Module - 사용 형식 / 소스 관리

구구달스 2023. 7. 24. 22:04
CloudNet@ 가시다님이 진행하는 Terraform 101 Study 2기
"테라폼으로 시작하는 IaC" (한빛미디어) 도서로 진행!

 Module 사용 형식

🧿 모듈과 프로바이더

  • Module 에서 사용되는 모든 리소스는 관련 프로바이더의 정의가 필요

프로바이더의 정의 위치 선택

✔ 유형 1. 자식 module 에서 프로바이더 정의 (잘 사용하지 않음)

  • 프로바이더 버전과 구성에 민감
  • 루트 모듈 에서 프로바이더 정의 없이 자식 모듈이 독립적인 구조
  • 단점
    • 동일한 프로바이더가 루트와 자식 양쪽에 또는 서로 다른 자식 모듈에 버전 조건 합의가 안 되면 오류 발생
    • 모듈에 반복문을 사용할 수 없음

 

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

  • 자식 모듈은 루트 모듈의 프로바이더 구성에 종속
  • 디렉터리 구조로는 분리되어 있지만 테라폼 실행 단계에서 동일 계층으로 해석
  • 프로바이더를 모듈 내 리소스와 데이터 소스에 일괄 적용
  • 자식 모듈에 대한 반복문 사용에 자유로움

  • 동일한 module 에 사용되는 프로바이더 조건이 다른 경우 각 module 별로 프로바이더를 맵핑하는 방법
    • 모듈에는 다수의 프로바이더가 사용될 가능성이 있으므로 map 타입으로 구성하는 provider로 정의                    

실습 디렉터리 구성

  • 06-module-training/modules/terraform-aws-ec2/

✔ 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
  }
}

✔ variable.tf (자식 모듈)

variable "instance_type" {
  description = "vm 인스턴스 타입 정의"
  default     = "t2.micro"
}

variable "instance_name" {
  description = "vm 인스턴스 이름 정의"
  default     = "my_ec2"
}

✔ output.tf (자식모듈)

output "private_ip" {
  value = aws_instance.default.private_ip
}
  • 06-module-training/multi_provider_for_module

✔ main.tf  (루트 모듈)

provider "aws" {
  region = "us-west-1"
}

provider "aws" {
  alias = "seoul"
  region = "ap-northeast-2"
}

module "ec2_california" {
  source = "../modules/terraform-aws-ec2"
}

module "ec2_seoul" {
  source = "../modules/terraform-aws-ec2"
  providers = {
    aws = aws.seoul
  }
  instance_type = "t2.micro"
}

 

✔ output.tf (루트모듈)

output "module_output_california" {
  value = module.ec2_california.private_ip
}

output "module_output_seoul" {
  value = module.ec2_seoul.private_ip
}
  • terraform apply 실행

  • aws console 확인

 

🧿 모듈의 반복문

  • module 이라는 리소스 정의 묶음을 원하는 수량으로 프로비저닝 가능
  • count 를 사용한 반복문 사용
    • 리소스에서의 사용 방식처럼 module 블록 내에 선언

 

  • 06-module-training/module_loop_count

✔ main.tf 

provider "aws" {
  region = "ap-northeast-2"
}

module "ec2-seoul" {
    count =2
    source = "../modules/terraform-aws-ec2"
}

output "module_output" {
  value = module.ec2-seoul[*].private_ip
}
  • terraform init 실행

  • terraform apply 실행

  • aws console 확인


  • 동일한 module 구성에 필요한 인수 값이 다르다면 for_each 사용

✔ main.tf 

locals {
  env = {
    dev = {
        type = "t2.micro"
        name = "dev_ec2"
    }
    prod = {
        type = "t3.micro"
        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 init 실행

terraform apply 실행

  • terraform apply 실행

  • aws console 확인

✅ 모듈 소스 관리

  • Module 블록에 정의된 소스 구성으로 모듈의 코드 위치를 정의
  • terraform init 을 수행할 때 지정된 module을 다운로드해 사용
  • module 소스 유형
    • 로컬 디렉터리
    • 테라폼 레지스트리
    • GitHub
    • Bitbucket
    • Git
    • S3
    • HTTP URLs

🧿 로컬 디렉터리

  • 테라폼 레지스트리와 구분하기 위해 하위 디렉터리는 ./ 로 상위 디렉터리는 ../ 로 시작
  • 대상 moudle 은 이미 같은 로컬 파일 시스템에 존재하므로 다운로드 없이 바로 사용
  • 재사용성이 고려된다면 상위 디렉터리에 별도 관리 권장
  • 항상 루트 module 과 함께 동작해야 하는 경우 하위 디렉터리에 module 정의

작업 환경 기준 > 로컬 경로 상위에 위치한 module 경로 선언

module "local_module" {
  source = "../modules/my_local_module"
}

🧿 테라폼 레지스트리

  • 테라폼 프로토콜을 사용해 module 을 사용하는 방식
  • 공개된 테라폼 module 사용하거나 Terraform Cloud, Enterprise 에서 제공되는 비공개 module 사용
  • 공개된 모듈 

https://registry.terraform.io/browse/modules

 

Terraform Registry

 

registry.terraform.io

  • 공개된 테라폼 module 을 source에 선언
    • <네임스페이스>/<이름>/<프로바이더>
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  version = "3.14.2"
}
  • Terraform Enterprise 처럼 비공개 module 사용 > source 선언 시 주소가 앞에 추가
    • <호스트 이름>/<네임스페이스>/<이름>/<프로바이더>
module "ecs_instance" {
  source = "app.terraform.io/alibaba/ecs-instance/alicloud"
  version = ">= 2.9.0"
}

🧿 깃허브

  • 앞서 실습한 terraform-aws-ec2 를 깃러브에 업로드 하는 과정
    1. 깃허브에 로그인
    2. 우측 상단 [+] 클릭 > [New repository] 선택 > 새로운 깃허브 저장소 생성
    3. Repository name 의 이름 입력 
    4. Public 선택
    5. Add .gitignore 에서 Terraform 선택
    6. Create reposiroty 선택

  • Create new file 선택

  • "terraform-aws-ec2" 입력 ▶ "/" 입력 ▶ "main.tf" 입력 ▶ 내용 입력 ▶ Commit change 클릭

  • 깃허브에 구성된  moidule 을 source 에 선언
    • github.com/<소유자 아이디>/<디렉터리>/<디렉터리>
provider "aws" {
  region = "ap-northeast-2"
}

module "ec2_seoul" {
    source = "github.com/kschoi728/terrafprm-module-repo/terraform-aws-ec2"
}

output "module_output"{
    value = module.ec2_seoul.private_ip
}
  • 깃허브 token 생성

 

  • terraform init 실행 - 깃허브의 module 을 다운로드

Comments