デプロイ後にリソースをテストする

完了

Bicep のデプロイを検証してプレビューすることで、Bicep ファイルが正常にデプロイされるという確信が得られました。 しかし、デプロイがすべてではありません。 デプロイの終了後、デプロイが期待通りに実行されたことを確認することも役に立ちます。

このユニットでは、デプロイの終了後に実行できるテストについて学習します。 また、期待どおりになっていない場合に行うデプロイのロールバックについても学習します。

スモーク テストとネガティブ テストを実行する

Bicep ファイルでリソースを定義する場合、Azure でリソースを作成することだけが目的ではありません。 組織の要件を満たしながら、組織の価値を高めることです。 Bicep ファイルを検証してプレビューすると、リソース定義が有効であるという確信が得られます。 ただし、リソースが実際に希望どおりに機能するかどうかは必ずしもわかりません。

たとえば、Bicep デプロイ ワークフローを使用して新しい Azure SQL 論理サーバーをデプロイするとします。 サーバーの Bicep 定義は有効で、リンター ジョブおよびプレフライト検証ジョブを通過します。 what-if コマンドで、サーバーが作成されることが示されます。これは期待どおりです。 デプロイも正常に終了します。 しかし、それでもデプロイ プロセスの最後に、使用準備が整った稼働するデータベース サーバーが得られない場合があります。 次のような理由が考えられます。

  • ネットワーク トラフィックがサーバーに到達できるようにファイアウォール規則を構成していない。
  • サーバーで Microsoft Entra 認証を有効にすべきでない場合に有効にした、またはその逆。

基本的な Bicep ファイルをデプロイするだけの場合であっても、デプロイしたリソースが実際に機能し、要件を満たしていることをどのように検証するかは、検討に値します。 この原則を適用する方法の例を次に示します。

  • Web サイトをデプロイするときは、ワークフローから Web アプリケーションに接続を試みます。 ワークフローから Web サイトに正常に接続でき、有効な応答コードが返されることを確認します。
  • コンテンツ配信ネットワーク (CDN) をデプロイする場合は、CDN を介してリソースに接続を試みます。 ワークフローから CDN に正常に接続でき、有効な応答コードが返されることを確認します。

これらのテストは、"インフラストラクチャ スモーク テスト" と呼ばれることもあります。 スモーク テストは、デプロイの主要な問題を発見するために設計された単純な形式のテストです。

Note

一部の Azure リソースは、GitHub ホステッド ランナーから簡単にアクセスできません。 スモーク テスト ジョブを実行するために、プライベート ネットワークを介したリソースへのアクセスが必要な場合は、状況に応じてセルフホステッド ランナーの使用を検討してください。

また、"ネガティブ テスト" を実行することもお勧めします。 ネガティブ テストは、リソースが望ましくない動作をしないことを確認するのに役立ちます。 たとえば、仮想マシンをデプロイするときには、Azure Bastion を使用して仮想マシンに安全に接続するのが推奨される方法です。 ワークフローにネガティブ テストを追加して、リモート デスクトップ接続や SSH を使用して仮想マシンに直接接続できないことを確認することができます。

重要

これらのテストの目的は、Bicep によってリソースが正しくデプロイされたかどうかを確認することではありません。 Bicep を使用する場合、Bicep ファイルに指定したリソースがデプロイされると仮定することになります。 それよりも、定義したリソースが状況に応じて動作し、要件を満たすかどうかを検証することが本当の目的です。

GitHub ワークフローからテストを実行する

ワークフローでテストを実行する方法はたくさんあります。 このモジュールでは、Pester を使用します。これは、PowerShell を使用して書かれたテストを実行するオープンソースのツールです。 Pester は、GitHub ホステッド ランナーにプレインストールされています。 スクリプト ステップで使用するために特別な操作を行う必要はありません。

他のテスト フレームワークを使用することや、テスト ツールを使用せずにテストを実行することもできます。 たとえば、考慮すべきもう 1 つのテスト ツールとして PSRule for Azure があります。これには、Azure 用に事前に構築された規則とテストが含まれています。 また、テンプレートの検証や、デプロイされた Azure リソースに対するテストも実行できます。 PSRule のリンクについては「まとめ」を参照してください。

ワークフローからテストを実行する場合にテストが失敗すると、ワークフローの続行が停止されます。 次の演習では、インフラストラクチャ スモーク テストでワークフローを使用する方法について確認します。

テスト結果はワークフロー ログに書き込まれます。 また GitHub Marketplace には、経時的にテスト結果を表示および追跡できる Microsoft 以外のアクションも含まれています。

ジョブ間でデータを渡す

ワークフローを複数のジョブに分割し、それぞれに独自の責任がある場合、これらのジョブ間でデータを渡す必要がある場合があります。 たとえば、あるジョブで Azure リソースを作成し、別のジョブでそれを操作する必要がある場合です。 データを渡すためには、作成されたリソースの名前を第 2 ジョブが認識している必要があります。 たとえば、スモーク テスト ジョブでは、デプロイ ジョブでデプロイされたリソースにアクセスする必要があります。

Bicep ファイルによってリソースがデプロイされるので、そこからリソースのプロパティにアクセスし、デプロイの出力として発行することができます。 arm-deploy アクションを使用して Bicep デプロイを実行する場合、このアクションではステップ出力にこれらの Bicep デプロイ出力が格納されます。 次に、arm-deploy アクションを保持するジョブがそれらのステップ出力をジョブ出力してパブリッシュできます。 このジョブは、このステップの id プロパティ (deploy に設定しました) を参照します。

deploy:
  runs-on: ubuntu-latest
  environment: Website
  needs: preview
  outputs:
    appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }}
  steps:
  - uses: actions/checkout@v3
  - uses: azure/login@v1
    name: Sign in to Azure
    with:
      client-id: ${{ secrets.AZURE_CLIENT_ID }}
      tenant-id: ${{ secrets.AZURE_TENANT_ID }}
      subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
  - uses: azure/arm-deploy@v1
    id: deploy
    name: Deploy website
    with:
      deploymentName: ${{ github.run_number }}
      resourceGroupName: ${{ env.AZURE_RESOURCEGROUP_NAME }}
      template: ./deploy/main.bicep
      parameters: environmentType=${{ env.ENVIRONMENT_TYPE }}

後続の任意のジョブでは、出力を生成するジョブと依存関係がある限りそのジョブの出力にアクセスできます。

smoke-test:
  runs-on: ubuntu-latest
  needs: deploy
  steps:
  - uses: actions/checkout@v3
  - run: |
      $container = New-PesterContainer `
        -Path 'deploy/Website.Tests.ps1' `
        -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' }
      Invoke-Pester `
        -Container $container `
        -CI
    name: Run smoke tests
    shell: pwsh

また、特別な構文を使用して、ワークフロー スクリプトからの出力を渡すこともできます。 概要の詳細情報へリンクします。

その他のテストの種類

機能テスト統合テストは、多くの場合、デプロイされたリソースが期待した通り動作していることを確認するために使用されます。 たとえば、統合テストの場合、Web サイトに接続し、テスト トランザクションを送信し、トランザクションが正常に終了するのを確認するために待機する場合があります。 統合テストを使用すると、チームが構築したソリューションだけでなく、実行されているインフラストラクチャもテストすることができます。 今後のモジュールでは、これらの種類のテストをワークフローに追加する方法について説明します。

また、パフォーマンス テストやセキュリティ侵入テストなど、他の種類のテストをデプロイ ワークフローから実行することもできます。 これらのテストについてはこのモジュールで説明しませんが、自動デプロイ プロセスの価値を高めることができます。

ロールバックまたはロールフォワード

ワークフローによるリソースのデプロイは成功しても、テストが失敗したとします。 この場合、何をする必要がありますか。

このモジュールの前半で、GitHub Actions を使用すると、前のジョブが失敗したときに実行されるロールバック ジョブを作成できることを学習しました。 このアプローチを使用して、テスト ジョブで予期しない結果が報告されたときにロールバック ジョブを作成することができます。 また、手動で変更をロールバックすることができます。あるいは、失敗が一時的な問題によるもので、既に解決されている場合は、ワークフロー全体を再実行することができます。

Note

Azure Resource Manager にデプロイを送信するときに、最後に成功したデプロイが失敗した場合は Resource Manager によって自動的に再実行されるように要求することができます。 これを行うには、Azure CLI の az deployment group create コマンドを使用してデプロイを送信するときに、--rollback-on-error パラメーターを使用します。

たとえば、ロールバック ジョブをワークフローに追加できます。 ロールバック ジョブは、スモーク テスト ジョブが失敗すると実行されます。

rollback: 
  runs-on: ubuntu-latest
  needs: smoke-test
  if: ${{ always() && needs.smoke-test.result == 'failure' }}
  steps:
  - run: |
      echo "Performing rollback steps..."

このジョブは、スモーク テスト ジョブに依存します。 実行されるのは、スモーク テストが失敗した場合のみです。 既定では、前のジョブが失敗するたびに GitHub Actions によってワークフローが停止されます。 if 条件には、この動作をオーバーライドする always() チェックが含まれています。 式に always() がない場合、ロールバック ジョブは前のジョブが失敗するたびにスキップされます。

ロールバック ジョブで実行すべきステップを適切に実行するのは困難なことがよくあります。 一般的に、Bicep のデプロイは複雑であり、変更をロールバックするのは容易ではありません。 特に、デプロイに他のコンポーネントが含まれている場合は、ロールバックが困難になります。

たとえば、Azure SQL データベースを定義する Bicep ファイルがワークフローによってデプロイされた後、そのデータベースに何らかのデータが追加されたとします。 このデプロイをロールバックする場合、データを削除する必要はありますか。 データベースも削除する必要はありますか。 すべての失敗とすべてのロールバックが実行中の環境にどのように影響するかを予測するのは困難です。

そのため、多くの企業は "ロールフォワード" を好んでいます。つまり、失敗の理由をすぐに修正してから再度デプロイする処理です。 高品質の自動デプロイ プロセスを構築し、これらのラーニング パスで学んだすべてのベスト プラクティスに従うことで、高品質を維持しながら問題を迅速に修正し、Bicep ファイルを再デプロイできるようになります。

ヒント

DevOps の考え方の原則の 1 つは、間違いから学ぶことです。 デプロイをロールバックする必要がある場合は、エラーが発生した理由を慎重に検討し、今後同じ問題が発生しても検出できるように、デプロイを開始する前に自動テストを追加します。