테라폼(Terraform)은 인프라를 코드로 관리하는 도구입니다(Infra as Code, IaC). 쉽게 말해, 서버, 데이터베이스, 네트워크 등의 인프라 리소스를 프로그래밍 코드로 정의하고 관리할 수 있도록 해줍니다. 이를 통해 인프라를 더 쉽게 배포하고 관리할 수 있습니다.
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
prerequisite: azure cli가 설치되어 있어야 합니다.
테라폼 로직 코드를 작성하는 메인 파일입니다. 테라폼에서는 다른 파일들을 import 없이 참조할 수 있습니다.
module "network_peering" {
source = "./modules/network_association/network_peering"
common_resource_group_name = var.common_resource_group_name
subscription_id = var.subscription_id
common_subscription_id = local.common_subscription_id
resource_group_name = module.resource_group.resource_group_name
}
main.tf에서 사용되는 변수를 저장합니다.
main.tf를 실행한 결과를 출력합니다. 여기서 출력한 값을 다른 모듈에서 참조할 수 있습니다.
테라폼 환경변수를 저장합니다(.env 파일과 흡사). 보안상 민감한 정보를 저장하기 때문에 .gitignore에 추가합니다. 여기에 정의된 변수는 variables.tf에 똑같은 변수명으로 정의되어 있어야 하며 자동으로 참조됩니다.
테라폼에 의해 생성된 리소스들이 어떻게 정의되어 있는지 상태를 저장, 관리합니다. apply 명령어에 의해 자동으로 생성되지만, import 명령어로 상태를 업데이트 할 수도 있습니다.
# 테라폼 상태파일에 리소스 추가
terraform import azurerm_key_vault_access_policy.client <resource_id>
# 해당 리소스 상태 확인
terraform state show azurerm_mysql_flexible_server.example_mysql
# 상태파일에 등록된 리소스 나열
terraform state list
main.tf에서 사용할 커스텀 변수를 저장합니다.
프로바이더를 저장합니다.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.107.0"
}
}
}
사용할 프로바이더의 버전을 설정할 수 있습니다.
provider "azurerm" {
features {}
}
사용할 프로바이더를 선언합니다.
main.tf에서 동시에 두개 이상의 구독을 제어하는 경우엔 다음과 같이 두개의 프로바이더에 구독id와 alias를 지정합니다.
provider "azurerm" {
features {}
alias = "source" # alias 속성을 사용하면 resource 마다 provider를 지정해야함.
subscription_id = var.subscription_id
}
provider "azurerm" {
features {}
alias = "common" # alias 속성을 사용하면 resource 마다 provider를 지정해야함.
subscription_id = var.common_subscription_id
}
프로바이더에 alias를 정의하면 main.tf 에서 리소스를 생성/참조할 때 반드시 어느 프로바이더를 사용할지 설정해야 합니다.
resource "azurerm_virtual_network_peering" "SourceToCommon" {
provider = azurerm.source # 어떤 프로바이더를 사용할지 설정합니다.
name = "peerSourceToCommon"
resource_group_name = data.azurerm_resource_group.dev.name
virtual_network_name = var.vnet_name # data.azurerm_virtual_network.source_vnet.name
remote_virtual_network_id = data.azurerm_virtual_network.common_vnet.id
allow_virtual_network_access = true
allow_forwarded_traffic = true
}
resource "azurerm_virtual_network_peering" "CommonToSource" {
provider = azurerm.common
name = "peerCommonToSource"
resource_group_name = data.azurerm_resource_group.common_rg.name
virtual_network_name = data.azurerm_virtual_network.common_vnet.name
remote_virtual_network_id = var.vnet_id # data.azurerm_virtual_network.source_vnet.id
allow_virtual_network_access = true
allow_forwarded_traffic = true
}
리소스를 생성합니다. 변경사항이 없는 경우, 리소스는 재생성되지 않습니다. 그러나 변경사항이 있는 경우, 데이터베이스와 같은 리소스는 삭제 후 재생성될 수 있으므로, 프로퍼티 변경 시 재생성 여부를 확인하고 수정해야 합니다. 재생성이 실수로 이루어지는 것을 방지하기 위해, lifecycle의 prevent_destroy 옵션을 추가할 수 있습니다. 테라폼 Argument Reference에 "Changing this forces a new resource to be created."라는 설명이 있을 경우, 해당 프로퍼티 변경 시 리소스가 재생성됩니다.
resource "azurerm_mysql_flexible_server" "example_mysql" {
provider = azurerm.source
name = var.mysql_name
location = var.location
resource_group_name = var.resource_group_name
administrator_login = var.mysql_admin_username
administrator_password = var.mysql_admin_password
sku_name = var.mysql_flexible_server_sku_name
version = "8.0.21"
zone = 3
## prevent_destroy가 참이면 재생성 방지
lifecycle {
prevent_destroy = true
}
}
이미 생성되어 있는 리소스를 참조합니다. 참조한 리소스는 data객체에 저장됩니다.
data "azurerm_resource_group" "common_rg" {
provider = azurerm.common
name = var.common_resource_group_name
}
resource "azurerm_virtual_network_peering" "SourceToCommon" {
provider = azurerm.source # 어떤 프로바이더를 사용할지 설정합니다.
name = "peerSourceToCommon"
## 참조 data 사용
resource_group_name = data.azurerm_resource_group.dev.name
virtual_network_name = var.vnet_name
remote_virtual_network_id = data.azurerm_virtual_network.common_vnet.id
allow_virtual_network_access = true
allow_forwarded_traffic = true
}
module "network_peering" {
source = "./modules/network_association/network_peering"
common_resource_group_name = var.common_resource_group_name
subscription_id = var.subscription_id
common_subscription_id = var.common_subscription_id
resource_group_name = module.resource_group.resource_group_name
vnet_name = module.virtual_network.vnet_name
vnet_id = module.virtual_network.vnet_id # 모듈 연동
}
프로퍼티 값에 module객체로 다른 모듈을 참조하면 (예:vnet_id =module.virtual_network.vnet_id) 참조된 모듈이 먼저 실행됩니다.
변수를 정의합니다. 이는 주로 variables.tf 파일에서 수행합니다. description에는 변수에 대한 설명을 작성하고, type에는 변수의 타입을 명시하며, default에는 기본값을 입력할 수 있습니다. terraform.tfvars 파일에 일치하는 변수가 없을 경우, 기본값이 사용됩니다.
variable "vm_size" {
description = "The size of the virtual machine"
type = string
default = "Standard_DS1_v2"
}
테라폼에서는 운영 환경에 따라 서로 다른 구성을 적용할 수 있게 workspace 기능을 제공합니다.
workspace는 각 환경의 독립적인 상태 파일을 유지하고, 환경별로 다른 변수 파일을 사용하여 각 환경에 적합한 설정을 적용할 수 있습니다.
workspace를 적용하면 명령어를 다음과 같이 작성합니다.
# dev workspace 선택 terraform workspace select dev
# dev 환경변수 파일이 envs 디렉토리에 있을 경우. terraform plan -out=tfplan -var-file=envs/dev.tfvars
# workspace 목록 확인 terraform workspace list
# 현재 workspace 확인 terraform workspace show
# workspace 생성 terraform workspace new dev
# workspace 삭제 terraform workspace delete dev
# workspace 선택 terraform workspace select dev
리소스의 프로퍼티 변경을 막기 위해, lifecycle.ignore_changes 속성을 추가할 수 있습니다.
# 예시
resource "azurerm_mysql_flexible_server" "example_mysql" {
name = var.mysql_name
location = var.location
resource_group_name = var.resource_group_name
administrator_login = var.mysql_admin_username
administrator_password = var.mysql_admin_password
sku_name = var.mysql_flexible_server_sku_name
version = "8.0.21"
lifecycle {
ignore_changes = [
# 무시할 속성 목록 추가
]
}
}