1.1.4.5. Azure IoT HubとIoT Connect Gatewayの自動構築コードを作成する

注釈

  • 本ページに記載の画像・設定項目は、2022年5月時点の情報です。Microsoft Azureの仕様変更により、内容が変更となる場合がありますのでご注意ください。

本書では、Azure IoT HubおよびIoT Connect Gateway(以下ICGW)を自動構築する際に作成するAzure DevOps - Release PipelinesのSecure Files、Variables、Ansible Playbookファイル、Job/Task例を記載しています。

なお、本書中の設定値の「< >」の表記については、ご利用の環境により各自入力いただく箇所となります("<"から">"までを設定値に置き換えてください)。

Secure Filesを作成する

Smart Data Platform(以下SDPF)のAPI情報や、ICGW・Azure IoT Hubのパラメーターを記載した.ymlファイルを作成し、Secure Filesに格納します。

なお、Secure Filesに格納されたファイルは自動で暗号化され、外部からは内容を確認できないようになっています。

アップロード後の内容の確認や修正はできませんのでご注意ください。

内容を編集したい場合は、ファイルを一度削除→再アップロードいただく形となります。

vars_icgw_iothub.yml(例)

SDPFのAPI情報やICGW・Azure IoT Hubの認証情報、設定値を保存したファイルです。

SDPFのAPI情報については、「1.1.3.3. Smart Data Platform APIの利用準備をする」を参照いただき、設定変更のうえご確認ください。

sdpf_apikey: <SDPF API鍵>
sdpf_secretkey: <SDPF API秘密鍵>
sdpf_tenantid: <SDPFワークスペースのテナントID(グローバル)>

token_host: https://api.ntt.com/keystone/v3/auth/tokens
icgw_host: https://api.ntt.com/iot-c-icgw/v1/tenants/

group_name: <ICGWでのSIMグループ名>
sim_imsi: "<SIMグループに割り当てるSIMのIMSI>"

az_auth_name: <認証設定名>
az_auth_description: <認証設定の説明文>
az_device_id: <Azure IoT Hubに登録するデバイス名>

az_pconv_name: <プロトコル変換設定名>
az_iot_hub_host: <Azure IoT Hubのホスト名>

Variablesを作成する

以下のとおり、Variablesを設定します。

設定画面の列「Scope」については、作成したStageを指定してください。

設定画面の列「Settable at release time」については、Offとしてください。

Variables
Name Value Example
backendResourceGroupLocation <Terraform状態ファイル保管用ストレージアカウントのリソースグループのリージョン> japaneast
backendResourceGroupName <Terraform状態ファイル保管用ストレージアカウントのリソースグループ名> backend-rg
backendStorageAccountName <Terraform状態ファイル保管用ストレージアカウント名> -(※3~24文字、数字と小文字のみ使用可能)
backendStorageAccountSku <Terraform状態ファイル保管用ストレージアカウントのSKU> Standard_LRS
iotDeviceId <Azure IoT Hubに登録するデバイス名> iot-device
iotHubName <作成するAzure IoT Hub名> -
iotHubSku <作成するAzure IoT HubのSKU> F1
pb_filename <ICGW自動設定用のAnsible Playbookファイル> pb_icgw_iothub.yml
resourceGroupLocation <IoT Hubを配置するAzure環境のリソースグループのリージョン> japaneast
resourceGroupName <IoT Hubを配置するAzure環境のリソースグループ名> iothub-rg
serviceConnection <作成したサービス接続名> -
subscriptionId <Azure環境のサブスクリプションID> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
vars_filename <SDPF APIおよびICGW、Azure IoT Hubの認証情報などが記入されたファイル> vars_icgw_iothub.yml
workingDirectory <作業ディレクトリ> $(System.DefaultWorkingDirectory)/<リポジトリ内のコードが保存されているディレクトリ>

Ansible Playbookファイルを作成する

ICGWの自動設定のため、ICGWに対する操作を定義したAnsible Playbookファイルを作成します。

ファイルは、Azure DevOpsと連携させたリポジトリ内のコード保存ディレクトリに格納してください。

- hosts: localhost
  vars_files:
    - "../../../../../_temp/vars_icgw_iothub.yml"

  tasks:
    - name: Get Authentication Token
      uri:
        url: "{{ token_host }}"
        headers:
          Content-Type: "application/json"
        status_code: 201
        method: "POST"
        body_format: "json"
        body:
          {
            "auth": {
              "identity": {
                "methods": [
                  "password"
                ],
                "password": {
                  "user": {
                    "domain": {
                      "id": "default"
                    },
                    "name": "{{ sdpf_apikey }}",
                    "password": "{{ sdpf_secretkey }}"
                  }
                }
              },
              "scope": {
                "project": {
                  "id": "{{ sdpf_tenantid }}"
                }
              }
            }
          }
      register: token
    - name: Print Response
      debug:
        var: token.x_subject_token


    - name: Create Group and Assign Sim
      uri:
        url: "{{ icgw_host }}{{ sdpf_tenantid }}/groups"
        headers:
          X-Auth-Token: "{{ token.x_subject_token }}"
          Content-Type: "application/json"
        status_code: 201
        method: "POST"
        body_format: "json"
        body:
          {
            "name": "{{ group_name }}"
          }
      register: group
    - name: Print Response
      debug:
        var: group.json.id


    - name: Get Sim
      uri:
        url: "{{ icgw_host }}{{ sdpf_tenantid }}/sims?imsi={{ sim_imsi }}"
        headers:
          X-Auth-Token: "{{ token.x_subject_token }}"
          Content-Type: "application/json"
        status_code: 200
        method: "GET"
      register: sim
    - name: Print Response
      debug:
        var: sim.json.sims[0].msisdn


    - name: Assign Sim to Group
      uri:
        url: "{{ icgw_host }}{{ sdpf_tenantid }}/sims/{{ sim_imsi }}"
        headers:
          X-Auth-Token: "{{ token.x_subject_token }}"
          Content-Type: "application/json"
        status_code: 200
        method: "PUT"
        body_format: "json"
        body:
          {
            "groupId": "{{ group.json.id }}",
            "msisdn": "{{ sim.json.sims[0].msisdn }}"
          }

    - name: Create Authentication
      uri:
        url: "{{ icgw_host }}{{ sdpf_tenantid }}/authentications"
        headers:
          X-Auth-Token: "{{ token.x_subject_token }}"
          Content-Type: "application/json"
        status_code: 201
        method: "POST"
        body_format: "json"
        body:
          {
            "type": "azure-iot-credentials",
            "name": "{{ az_auth_name }}",
            "description": "{{ az_auth_description }}",
            "sharedAccessKey": "{{ az_auth_key }}",
            "deviceId": "{{ az_device_id }}"
          }
      register: auth
    - name: Print Response
      debug:
        var: auth.json.id

    - name: Set Protocol Conversion
      uri:
        url: "{{ icgw_host }}{{ sdpf_tenantid}}/groups/{{ group.json.id }}/pconv"
        headers:
          X-Auth-Token: "{{ token.x_subject_token }}"
          Content-Type: "applicaion/json"
        status_code: 201
        method: "POST"
        body_format: "json"
        body:
          {
            "enabled": true,
            "name": "{{ az_pconv_name }}",
            "type": "mqtt",
            "destination":
              {
                "serviceType": "azure-iot",
                "host": "{{ az_iot_hub_host }}",
                "authenticationId": "{{ auth.json.id }}"
              }
          }
      register: pconv

Job「Create Azure IoT Hub & Setting ICGW for Azure IoT Hub」

  • Display name: Create Azure IoT Hub & Setting ICGW for Azure IoT Hub

  • Agent selection:
    • Agent pool: Azure Pipelines
    • Agent Specification: ubuntu-latest
    • Demands: (設定なし)
  • Execution plan:
    • Parallelism: None
    • Timeout: 0
    • Job cancel timeout: 1
  • Additional options:
    • Skip download of artifacts: Off
    • Allow scripts to access the OAuth token: Off
    • Run this job: Only when all previous jobs have succeeded
    Job

Task「[Azure IoT Hub]Install Latest Terraform」

  • 利用Task「Terraform Installer」

    • Task version: 0.*

    • Display name: [Azure IoT Hub]Install Latest Terraform

    • Version: latest

    • Download URL: (設定なし)

    • Control Options:
      • Enabled: On
      • Continue on error: Off
      • Number of retries if task failed: 0
      • Timeout: 0
      • Run this task: Only when all previous tasks have succeeded
    • Output Variables:
      • Reference name: (設定なし)
    Task 1

Task「[Azure IoT Hub]Run Terraform Init」

  • 利用Task「Terraform CLI」

    • Task version: 0.*

    • Display name: [Azure IoT Hub]Run Terraform Init

    • Command: init

    • Configuration Directory: $(workingDirectory)

    • Command Options: (設定なし)

    • Backend Type: azurerm

    • Allow Telemetry Collection: Off

    • AzureRM Backend Configuration:
      • Backend Azure Service Connection: $(serviceConnection)
      • Azure Subscription Id: $(subscriptionId)
      • Create Backend(if not exists): On
      • Resource Group Name: $(backendResourceGroupName)
      • Resource Group Location: $(backendResourceGroupLocation)
      • Storage Account Name: $(backendStorageAccountName)
      • Storage Account SKU: $(backendStorageAccountSku)
      • Container Name: tfstate
      • Key: terraform.tfstate
    • Variables:
      • Secured Variables File (Secrets): (設定なし)
    • Control Options:
      • Enabled: On
      • Continue on error: Off
      • Number of retries if task failed: 0
      • Timeout: 0
      • Run this task: Only when all previous tasks have succeeded
    • Output Variables:
      • Reference name: (設定なし)
    Task 2-1

Task「[Azure IoT Hub]Run Terraform Plan」

  • 利用Task「Terraform CLI」

    • Task version: 0.*

    • Display name: [Azure IoT Hub]Run Terraform Plan

    • Command: plan

    • Configuration Directory: $(workingDirectory)

    • Run Azure CLI Login: Off

    • Command Options:

      -var be_rg=$(backendResourceGroupName) -var be_storage=$(backendStorageAccountName) -var be_container='tfstate' -var be_key='terraform.tfstate' -var rg_name=$(resourceGroupName) -var rg_location=$(resourceGroupLocation) -var iothub_name=$(iotHubName) -var iothub_sku=$(iotHubSku)
      
    • Allow Telemetry Collection: Off

    • Publish Plan Results Name: (設定なし)

    • Providers:
      • AzureRM Provider Service Connection: $(serviceConnection)
      • Azure Subscription Id: $(subscriptionId)
      • AWS Provider Service Connection: (設定なし)
      • AWS Provider default region: (設定なし)
      • Google Credentials JSON File: (設定なし)
      • Project: (設定なし)
      • Region: (設定なし)
    • Variables:
      • Secured Variables File (Secrets): (設定なし)
    • Control Options:
      • Enabled: On
      • Continue on error: Off
      • Number of retries if task failed: 0
      • Timeout: 0
      • Run this task: Only when all previous tasks have succeeded
    • Output Variables:
      • Reference name: (設定なし)
    Task 3-1

Task「[Azure IoT Hub]Run Terraform Apply」

  • 利用Task「Terraform CLI」

    • Task version: 0.*

    • Display name: [Azure IoT Hub] Run Terraform Apply

    • Command: apply

    • Configuration Directory: $(workingDirectory)

    • Run Azure CLI Login: Off

    • Command Options:

      -var be_rg=$(backendResourceGroupName) -var be_storage=$(backendStorageAccountName) -var be_container='tfstate' -var be_key='terraform.tfstate' -var rg_name=$(resourceGroupName) -var rg_location=$(resourceGroupLocation) -var iothub_name=$(iotHubName) -var iothub_sku=$(iotHubSku)
      
    • Allow Telemetry Collection: Off

    • Providers:
      • AzureRM Provider Service Connection: $(serviceConnection)
      • Azure Subscription Id: $(subscriptionId)
      • AWS Provider Service Connection: (設定なし)
      • AWS Provider default region: (設定なし)
      • Google Credentials JSON File: (設定なし)
      • Project: (設定なし)
      • Region: (設定なし)
    • Variables:
      • Secured Variables File (Secrets): (設定なし)
    • Control Options:
      • Enabled: On
      • Continue on error: Off
      • Number of retries if task failed: 0
      • Timeout: 0
      • Run this task: Only when all previous tasks have succeeded
    • Output Variables:
      • Reference name: (設定なし)
    Task 4-1

Task「[Azure IoT Hub]Register IoT Hub Device」

  • 利用Task「Azure CLI」

    • Task version: 2.*

    • Display name: [Azure IoT Hub]Register IoT Hub Device

    • Azure Resource Manager connection: $(serviceConnection)

    • Script Type: Shell

    • Script Location: Inline script

    • Inline Script:

      az config set extension.use_dynamic_install=yes_without_prompt
      az account show
      az iot hub device-identity create --device-id $(iotDeviceId) --hub-name $(iotHubName)
      echo $(az iot hub device-identity show --device-id $(iotDeviceId) --hub-name $(iotHubName) --query "[authentication.symmetricKey.primaryKey]" -o tsv)
      echo "##vso[task.setvariable variable=key]$(az iot hub device-identity show --device-id $(iotDeviceId) --hub-name $(iotHubName) --query "[authentication.symmetricKey.primaryKey]" -o tsv)"
      
    • Script Arguments: (設定なし)

    • Advanced:
      • Access service principal details in script: Off
      • Use global Azure CLI configuration: Off
      • Working Directory: (設定なし)
      • Fail on Standard Error: Off
    • Control Options:
      • Enabled: On
      • Continue on error: Off
      • Number of retries if task failed: 0
      • Timeout: 0
      • Run this task: Only when all previous tasks have succeeded
    • Environment Variables: (設定なし)

    • Output Variables:
      • Reference name: iothub
    Task 5-1

Task「[ICGW]Download Secure File」

  • 利用Task「Download secure file」

    • Task version: 1.*

    • Display name: [ICGW]Download Secure File

    • Secure File: <ICGWおよびAzure IoT Hubの認証情報などが記入されたファイル>(例: vars_icgw_iothub.yml)>

    • Retry Count: 8

    • Socket Timeout: (設定なし)

    • Control Options:
      • Enabled: On
      • Continue on error: Off
      • Number of retries if task failed: 0
      • Timeout: 0
      • Run this task: Only when all previous tasks have succeeded
    • Output Variables:
      • Reference name: vars
    Task 6-1

Task「[ICGW]Run Ansible Playbook」

  • 利用Task「Command line」
    • Task version: 2.*

    • Display name: [ICGW]Run Ansible Playbook

    • Script:

      ansible-playbook '$(workingDirectory)/$(pb_filename)' -e "az_auth_key=$(key)" -e "vars_file_path=$(vars.secureFilePath)"
      
    • Advanced:
      • Working Directory: (設定なし)
      • Fail on Standard Error: Off
    • Control Options:
      • Enabled: On
      • Continue on error: Off
      • Number of retries if task failed: 0
      • Timeout: 0
      • Run this task: Only when all previous tasks have succeeded
    • Environment Variables: (設定なし)

    • Output Variables:
      • Reference name: (設定なし)
    Task 7-1