IoT Central を Azure Pipelines に統合して、継続的インテグレーションと継続的デリバリーを実現する

継続的インテグレーションと継続的デリバリー (CI/CD) とは、自動化パイプラインを使用して短時間のサイクルを頻繁に実行することで、ソフトウェアを開発および配布するプロセスのことです。 この記事では、IoT Central アプリケーション構成のビルド、テスト、デプロイを自動化する方法について説明します。 この自動化により、開発チームは信頼性の高いリリースをより頻繁に提供できます。

継続的インテグレーションは、ソース コード リポジトリ内のブランチにコードをコミットすることから始まります。 競合が発生しないようにするために、各コミットは他の開発者からのコミットとマージされます。 変更は、ビルドを作成し、そのビルドに対して自動テストを実行することでさらに検証されます。 このプロセスにより、ターゲット環境にデプロイする成果物、つまり配置バンドルが最終的に作成されます。 この場合、ターゲットは Azure IoT Central アプリケーションです。

IoT Central が大規模な IoT ソリューションの一部となるのと同様に、IoT Central は CI/CD パイプラインの一部となります。 CI/CD パイプラインでは、開発から運用までの各環境に IoT ソリューション全体とすべての構成をデプロイする必要があります。

一般的な CI/CD パイプラインの段階を示す図。

IoT Central は、"サービスとしてのプラットフォーム" コンポーネントとは異なるデプロイ要件がある "サービスとしてのアプリケーション プラットフォーム" です。 IoT Central では、構成とデバイス テンプレートをデプロイします。 これらの構成とデバイス テンプレートは、API を使用して管理され、リリース パイプラインに統合されます。

IoT Central アプリの作成を自動化することは可能ですが、CI/CD パイプラインを開発する前では、各環境でアプリを作成する必要があります。

Azure IoT Central REST API を使用すると、IoT Central アプリの構成をリリース パイプラインに統合できます。

このガイドでは、GitHub で管理されている構成ファイルに基づいて IoT Central アプリケーションを更新する新しいパイプラインの作成について説明します。 このガイドには、Azure Pipelines との統合に関する具体的な手順が記載されていますが、このガイドは、Tekton、Jenkins、GitLab、GitHub Actions などのツールを使用して構築されたリリース パイプラインに IoT Central を組み込むために応用できます。

このガイドでは、IoT Central アプリケーションの 1 つのインスタンスに IoT Central 構成を適用するだけのパイプラインを作成します。 これらの手順は、ソリューション全体をデプロイし、それを "開発" から "QA"、"QA" から "運用前"、"運用前" から "運用" に昇格させる (途中で必要なすべてのテストを実行する) 大規模なパイプラインに統合する必要があります。

現在、スクリプトは、IoT Central インスタンス間で、ダッシュボード、ビュー、デバイス テンプレートのカスタム設定、価格プラン、UX カスタマイズ、アプリケーション イメージ、ルール、スケジュール済みジョブ、保存済みジョブ、登録グループの設定を転送しません。

現在、スクリプトは、ターゲット IoT Central アプリケーションから、構成ファイルに存在しない設定を削除しません。

前提条件

このガイドの手順を完了するには、次の前提条件を満たす必要があります。

  • Azure Cloud Shell で Bash 環境を使用します。 詳細については、「Azure Cloud Shell の Bash のクイックスタート」を参照してください。

  • CLI リファレンス コマンドをローカルで実行する場合、Azure CLI をインストールします。 Windows または macOS で実行している場合は、Docker コンテナーで Azure CLI を実行することを検討してください。 詳細については、「Docker コンテナーで Azure CLI を実行する方法」を参照してください。

    • ローカル インストールを使用する場合は、az login コマンドを使用して Azure CLI にサインインします。 認証プロセスを完了するには、ターミナルに表示される手順に従います。 その他のサインイン オプションについては、Azure CLI でのサインインに関するページを参照してください。

    • 初回使用時にインストールを求められたら、Azure CLI 拡張機能をインストールします。 拡張機能の詳細については、Azure CLI で拡張機能を使用する方法に関するページを参照してください。

    • az version を実行し、インストールされているバージョンおよび依存ライブラリを検索します。 最新バージョンにアップグレードするには、az upgrade を実行します。

サンプル コードのダウンロード

作業を開始するには、IoT Central CI/CD GitHub リポジトリをフォークし、そのフォークをローカル コンピューターに複製します。

  1. GitHub リポジトリをフォークするには、IoT Central CI/CD GitHub リポジトリを開き、[フォーク] を選択します。

  2. コンソールまたは bash ウィンドウを開き、次のコマンドを実行して、リポジトリのフォークをローカル コンピューターに複製します。

    git clone https://github.com/{your GitHub username}/iot-central-CICD-sample
    

サービス プリンシパルの作成

Azure Pipelines は Key Vault と直接統合できますが、パイプラインには、データ エクスポート先のシークレットのフェッチなど、一部の動的 Key Vault 操作のためにサービス プリンシパルが必要です。

サブスクリプションに範囲を絞ったサービス プリンシパルを作成するには:

  1. 次のコマンドを実行して、新しいサービス プリンシパルを作成します。

    az ad sp create-for-rbac -n DevOpsAccess --scopes /subscriptions/{your Azure subscription Id} --role Contributor
    
  2. passwordappIdtenant の値は、後で必要になるためメモします。

  3. サービス プリンシパルのパスワードを SP-Password という名前のシークレットとして運用 Key Vault に追加します。

    az keyvault secret set --name SP-Password --vault-name {your production key vault name} --value {your service principal password}
    
  4. Key Vault からシークレットを読み取るためのアクセス許可をサービス プリンシパルに付与します。

    az keyvault set-policy --name {your production key vault name} --secret-permissions get list --spn {the appId of the service principal}
    

IoT Central API トークンを生成する

このガイドでは、パイプラインで API トークンを使用して IoT Central アプリケーションを操作します。 サービス プリンシパルも使用できます。

注意

IoT Central API トークンの有効期限は 1 年後です。

開発用と運用用の両方の IoT Central アプリについて、次の手順を実行します。

  1. IoT Central アプリで、[アクセス許可] を選択し、次に [API トークン] を選択します。

  2. [新規] を選択します。

  3. トークンに名前を付け、アプリで最上位レベルの組織を指定し、ロールを [アプリの管理者] に設定します。

  4. 開発 IoT Central アプリケーションからの API トークンをメモします。 これは、後ほど IoTC-Config.ps1 スクリプトを実行するときに使用します。

  5. 運用 IoT Central アプリケーションから生成されたトークンを API-Token という名前のシークレットとして運用 Key Vault に保存します。

    az keyvault secret set --name API-Token --vault-name {your production key vault name} --value '{your production app API token}'
    

構成ファイルを生成する

次の手順では、既存の IoT Central アプリケーションに基づいて開発環境用の JSON 構成ファイルを生成します。 また、アプリケーションから既存のすべてのデバイス テンプレートをダウンロードします。

  1. IoT Central CI/CD リポジトリのローカル コピーで次の PowerShell 7 スクリプトを実行します。

    cd .\iot-central-CICD-sample\PowerShell\
    .\IoTC-Config.ps1
    
  2. 手順に従って Azure アカウントにサインインします。

  3. サインインすると、スクリプトによって [IoTC Config options] (IoTC 構成のオプション) メニューが表示されます。 このスクリプトでは、既存の IoT Central アプリケーションから構成ファイルを生成し、別の IoT Central アプリケーションに構成を適用できます。

  4. オプション 1 を選択して構成ファイルを生成します。

  5. 必要なパラメーターを入力し、Enter キーを押します。

    • 開発 IoT Central アプリケーションで生成した API トークン。
    • 開発 IoT Central アプリケーションのサブドメイン。
    • 構成ファイルとデバイス テンプレートを格納するフォルダーとして「..\Config\Dev」と入力します。
    • 開発 Key Vault の名前。
  6. スクリプトによって、リポジトリのローカル コピーの Config\Dev フォルダー内に、IoTC Configuration という名前のフォルダーが作成されます。 このフォルダーには、構成ファイルと、アプリケーション内のすべてのデバイス テンプレート用の Device Models という名前のフォルダーが含まれます。

構成ファイルを変更します

開発 IoT Central アプリケーション インスタンスの設定を表す構成ファイルが作成されたので、運用 IoT Central アプリケーション インスタンスにこの構成を適用する前に、必要な変更を加えます。

  1. 前に作成した Dev フォルダーのコピーを作成し、そのコピーに Production という名前を付けます。

  2. テキスト エディターを使用して、Production フォルダー内の IoTC-Config.json を開きます。

  3. このファイルには複数のセクションがあります。 ただし、アプリケーションで特定の設定が使用されていない場合、そのセクションはファイルから除外されます。

    {
      "APITokens": {
        "value": [
          {
            "id": "dev-admin",
            "roles": [
              {
                "role": "ca310b8d-2f4a-44e0-a36e-957c202cd8d4"
              }
            ],
            "expiry": "2023-05-31T10:47:08.53Z"
          }
        ]
      },
      "data exports": {
        "value": [
          {
            "id": "5ad278d6-e22b-4749-803d-db1a8a2b8529",
            "displayName": "All telemetry to blob storage",
            "enabled": false,
            "source": "telemetry",
            "destinations": [
              {
                "id": "393adfc9-0ed8-45f4-aa29-25b5c96ecf63"
              }
            ],
            "status": "notStarted"
          }
        ]
      },
      "device groups": {
        "value": [
          {
            "id": "66f41d29-832d-4a12-9e9d-18932bee3141",
            "displayName": "MXCHIP Getting Started Guide - All devices"
          },
          {
            "id": "494dc749-0963-4ec1-89ff-e1de2228e750",
            "displayName": "RS40 Occupancy Sensor - All devices"
          },
          {
            "id": "dd87877d-9465-410b-947e-64167a7a1c39",
            "displayName": "Cascade 500 - All devices"
          },
          {
            "id": "91ceac5b-f98d-4df0-9ed6-5465854e7d9e",
            "displayName": "Simulated devices"
          }
        ]
      },
      "organizations": {
        "value": []
      },
      "roles": {
        "value": [
          {
            "id": "344138e9-8de4-4497-8c54-5237e96d6aaf",
            "displayName": "Builder"
          },
          {
            "id": "ca310b8d-2f4a-44e0-a36e-957c202cd8d4",
            "displayName": "Administrator"
          },
          {
            "id": "ae2c9854-393b-4f97-8c42-479d70ce626e",
            "displayName": "Operator"
          }
        ]
      },
      "destinations": {
        "value": [
          {
            "id": "393adfc9-0ed8-45f4-aa29-25b5c96ecf63",
            "displayName": "Blob destination",
            "type": "blobstorage@v1",
            "authorization": {
              "type": "connectionString",
              "connectionString": "DefaultEndpointsProtocol=https;AccountName=yourexportaccount;AccountKey=*****;EndpointSuffix=core.windows.net",
              "containerName": "dataexport"
            },
            "status": "waiting"
          }
        ]
      },
      "file uploads": {
        "connectionString": "FileUpload",
        "container": "fileupload",
        "sasTtl": "PT1H"
      },
      "jobs": {
        "value": []
      }
    }
    
  4. アプリケーションでファイル アップロードが使用されている場合、スクリプトによって、connectionString プロパティで示されている値を使用して、開発 Key Vault 内にシークレットが作成されます。 運用ストレージ アカウントの接続文字列を含む同じ名前のシークレットを、運用 Key Vault 内に作成します。 次に例を示します。

    az keyvault secret set --name FileUpload --vault-name {your production key vault name} --value '{your production storage account connection string}'
    
  5. アプリケーションでデータ エクスポートが使用されている場合は、宛先のシークレットを運用 Key Vault に追加します。 構成ファイルには宛先の実際のシークレットは含まれず、シークレットは Key Vault に格納されます。

  6. Key Vault 内のシークレットの名前を持つシークレットを構成ファイル内で更新します。

    変換先の型 変更するプロパティ
    Service Bus キュー connectionString
    Service Bus トピック connectionString
    Azure Data Explorer clientSecret
    Azure Blob Storage connectionString
    Event Hubs connectionString
    Webhook No Auth 該当なし

    次に例を示します。

    "destinations": {
      "value": [
        {
          "id": "393adfc9-0ed8-45f4-aa29-25b5c96ecf63",
          "displayName": "Blob destination",
          "type": "blobstorage@v1",
          "authorization": {
            "type": "connectionString",
            "connectionString": "Storage-CS",
            "containerName": "dataexport"
          },
          "status": "waiting"
        }
      ]
    }
    
  7. Configuration フォルダーを GitHub リポジトリにアップロードするために、IoTC-CICD-howto フォルダーから次のコマンドを実行します。

     git add Config
     git commit -m "Adding config directories and files"
     git push
    

パイプラインを作成する

  1. Web ブラウザーで https://dev.azure.com/{your DevOps organization} に移動して、Azure DevOps 組織を開きます
  2. [新しいプロジェクト] を選択して新しいプロジェクトを作成します。
  3. プロジェクトに名前を付け、必要に応じて説明を入力し、[作成] を選択します。
  4. [プロジェクトへようこそ] ページで、[パイプライン] を選択し、次に [パイプラインを作成] を選択します。
  5. コードの場所として [GitHub] を選択します。
  6. [Authorize AzurePipelines] (Azure Pipelines を承認する) を選択して、Azure Pipelines が GitHub アカウントにアクセスすることを承認します。
  7. [リポジトリの選択] ページで、IoT Central CI/CD GitHub リポジトリのフォークを選択します。
  8. GitHub にログインし、Azure Pipelines がリポジトリにアクセスするためのアクセス許可を指定するように求められたら、[承認してインストール] を選択します。
  9. [パイプラインの構成] ページで、[スタート パイプライン] を選択して作業を開始します。 azure-pipelines.yml が編集のために表示されます。

変数グループを作成する

Key Vault シークレットをパイプラインに統合する簡単な方法は、変数グループを使用することです。 変数グループを使用して、デプロイ スクリプトで適切なシークレットを使用できるようにします。 変数グループを作成するには:

  1. 左側のメニューの [パイプライン] セクションで [ライブラリ] を選択します。

  2. [+ Variable group] を選択します。

  3. 変数グループの名前として「keyvault」と入力します。

  4. トグルを有効にして、Azure Key Vault 内のシークレットをリンクします。

  5. Azure サブスクリプションを選択して承認します。 次に、運用 Key Vault 名を選択します。

  6. [追加] を選択して、グループへの変数の追加を開始します。

  7. 次のシークレットを追加します。

    • 運用アプリの IoT Central API キー。 このシークレットには、作成時に API-Token という名前を付けました。
    • 前に作成したサービス プリンシパルのパスワード。 このシークレットには、作成時に SP-Password という名前を付けました。
  8. [OK] を選択します。

  9. [保存] を選択して変数グループを保存します。

パイプラインを構成する

次に、IoT Central アプリケーションに構成の変更をプッシュするようにパイプラインを構成します。

  1. 左側のメニューの [パイプライン] セクションで [パイプライン] を選択します。

  2. パイプライン YAML の内容を次の YAML に置き換えます。 この構成は、運用 Key Vault に次のものが含まれていることを前提としています。

    • API-Token という名前のシークレット内の運用 IoT Central アプリの API トークン。
    • SP-Password という名前のシークレット内のサービス プリンシパル パスワード。

    -AppName-KeyVault の値を、運用インスタンスの適切な値に置き換えます。

    サービス プリンシパルを作成したときに -AppId-TenantId をメモしました。

    trigger:
    - master
    variables:
    - group: keyvault
    - name: buildConfiguration
      value: 'Release'
    steps:
    - task: PowerShell@2
      displayName: 'IoT Central'
      inputs:
        filePath: 'PowerShell/IoTC-Task.ps1'
        arguments: '-ApiToken "$(API-Token)" -ConfigPath "Config/Production/IoTC Configuration" -AppName "{your production IoT Central app name}" -ServicePrincipalPassword (ConvertTo-SecureString "$(SP-Password)" -AsPlainText -Force) -AppId "{your service principal app id}" -KeyVault "{your production key vault name}" -TenantId "{your tenant id}"'
        pwsh: true
        failOnStderr:  true
    
  3. [保存および実行] を選択します。

  4. YAML ファイルは GitHub リポジトリに保存されるため、コミット メッセージを指定し、[保存および実行] をもう一度選択する必要があります。

パイプラインがキューに入れられます。 実行されるまでに数分かかる場合があります。

パイプラインを初めて実行するとき、パイプラインがサブスクリプションにアクセスするためのアクセス許可、および Key Vault にアクセスするためのアクセス許可を指定するように求められます。 [許可] を選択し、リソースごとにもう一度 [許可] を選択します。

パイプライン ジョブが正常に完了したら、運用 IoT Central アプリケーションにサインインし、構成が想定どおりに適用されたことを確認します。

開発から運用に変更をプロモートする

これで機能するパイプラインを用意できたので、構成の変更を使用して IoT Central インスタンスを直接管理できます。 Device Models フォルダーに新しいデバイス テンプレートをアップロードし、構成ファイルを直接変更できます。 この方法により、IoT Central アプリケーションの構成を他のコードと同じように扱うことができます。

次のステップ

IoT Central の構成を CI/CD パイプラインに統合する方法について学習したので、次のステップとして、IoT Central アプリケーションを管理および監視する方法について学習することをお勧めします。