빠른 시작: Terraform을 사용하여 Azure IoT Device Provisioning Service 만들기
이 빠른 시작에서는 Terraform을 사용하여 해시된 할당 정책을 사용하여 Azure IoT Hub DPS(Device Provisioning Service) 리소스를 배포하는 방법을 알아봅니다.
이 빠른 시작은 다음 Terraform 및 Terraform 공급자 버전으로 테스트되었습니다.
Terraform은 클라우드 인프라의 정의, 미리 보기 및 배포를 사용합니다. Terraform을 사용하는 경우 HCL 구문를 사용하여 구성 파일을 만듭니다. HCL 구문을 사용하면 클라우드 공급자(예: Azure) 그리고 클라우드 인프라를 구성하는 요소를 지정할 수 있습니다. 구성 파일을 만든 후 배포되기 전에 인프라 변경을 미리 볼 수 있는 실행 계획를 만듭니다. 변경 내용을 확인 한 후에는 실행 계획을 적용하여 인프라를 배포합니다.
이 문서에서는 다음 방법을 설명합니다.
- Storage 계정 및 Storage 컨테이너 만들기
- Event Hubs, 네임스페이스 및 권한 부여 규칙 만들기
- IoT Hub 만들기
- Storage 계정 엔드포인트 및 Event Hubs 엔드포인트에 IoT Hub 연결
- IoT Hub 공유 액세스 정책 만들기
- DPS 리소스 만들기
- DPS 및 IoT Hub 연결
필수 조건
- Azure 구독: Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.
Terraform 코드 구현
참고 항목
이 문서의 예제 코드는 Azure Terraform GitHub 리포지토리에 있습니다. Terraform을 사용하여 Azure 리소스를 관리하는 방법을 보여 주는 추가 문서 및 샘플 코드를 참조하세요.
샘플 Terraform 코드를 테스트 및 실행할 디렉터리를 만들고 현재 디렉터리로 만듭니다.
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 {} }
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 storage account & container resource "random_string" "sa_name" { length = 12 special = false upper = false } resource "azurerm_storage_account" "sa" { name = random_string.sa_name.id resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = "Standard" account_replication_type = "LRS" } resource "azurerm_storage_container" "my_terraform_container" { name = "mycontainer" storage_account_name = azurerm_storage_account.sa.name container_access_type = "private" } # Create an Event Hub & Authorization Rule resource "random_pet" "eventhub_namespace_name" { prefix = var.eventhub_namespace_name_prefix } resource "azurerm_eventhub_namespace" "namespace" { name = random_pet.eventhub_namespace_name.id resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location sku = "Basic" } resource "azurerm_eventhub" "my_terraform_eventhub" { name = "myEventHub" resource_group_name = azurerm_resource_group.rg.name namespace_name = azurerm_eventhub_namespace.namespace.name partition_count = 2 message_retention = 1 } resource "azurerm_eventhub_authorization_rule" "my_terraform_authorization_rule" { resource_group_name = azurerm_resource_group.rg.name namespace_name = azurerm_eventhub_namespace.namespace.name eventhub_name = azurerm_eventhub.my_terraform_eventhub.name name = "acctest" send = true } # Create an IoT Hub resource "random_pet" "iothub_name" { prefix = var.iothub_name_prefix length = 1 } resource "azurerm_iothub" "iothub" { name = random_pet.iothub_name.id resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location sku { name = "S1" capacity = 1 } endpoint { type = "AzureIotHub.StorageContainer" connection_string = azurerm_storage_account.sa.primary_blob_connection_string name = "export" batch_frequency_in_seconds = 60 max_chunk_size_in_bytes = 10485760 container_name = azurerm_storage_container.my_terraform_container.name encoding = "Avro" file_name_format = "{iothub}/{partition}_{YYYY}_{MM}_{DD}_{HH}_{mm}" } endpoint { type = "AzureIotHub.EventHub" connection_string = azurerm_eventhub_authorization_rule.my_terraform_authorization_rule.primary_connection_string name = "export2" } route { name = "export" source = "DeviceMessages" condition = "true" endpoint_names = ["export"] enabled = true } route { name = "export2" source = "DeviceMessages" condition = "true" endpoint_names = ["export2"] enabled = true } enrichment { key = "tenant" value = "$twin.tags.Tenant" endpoint_names = ["export", "export2"] } cloud_to_device { max_delivery_count = 30 default_ttl = "PT1H" feedback { time_to_live = "PT1H10M" max_delivery_count = 15 lock_duration = "PT30S" } } tags = { purpose = "testing" } } #Create IoT Hub Access Policy resource "azurerm_iothub_shared_access_policy" "hub_access_policy" { name = "terraform-policy" resource_group_name = azurerm_resource_group.rg.name iothub_name = azurerm_iothub.iothub.name registry_read = true registry_write = true service_connect = true } # Create IoT Hub DPS resource "random_pet" "dps_name" { prefix = var.dps_name_prefix length = 1 } resource "azurerm_iothub_dps" "dps" { name = random_pet.dps_name.id resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location allocation_policy = "Hashed" sku { name = "S1" capacity = 1 } linked_hub { connection_string = azurerm_iothub_shared_access_policy.hub_access_policy.primary_connection_string location = azurerm_resource_group.rg.location allocation_weight = 150 apply_allocation_policy = true } }
variables.tf
라는 파일을 만들고 다음 코드를 삽입합니다.variable "resource_group_location" { default = "eastus" description = "Location of the resource group." } variable "resource_group_name_prefix" { 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 "eventhub_namespace_name_prefix" { default = "namespace" description = "Prefix of the event hub namespace name that's combined with a random ID so name is unique in your Azure subscription." } variable "iothub_name_prefix" { default = "iothub" description = "Prefix of the iot hub name that's combined with a random ID so name is unique in your Azure subscription." } variable "dps_name_prefix" { default = "dps" description = "Prefix of the dps name that's combined with a random ID so name is unique in your Azure subscription." }
outputs.tf
라는 파일을 만들고 다음 코드를 삽입합니다.output "azurerm_iothub_name" { value = azurerm_iothub.iothub.name } output "azurerm_iothub_dps_name" { value = azurerm_iothub_dps.dps.name } output "resource_group_name" { value = azurerm_resource_group.rg.name }
Terraform 초기화
terraform init를 실행하여 Terraform 배포를 초기화합니다. 이 명령은 Azure 리소스를 관리하는 데 필요한 Azure 공급자를 다운로드합니다.
terraform init -upgrade
주요 정보:
-upgrade
매개 변수는 필요한 공급자 플러그 인을 구성의 버전 제약 조건을 준수하는 최신 버전으로 업그레이드합니다.
Terraform 실행 계획 만들기
terraform plan을 실행하여 실행 계획을 만듭니다.
terraform plan -out main.tfplan
주요 정보:
terraform plan
명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다.- 선택 사항인
-out
매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다.-out
매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
Terraform 실행 계획 적용
terraform apply를 실행하여 실행 계획을 클라우드 인프라에 적용합니다.
terraform apply main.tfplan
주요 정보:
- 예시
terraform apply
명령은 이전에terraform plan -out main.tfplan
를 실행했다고 가정합니다. -out
매개 변수에 다른 파일 이름을 지정한 경우terraform apply
에 대한 호출에서 동일한 파일 이름을 사용합니다.-out
매개 변수를 사용하지 않은 경우 매개 변수 없이terraform apply
를 호출합니다.
결과 확인
az iot dps show를 실행하여 Azure DPS 리소스를 표시합니다.
az iot dps show \
--name <azurerm_iothub_dps_name> \
--resource-group <resource_group_name>
주요 정보:
terraform apply
출력에 리소스 그룹 및 DPS 인스턴스의 이름이 표시됩니다. terraform output을 실행하여 이러한 출력 값을 볼 수도 있습니다.
리소스 정리
Terraform을 통해 리소스를 만들 필요가 더 이상 없으면 다음 단계를 수행합니다.
terraform 플랜을 실행하고
destroy
플래그를 지정합니다.terraform plan -destroy -out main.destroy.tfplan
주요 정보:
terraform plan
명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다.- 선택 사항인
-out
매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다.-out
매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
terraform apply를 실행하여 실행 계획을 적용합니다.
terraform apply main.destroy.tfplan
Azure의 Terraform 문제 해결
Azure에서 Terraform을 사용할 때 일반적인 문제 해결
다음 단계
이 빠른 시작에서는 IoT 허브 및 Device Provisioning Service 인스턴스를 배포하고, 두 리소스를 연결했습니다. 이 설정을 사용하여 디바이스를 프로비저닝하는 방법을 알아보려면 디바이스를 만들기 위한 빠른 시작으로 계속 진행하세요.