이 빠른 시작에서는 Terraform을 사용하여 Azure에서 프라이빗 DNS 영역, 네트워크 인터페이스, Windows 가상 머신, 프라이빗 DNS A 레코드, 네트워크 보안 그룹 및 네트워크 보안 규칙을 만듭니다.
Terraform 을 사용하면 클라우드 인프라의 정의, 미리 보기 및 배포가 가능합니다. Terraform을 사용하여 HCL 구문을 사용하여 구성 파일을 만듭니다. HCL 구문을 사용하면 클라우드 공급자(예: Azure) 그리고 클라우드 인프라를 구성하는 요소를 지정할 수 있습니다. 구성 파일을 만든 후에는 인프라 변경 내용을 배포하기 전에 미리 볼 수 있는 실행 계획을 만듭니다. 변경 내용을 확인 한 후에는 실행 계획을 적용하여 인프라를 배포합니다.
- 고유한 이름으로 Azure 리소스 그룹을 만듭니다.
- 지정된 이름과 주소를 사용하여 가상 네트워크를 설정합니다.
- 만든 가상 네트워크 내에서 서브넷을 설정합니다.
- 프라이빗 DNS 영역 만들기.
- 가상 머신에 대한 임의의 암호를 생성합니다.
- 두 개의 네트워크 인터페이스를 만듭니다.
- 두 개의 Windows 가상 머신을 만들고 네트워크 인터페이스를 연결합니다.
- 프라이빗 DNS A 레코드를 만듭니다.
- ICMP 트래픽을 허용하는 네트워크 보안 그룹 및 네트워크 보안 규칙을 만듭니다.
- 가상 머신의 이름 및 관리자 자격 증명을 출력합니다.
필수 조건
활성 구독이 있는 Azure 계정을 만듭니다. 계정을 무료로 만들 수 있습니다.
Terraform 코드 구현
참고 항목
이 문서의 샘플 코드는 Azure Terraform GitHub 리포지토리에 있습니다. 현재 및 이전 버전의 Terraform에서 테스트 결과를 포함하는 로그 파일을 볼 수 있습니다.
Terraform을 사용하여 Azure 리소스를 관리하는 방법을 보여 주는 더 많은 문서 및 샘플 코드를 참조하세요.
샘플 Terraform 코드를 테스트하고 실행할 디렉터리를 만들고 현재 디렉터리로 만듭니다.
이름이 지정된
main.tf
파일을 만들고 다음 코드를 삽입합니다.# Resource Group resource "random_pet" "rg_name" { separator = "-" } resource "azurerm_resource_group" "rg" { location = var.resource_group_location name = "${var.resource_group_name_prefix}-${random_pet.rg_name.id}" } # Random String for unique naming resource "random_string" "name" { length = 8 special = false upper = false lower = true numeric = false } # Virtual Network resource "azurerm_virtual_network" "vnet" { name = "vnet-${random_string.name.result}" address_space = var.address_space location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name } # Subnet resource "azurerm_subnet" "subnet" { name = "subnet-${random_string.name.result}" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.vnet.name address_prefixes = var.address_prefixes } # Private DNS Zone resource "azurerm_private_dns_zone" "dns_zone" { name = var.private_dns_zone_name resource_group_name = azurerm_resource_group.rg.name } # Private DNS Zone Virtual Network Link resource "azurerm_private_dns_zone_virtual_network_link" "dsn_vnet_link" { name = "dns-vnet-link-${random_string.name.result}" resource_group_name = azurerm_resource_group.rg.name private_dns_zone_name = azurerm_private_dns_zone.dns_zone.name virtual_network_id = azurerm_virtual_network.vnet.id } # Random Passwords for VMs resource "random_password" "vm1_admin_password" { length = 16 special = true } resource "random_password" "vm2_admin_password" { length = 16 special = true } # Network Interfaces resource "azurerm_network_interface" "nic1" { name = "nic1-${random_string.name.result}" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" } } resource "azurerm_network_interface" "nic2" { name = "nic2-${random_string.name.result}" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" } } # Windows Virtual Machines resource "azurerm_windows_virtual_machine" "vm1" { name = "vm1-${random_string.name.result}" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location size = "Standard_F2" admin_username = var.admin_username admin_password = random_password.vm1_admin_password.result network_interface_ids = [ azurerm_network_interface.nic1.id, ] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2019-Datacenter" version = "latest" } # Make idempotent vm_agent_platform_updates_enabled = true } resource "azurerm_windows_virtual_machine" "vm2" { name = "vm2-${random_string.name.result}" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location size = "Standard_F2" admin_username = var.admin_username admin_password = random_password.vm1_admin_password.result network_interface_ids = [ azurerm_network_interface.nic2.id, ] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2019-Datacenter" version = "latest" } # Make idempotent vm_agent_platform_updates_enabled = true } # Private DNS A Record resource "azurerm_private_dns_a_record" "pdar" { name = "test" zone_name = azurerm_private_dns_zone.dns_zone.name resource_group_name = azurerm_resource_group.rg.name ttl = 300 records = [azurerm_windows_virtual_machine.vm1.private_ip_address] } # Network Security Group resource "azurerm_network_security_group" "nsg" { name = "nsg-${random_string.name.result}" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name } # Network Security Rule resource "azurerm_network_security_rule" "nsr_icmp" { name = "Allow-ICMP" priority = 100 direction = "Inbound" access = "Allow" protocol = "Icmp" source_port_range = "*" destination_port_range = "*" source_address_prefix = "*" destination_address_prefix = "*" resource_group_name = azurerm_resource_group.rg.name network_security_group_name = azurerm_network_security_group.nsg.name }
이름이 지정된
outputs.tf
파일을 만들고 다음 코드를 삽입합니다.output "resource_group_name" { value = azurerm_resource_group.rg.name } output "windows_virtual_machine_1_name" { value = azurerm_windows_virtual_machine.vm1.name } output "windows_virtual_machine_2_name" { value = azurerm_windows_virtual_machine.vm2.name } output "windows_virtual_machine_1_password" { value = azurerm_windows_virtual_machine.vm1.admin_password sensitive = true } output "windows_virtual_machine_2_password" { value = azurerm_windows_virtual_machine.vm2.admin_password sensitive = true } output "windows_virtual_machine_1_admin_username" { value = azurerm_windows_virtual_machine.vm1.admin_username sensitive = true } output "windows_virtual_machine_2_admin_username" { value = azurerm_windows_virtual_machine.vm2.admin_username sensitive = true }
이름이 지정된
providers.tf
파일을 만들고 다음 코드를 삽입합니다.terraform { required_version = ">=1.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~>3.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features {} }
이름이 지정된
variables.tf
파일을 만들고 다음 코드를 삽입합니다.variable "resource_group_location" { type = string default = "eastus" description = "Location of the resource group." } variable "resource_group_name_prefix" { type = string default = "rg" description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription." } variable "address_space" { type = list(string) default = ["10.0.0.0/16"] description = "The address space that is used the virtual network." } variable "address_prefixes" { type = list(string) default = ["10.0.2.0/24"] description = "The address prefixes to use for the subnet" } variable "private_dns_zone_name" { type = string default = "private.contoso.com" description = "The name of the Private DNS Zone. Must be a valid domain name. Changing this value forces a new resource to be created." } variable "admin_username" { type = string default = "adminuser" description = "The username for the Windows virtual machines." }
Terraform 초기화
terraform init를 실행하여 Terraform 배포를 초기화합니다. 이 명령은 Azure 리소스를 관리하는 데 필요한 Azure 공급자를 다운로드합니다.
terraform init -upgrade
핵심 사항:
-
-upgrade
매개 변수는 필요한 공급자 플러그 인을 구성의 버전 제약 조건을 준수하는 최신 버전으로 업그레이드합니다.
Terraform 실행 계획 만들기
terraform 계획을 실행하여 실행 계획을 만듭니다.
terraform plan -out main.tfplan
핵심 사항:
-
terraform plan
명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다. - 선택 사항인
-out
매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다.-out
매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
Terraform 실행 계획 적용
terraform 적용을 실행하여 클라우드 인프라에 실행 계획을 적용합니다.
terraform apply main.tfplan
핵심 사항:
- 예시
terraform apply
명령은 이전에terraform plan -out main.tfplan
를 실행했다고 가정합니다. -
-out
매개 변수에 다른 파일 이름을 지정한 경우terraform apply
에 대한 호출에서 동일한 파일 이름을 사용합니다. -
-out
매개 변수를 사용하지 않은 경우 매개 변수 없이terraform apply
를 호출합니다.
결과 확인
실행
az network private-dns zone list
하여 모든 DNS 영역을 보고 찾습니다.az network private-dns zone list --output table
DNS 영역과 연결된 리소스 그룹을 보려면 실행
az network private-dns zone show
합니다.az network private-dns zone show --name $dnsZoneName --resource-group $resourceGroupName
리소스 정리
Terraform을 통해 리소스를 만들 필요가 더 이상 없으면 다음 단계를 수행합니다.
terraform 계획을 실행하고 플래그를 지정합니다
destroy
.terraform plan -destroy -out main.destroy.tfplan
핵심 사항:
-
terraform plan
명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다. - 선택 사항인
-out
매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다.-out
매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
-
terraform을 실행하여 실행 계획을 적용합니다.
terraform apply main.destroy.tfplan
Azure의 Terraform 문제 해결
Azure에서 Terraform을 사용할 때 발생하는 일반적인 문제를 해결합니다.