적용 대상: ✔️ Linux VM
다음 Terraform 및 Terraform 공급자 버전을 사용하여 테스트한 기사:
이 문서에서는 Terraform을 사용하여 전체 Linux 환경 및 지원 리소스를 만드는 방법을 보여 줍니다. 이러한 리소스에는 가상 네트워크, 서브넷, 공용 IP 주소 등이 포함됩니다.
Terraform 을 사용하면 클라우드 인프라의 정의, 미리 보기 및 배포가 가능합니다. Terraform을 사용하여 HCL 구문을 사용하여 구성 파일을 만듭니다. HCL 구문을 사용하면 클라우드 공급자(예: Azure)와 클라우드 인프라를 구성하는 요소를 지정할 수 있습니다. 구성 파일을 만든 후에는 인프라 변경 내용을 배포하기 전에 미리 볼 수 있는 실행 계획을 만듭니다. 변경 내용을 확인하면 실행 계획을 적용하여 인프라를 배포합니다.
이 문서에서는 다음 방법을 알아봅니다.
- random_pet 사용하여 Azure 리소스 그룹 이름에 대한 임의 값을 만듭니다.
- azurerm_resource_group 사용하여 Azure 리소스 그룹을 만듭니다.
- azurerm_virtual_network 사용하여 VNET(가상 네트워크)을 만듭니다.
- azurerm_subnet 사용하여 서브넷을 만듭니다.
- azurerm_public_ip 사용하여 공용 IP를 만듭니다.
- azurerm_network_security_group 사용하여 네트워크 보안 그룹을 만듭니다.
- azurerm_network_interface 사용하여 네트워크 인터페이스를 만듭니다.
- azurerm_network_interface_security_group_association 사용하여 네트워크 보안 그룹과 네트워크 인터페이스 간의 연결을 만듭니다.
- random_id 사용하여 고유한 스토리지 계정 이름에 대한 임의 값을 생성합니다.
- azurerm_storage_account 사용하여 부팅 진단에 대한 스토리지 계정을 만듭니다.
- azurerm_linux_virtual_machine 사용하여 Linux VM 만들기
- AzAPI 리소스 azapi_resource 만듭니다.
- azapi_resource_action 사용하여 SSH 키 쌍을 생성하는 AzAPI 리소스를 만듭니다.
필수 조건
Terraform 코드 구현
비고
이 문서의 샘플 코드는 Azure Terraform GitHub 리포지토리에 있습니다. 현재 및 이전 버전의 Terraform에서 테스트 결과를 포함하는 로그 파일을 볼 수 있습니다.
Terraform을 사용하여 Azure 리소스를 관리하는 방법을 보여 주는 더 많은 문서 및 샘플 코드를 참조하세요.
샘플 Terraform 코드를 테스트할 디렉터리를 만들고, 이를 현재 디렉터리로 만듭니다.
providers.tf
라는 파일을 만들고 다음 코드를 삽입합니다.terraform { required_version = ">=0.12" required_providers { azapi = { source = "azure/azapi" version = "~>1.5" } azurerm = { source = "hashicorp/azurerm" version = "~>3.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features {} }
ssh.tf
라는 파일을 만들고 다음 코드를 삽입합니다.resource "random_pet" "ssh_key_name" { prefix = "ssh" separator = "" } resource "azapi_resource_action" "ssh_public_key_gen" { type = "Microsoft.Compute/sshPublicKeys@2022-11-01" resource_id = azapi_resource.ssh_public_key.id action = "generateKeyPair" method = "POST" response_export_values = ["publicKey", "privateKey"] } resource "azapi_resource" "ssh_public_key" { type = "Microsoft.Compute/sshPublicKeys@2022-11-01" name = random_pet.ssh_key_name.id ___location = azurerm_resource_group.rg.___location parent_id = azurerm_resource_group.rg.id } output "key_data" { value = azapi_resource_action.ssh_public_key_gen.output.publicKey }
main.tf
라는 파일을 만들고 다음 코드를 삽입합니다.resource "random_pet" "rg_name" { prefix = var.resource_group_name_prefix } resource "azurerm_resource_group" "rg" { ___location = var.resource_group_location name = random_pet.rg_name.id } # Create virtual network resource "azurerm_virtual_network" "my_terraform_network" { name = "myVnet" address_space = ["10.0.0.0/16"] ___location = azurerm_resource_group.rg.___location resource_group_name = azurerm_resource_group.rg.name } # Create subnet resource "azurerm_subnet" "my_terraform_subnet" { name = "mySubnet" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.my_terraform_network.name address_prefixes = ["10.0.1.0/24"] } # Create public IPs resource "azurerm_public_ip" "my_terraform_public_ip" { name = "myPublicIP" ___location = azurerm_resource_group.rg.___location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Dynamic" } # Create Network Security Group and rule resource "azurerm_network_security_group" "my_terraform_nsg" { name = "myNetworkSecurityGroup" ___location = azurerm_resource_group.rg.___location resource_group_name = azurerm_resource_group.rg.name security_rule { name = "SSH" priority = 1001 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" } } # Create network interface resource "azurerm_network_interface" "my_terraform_nic" { name = "myNIC" ___location = azurerm_resource_group.rg.___location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "my_nic_configuration" subnet_id = azurerm_subnet.my_terraform_subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.my_terraform_public_ip.id } } # Connect the security group to the network interface resource "azurerm_network_interface_security_group_association" "example" { network_interface_id = azurerm_network_interface.my_terraform_nic.id network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id } # Generate random text for a unique storage account name resource "random_id" "random_id" { keepers = { # Generate a new ID only when a new resource group is defined resource_group = azurerm_resource_group.rg.name } byte_length = 8 } # Create storage account for boot diagnostics resource "azurerm_storage_account" "my_storage_account" { name = "diag${random_id.random_id.hex}" ___location = azurerm_resource_group.rg.___location resource_group_name = azurerm_resource_group.rg.name account_tier = "Standard" account_replication_type = "LRS" } # Create virtual machine resource "azurerm_linux_virtual_machine" "my_terraform_vm" { name = "myVM" ___location = azurerm_resource_group.rg.___location resource_group_name = azurerm_resource_group.rg.name network_interface_ids = [azurerm_network_interface.my_terraform_nic.id] size = "Standard_DS1_v2" os_disk { name = "myOsDisk" caching = "ReadWrite" storage_account_type = "Premium_LRS" } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-jammy" sku = "22_04-lts-gen2" version = "latest" } computer_name = "hostname" admin_username = var.username admin_ssh_key { username = var.username public_key = azapi_resource_action.ssh_public_key_gen.output.publicKey } boot_diagnostics { storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint } }
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 "username" { type = string description = "The username for the local account that will be created on the new VM." default = "azureadmin" }
outputs.tf
라는 파일을 만들고 다음 코드를 삽입합니다.output "resource_group_name" { value = azurerm_resource_group.rg.name } output "public_ip_address" { value = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address }
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
를 호출합니다.
비용 정보는 Azure Portal과 마찬가지로 Terraform에 대한 가상 머신 생성 프로세스 중에 표시되지 않습니다. 가상 머신의 비용 작동 방식에 대해 자세히 알아보려면 비용 최적화 개요 페이지를 참조하세요.
결과 확인
Azure 리소스 그룹 이름을 가져옵니다.
resource_group_name=$(terraform output -raw resource_group_name)
JMESPath 쿼리를 사용하여 az vm list를 실행하여 리소스 그룹에서 만든 가상 머신의 이름을 표시합니다.
az vm list \ --resource-group $resource_group_name \ --query "[].{\"VM Name\":name}" -o table
자원을 정리하세요
Terraform을 통해 만든 리소스가 더 이상 필요하지 않은 경우 다음 단계를 수행합니다.
terraform 계획을 실행하고 플래그를 지정합니다
destroy
.terraform plan -destroy -out main.destroy.tfplan
핵심 사항:
-
terraform plan
명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다. - 선택 사항인
-out
매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다.-out
매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
-
terraform을 실행하여 실행 계획을 적용합니다.
terraform apply main.destroy.tfplan
Azure에서 Terraform 문제 해결
Azure에서 Terraform을 사용할 때 발생하는 일반적인 문제 해결
다음 단계
이 빠른 시작에서는 Terraform을 사용하여 간단한 가상 머신을 배포했습니다. Azure 가상 머신에 대한 자세한 내용을 알아보려면 Linux VM의 자습서를 계속 진행합니다.