演習 - ワークフローに複数の環境を追加する

完了

テスト環境と運用環境の両方にワークフローをデプロイするために、ワークフローを更新する準備ができました。 このユニットでは、環境全体でジョブを再利用できるよう、呼び出し対象のワークフローを使用するようにワークフローを更新します。

このプロセスでは、次のことを行います。

  • リント ジョブに再利用可能なワークフローを追加します。
  • 任意の環境にデプロイするために必要なジョブを定義する、再利用可能なワークフローを追加します。
  • 呼び出し対象のワークフローを使用するようにワークフローを更新します。
  • ワークフローを実行し、結果を表示します。

リント ジョブに再利用可能なワークフローを追加する

リント ジョブは、ワークフローがデプロイされる環境の数に関係なく、ワークフローの実行中に 1 回だけ発生します。 そのため、リント ジョブに呼び出し対象のワークフローを使用する必要はありません。 しかし、メインのワークフロー定義ファイルをシンプルで読みやすい状態に保つために、別のワークフロー ファイルでリント ジョブを定義することにしました。

  1. Visual Studio Code の .github/workflows フォルダー内に、lint.yml という名前の新しいファイルを作成します。

    Visual Studio Code エクスプローラーのスクリーンショット。.github フォルダーと workflows フォルダー、および lint.yml ファイルが含まれています。

  2. 次のワークフロー定義をファイルに貼り付けます。

    name: lint
    
    on:
      workflow_call:
    
    jobs:
      lint:
        name: Lint code
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v3
    
        - name: Lint code
          run: |
            az bicep build --file deploy/main.bicep
    

    リント ジョブは、既にワークフロー内にあるリント ジョブと同じですが、別のワークフロー ファイルに含まれています。

  3. 変更を保存し、ファイルを閉じます。

デプロイに再利用可能なワークフローを追加する

各環境のデプロイに必要なすべてのジョブを定義する、再利用可能なワークフローを作成します。 入力とシークレットを使用して、環境ごとに違う可能性のある設定を指定します。

  1. .github/workflows フォルダーで、deploy.yml という名前の新しいファイルを作成します。

    Visual Studio Code エクスプローラーのスクリーンショット。.github フォルダーと workflows フォルダー、および deploy.yml ファイルが含まれています。

    このファイルは、それぞれの環境に対して実行されたすべてのデプロイ アクティビティを示します。

  2. 次のワークフロー名、トリガー、入力、およびシークレットをファイルに貼り付けます。

    name: deploy
    
    on:
      workflow_call:
        inputs:
          environmentType:
            required: true
            type: string
          resourceGroupName:
            required: true
            type: string
        secrets:
          AZURE_CLIENT_ID:
            required: true
          AZURE_TENANT_ID:
            required: true
          AZURE_SUBSCRIPTION_ID:
            required: true
    

    Note

    Visual Studio Code で YAML ファイルの編集を始めると、問題があることを示す赤い波線が表示されることがあります。 これは、YAML ファイル用の Visual Studio Code 拡張機能がファイルのスキーマを誤って判断することがあるからです。

    拡張機能が指摘する問題は無視してかまいません。 または、次のコードをファイルの上部に追加して拡張機能が推測しないようにすることもできます。

    # yaml-language-server: $schema=./deploy.yml
    
  3. シークレットの下に、検証ジョブの定義を貼り付けます。

    jobs:
      validate:
         runs-on: ubuntu-latest
         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 }}
         - if: inputs.environmentType != 'Production'
           uses: azure/arm-deploy@v1
           name: Run preflight validation
           with:
             deploymentName: ${{ github.run_number }}
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             deploymentMode: Validate
         - if: inputs.environmentType == 'Production'
           uses: azure/arm-deploy@v1
           name: Run what-if
           with:
             failOnStdErr: false
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             additionalArguments: --what-if
    

    条件がこのジョブに適用されることに注目してください。 プレフライト検証は、非運用環境に対してのみ実行されます。 What-If 操作は、運用環境に対してのみ実行されます。 ラーニング パスの前のモジュールでは、これらの操作に個別のジョブを使用しましたが、ここではワークフローを簡略化するためにそれらを組み合わせています。

    ヒント

    YAML ファイルは、インデントによって区別されます。 このコードを入力する場合でも貼り付ける場合でも、インデントが正しいことを確認してください。 この演習の後半では、ファイルが一致することを確認できるように、完全な YAML ワークフロー定義を示します。

  4. 検証ジョブの下に、デプロイ ジョブの定義を貼り付けます。

    deploy:
      needs: validate
      environment: ${{ inputs.environmentType }}
      runs-on: ubuntu-latest
      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 Bicep file
        with:
          failOnStdErr: false
          deploymentName: ${{ github.run_number }}
          resourceGroupName: ${{ inputs.resourceGroupName }}
          template: ./deploy/main.bicep
          parameters: >
            environmentType=${{ inputs.environmentType }}
    
  5. デプロイ ジョブの下に、スモーク テスト ジョブの定義を貼り付けます。

    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
    
  6. deploy.yml ファイルが、次の例のようになっていることを確認します。

    name: deploy
    
    on:
      workflow_call:
        inputs:
          environmentType:
            required: true
            type: string
          resourceGroupName:
            required: true
            type: string
        secrets:
          AZURE_CLIENT_ID:
            required: true
          AZURE_TENANT_ID:
            required: true
          AZURE_SUBSCRIPTION_ID:
            required: true
    
    jobs:
      validate:
         runs-on: ubuntu-latest
         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 }}
         - if: inputs.environmentType != 'Production'
           uses: azure/arm-deploy@v1
           name: Run preflight validation
           with:
             deploymentName: ${{ github.run_number }}
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             deploymentMode: Validate
         - if: inputs.environmentType == 'Production'
           uses: azure/arm-deploy@v1
           name: Run what-if
           with:
             failOnStdErr: false
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             additionalArguments: --what-if
    
      deploy:
        needs: validate
        environment: ${{ inputs.environmentType }}
        runs-on: ubuntu-latest
        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 Bicep file
          with:
            failOnStdErr: false
            deploymentName: ${{ github.run_number }}
            resourceGroupName: ${{ inputs.resourceGroupName }}
            template: ./deploy/main.bicep
            parameters: >
              environmentType=${{ inputs.environmentType }}
    
      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
    
  7. ファイルに加えた変更を保存します。

ワークフロー定義を更新して、テンプレートを使用するようにします。

  1. .github/workflows フォルダーにある workflow.yml ファイルを開きます。

  2. 2 つの環境変数とともに、env: セクションの内容を削除します。 これらを、環境特有の変数に置き換えます。

  3. 先ほど作成した lint.yml ファイルを使用するために、lint: ジョブ定義の内容を削除し、次のコードに置き換えます。

    # Lint the Bicep file.
    lint:
      uses: ./.github/workflows/lint.yml
    
  4. 更新したリント ジョブの下にある、ファイル内のすべての内容を削除します。

  5. ファイルの末尾に、テスト環境にデプロイする次のコードを追加します。

    # Deploy to the test environment.
    deploy-test:
      uses: ./.github/workflows/deploy.yml
      needs: lint
      with:
        environmentType: Test
        resourceGroupName: ToyWebsiteTest
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
  6. 先ほど追加したコードの下に、運用環境にデプロイするために次のコードを追加します。

    # Deploy to the production environment.
    deploy-production:
      uses: ./.github/workflows/deploy.yml
      needs: deploy-test
      with:
        environmentType: Production
        resourceGroupName: ToyWebsiteProduction
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    

    更新されたワークフローで、リント ジョブが 1 回実行されます。 その後、呼び出し対象のワークフロー deploy.yml が 2 回 (環境ごとに 1 回) 使用されます。 これにより、ワークフローの定義が明確で理解しやすいものになります。 YAML ファイル内のコメントでは、各ジョブのターゲット環境が示されています。

  7. deploy.yml ファイルが次の例のようになっていることを確認します。

    name: deploy-toy-website-environments
    concurrency: toy-company
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
    
    permissions:
      id-token: write
      contents: read
    
    jobs:
    
      # Lint the Bicep file.
      lint:
        uses: ./.github/workflows/lint.yml
    
      # Deploy to the test environment.
      deploy-test:
        uses: ./.github/workflows/deploy.yml
        needs: lint
        with:
          environmentType: Test
          resourceGroupName: ToyWebsiteTest
        secrets:
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
      # Deploy to the production environment.
      deploy-production:
        uses: ./.github/workflows/deploy.yml
        needs: deploy-test
        with:
          environmentType: Production
          resourceGroupName: ToyWebsiteProduction
        secrets:
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
  8. 変更内容を保存します。

  9. Visual Studio Code ターミナルで次のコマンドを実行し、変更をコミットして Git リポジトリにプッシュします。

    git add .
    git commit -m "Add reusable workflows"
    git push
    
  10. これはリポジトリへの初めてのプッシュなので、サインインを求められる場合があります。

    Windows の場合、「1」と入力して Web ブラウザーの使用を認証し、Enter キーを押します。

    macOS の場合は、[承認] を選択します。

  11. ブラウザー ウィンドウが開きます。 場合によっては、再度 GitHub にサインインする必要があります。 [承認] を選択します。

ワークフロー実行を表示します。

  1. ブラウザーで、Actions に移動します。

    Initial commit というラベルが付いたワークフローの初めての実行が失敗として表示されます。 GitHub が、リポジトリの作成時にワークフローを自動的に実行しました。 その時点でシークレットの準備が整っていなかったため、失敗しました。 この失敗は無視してかまいません。

  2. deploy-toy-website-environments ワークフローを選択します。

  3. ワークフローの最新の実行を選択します。

    現在、ワークフローの実行では、YAML ファイルで定義したすべてのジョブが示されていることに注目してください。

    [注釈] パネルにいくつかの警告がリストされています。 これらの警告すべては、Bicep が情報メッセージをワークフロー ログに書き込む方法が原因です。 これらの警告は無視してかまいません。

  4. deploy-production / deploy ジョブの前にワークフローが一時停止する間待ちます。 ワークフローがここに達するまでに数分かかることがあります。

    ワークフローの実行が承認のために一時停止していることを示す GitHub のスクリーンショット。

  5. [Review deployments](デプロイのレビュー) ボタンを選択して、運用環境へのデプロイを承認します。

  6. [Production] 環境を選択し、[Approve and deploy](承認してデプロイ) ボタンを選択します。

    ワークフローの承認ページと [Approve and deploy]\(承認してデプロイ\) ボタンを示す GitHub インターフェイスのスクリーンショット。

    ワークフローの実行が完了するまで待ちます。 ワークフローは正常に完了しました。

  7. [コード] を選択します。

  8. [運用] デプロイを選びます。

    運用環境が強調表示されているコード ページ環境を示す GitHub のスクリーンショット。

  9. デプロイ画面に、運用環境のデプロイ履歴の概要が表示されます。

    運用環境を示す GitHub のスクリーンショット。一度のデプロイを示すデプロイ履歴が表示されています。

  10. コミット識別子を選択します。

    GitHub に、デプロイに含まれるコミットの一覧が表示されます。 これは、経時的な環境の変化を確認するのに役立ちます。

    コミットの一覧を含む、運用環境のデプロイの詳細を示す GitHub のスクリーンショット。

  11. ブラウザーで、Azure portal に移動します。

  12. ToyWebsiteProduction リソース グループに移動します。

  13. リソースの一覧で、Azure App Service アプリを開きます。

    App Services の玩具 Web サイト運用アプリと App Service プラン SKU の詳細を示す Azure portal のスクリーンショット。

    App Service プランの種類は S1 です。

  14. ToyWebsiteTest リソース グループの App Service アプリに移動します。

    App Service プランの種類は F1 です。 Bicep ファイルで定義した通り、2 つの環境は異なる設定を使用します。