다음을 통해 공유


빠른 시작: 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 코드 구현

  1. 샘플 Terraform 코드를 테스트 및 실행할 디렉터리를 만들고 현재 디렉터리로 만듭니다.

  2. 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 {}
    }
    
  3. 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
      }
    }
    
  4. 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."
    }
    
  5. 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을 통해 리소스를 만들 필요가 더 이상 없으면 다음 단계를 수행합니다.

  1. terraform 플랜을 실행하고 destroy 플래그를 지정합니다.

    terraform plan -destroy -out main.destroy.tfplan
    

    주요 정보:

    • terraform plan 명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다.
    • 선택 사항인 -out 매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다. -out 매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
  2. terraform apply를 실행하여 실행 계획을 적용합니다.

    terraform apply main.destroy.tfplan
    

Azure의 Terraform 문제 해결

Azure에서 Terraform을 사용할 때 일반적인 문제 해결

다음 단계

이 빠른 시작에서는 IoT 허브 및 Device Provisioning Service 인스턴스를 배포하고, 두 리소스를 연결했습니다. 이 설정을 사용하여 디바이스를 프로비저닝하는 방법을 알아보려면 디바이스를 만들기 위한 빠른 시작으로 계속 진행하세요.