terraform

[Terraform] 테라폼의 모듈화

bbiyak2da 2024. 11. 30. 12:36

Module

  • Terraform 구성 파일 내 재사용 가능한 블록으로, 특정 인프라 리소스를 정의하고 관리하는데 사용 (템플릿?)
  • 테라폼 모듈(일반적으로 루트 모듈)은 다른 모듈들을 호출하여 리소스를 구성에 포함시킬 수 있다.

Root Module

  • 테라폼을 실행하고 프로비저닝하는 최상위 모듈

 

Child Module

  • Root Module에서 활용하기 위해 참조하는 모듈

 

Module 구현

  • Module은 providers.tf, main.tf, variables.tf, outputs.tf 와 같은 4가지 tf파일로 구성된다.
    • providers.tf : 모듈에 사용될 provider의 최소 요구 버전 명시
    • main.tf : 모듈로 생성할 resource block 모음
    • variables.tf : 루트 모듈에서 입력해야 하는 input 값 정의
    • outputs.tf : 출력할 속성값 명시

예시

.
├── main.tf
├── outputs.tf
└── vnet
    ├── main.tf
    ├── outputs.tf
    └── variables.tf

 

 

[예시]

 

# 자식 모듈(vnet 모듈) - main.tf

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "East US"  # 원하는 지역으로 변경
}

resource "azurerm_virtual_network" "main" {
  name                = "example-vnet"
  address_space      = [var.vnet_cidr_block]
  location           = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_subnet" "public" {
  name                 = "public-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = [var.public_subnet_cidr_block]
}

resource "azurerm_subnet" "private" {
  name                 = "private-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = [var.private_subnet_cidr_block]
}

resource "azurerm_public_ip" "nat" {
  name                = "example-nat-ip"
  location           = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  allocation_method   = "Static"
}

resource "azurerm_nat_gateway" "main" {
  name                = "example-nat-gateway"
  location           = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  sku {
    name     = "Standard"
    tier     = "Standard"
  }
  public_ip_address_ids = [azurerm_public_ip.nat.id]
}

resource "azurerm_subnet_nat_gateway_association" "public" {
  subnet_id      = azurerm_subnet.public.id
  nat_gateway_id = azurerm_nat_gateway.main.id
}

resource "azurerm_route_table" "private" {
  name                = "example-private-route-table"
  location           = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  route {
    name                   = "private-route"
    address_prefix         = "0.0.0.0/0"
    next_hop_type         = "VirtualAppliance"
    next_hop_in_ip_address = azurerm_nat_gateway.main.id
  }
}

resource "azurerm_subnet_route_table_association" "private" {
  subnet_id      = azurerm_subnet.private.id
  route_table_id = azurerm_route_table.private.id
}

 


# 자식 모듈(vnet 모듈) - outputs.tf

output "vnet_id" {
  value = azurerm_virtual_network.main.id
}

output "public_subnet_id" {
  value = azurerm_subnet.public.id
}

output "private_subnet_id" {
  value = azurerm_subnet.private.id
}

 

# 자식 모듈(vnet 모듈) - variables.tf

variable "vnet_cidr_block" {
  type = string
}

variable "public_subnet_cidr_block" {
  type = string
}

variable "private_subnet_cidr_block" {
  type = string
}

 

이렇게 자식 모듈(vnet)을 정의해주었으니, 루트 모듈에서 활용해보자

 

# 루트 모듈 - main.tf

terraform {
  required_version = ">=0.12"

  required_providers {
    azapi = {
      source  = "azure/azapi"
      version = "~>1.5"
    }
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

module "vnet" {
  source                    = "./vnet"
  vnet_cidr_block            = "10.0.0.0/16"
  public_subnet_cidr_block  = "10.0.0.0/24"
  private_subnet_cidr_block = "10.0.1.0/24"
}

 

provider의 버전 정보는 보통 providers.tf 파일을 별도로 생성하기도 하지만,

main.tf 파일 내 block으로 지정해도 된다.

 

# 루트 모듈 - outputs.tf

output "vnet_id" {
  value = azurerm_virtual_network.main.id
}

output "public_subnet_id" {
  value = azurerm_subnet.public.id
}

output "private_subnet_id" {
  value = azurerm_subnet.private.id
}

 

이후 terraform init, plan, apply 실행 시키면 자식 모듈을 활용하여 루트 모듈에서 리소스 배포가 가능하다.

 


참고 문서

 

https://medium.com/@hyukjuner/terraform-azure-module-%EB%A7%8C%EB%93%A4%EA%B8%B0-fac1238800a4

 

Terraform Azure Module 만들기

재사용 가능한 테라폼 모듈 만들기

medium.com

https://velog.io/@gentledev10/terraform-create-module

 

Terraform module 만들기

Module 을 직접 만들어 보자

velog.io