演習 - Web アプリケーションをデプロイする
あなたの玩具会社では、Web サイト開発チームが最新バージョンの Web サイトを Git リポジトリにコミット済みです。 これで、Web サイトをビルドして Azure App Service にデプロイするようにワークフローを更新する準備が整いました。
このプロセスでは、次のことを行います。
- ビルド ジョブ用に新しい呼び出し先ワークフローを追加する。
- ビルド ジョブを含めるようにワークフローを更新する。
- 新しいスモーク テストを追加します。
- アプリケーションをデプロイするようにデプロイ ジョブを更新する。
- ワークフローを実行します。
ビルド ジョブに再利用可能なワークフローを追加する
ここで、Web サイト アプリケーションをビルドするために必要なステップを含む新しいジョブ定義を追加します。
Visual Studio Code を開きます。
.github/workflows フォルダーに、build.yml という名前の新しいファイルを作成します。
次の内容を build.yml ワークフロー ファイルに追加します。
name: build-website on: workflow_call: jobs: build-application: name: Build application runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install .NET Core uses: actions/setup-dotnet@v3 with: dotnet-version: 3.1 - name: Build publishable website run: | dotnet publish --configuration Release working-directory: ./src/ToyCompany/ToyCompany.Website - name: Zip publishable website run: | zip -r publish.zip . working-directory: ./src/ToyCompany/ToyCompany.Website/bin/Release/netcoreapp3.1/publish - name: Upload website as workflow artifact uses: actions/upload-artifact@v3 with: name: website path: ./src/ToyCompany/ToyCompany.Website/bin/Release/netcoreapp3.1/publish/publish.zip
このジョブによって、ソリューションをビルドする .NET SDK がインストールされます。 その後、ビルド ステップが実行されて、Web サイト アプリケーションのソース コードが、Azure で実行できるコンパイル済みファイルになります。 さらに、コンパイル済みの成果物が圧縮され、ワークフロー成果物としてアップロードされます。
ファイルに加えた変更を保存します。
ビルド ジョブをワークフローに追加する
workflow.yml ファイルを開きます。
jobs: 行と lint ジョブの間に、先ほど定義した再利用可能なワークフローを使用する build という名前の新しいジョブを追加します。
name: deploy-toy-website-end-to-end concurrency: toy-company on: push: branches: - main workflow_dispatch: permissions: id-token: write contents: read jobs: # Build the application and database. build: uses: ./.github/workflows/build.yml # Lint the Bicep file. lint: uses: ./.github/workflows/lint.yml
新しい build ジョブに依存するように deploy-test ジョブを更新します。
# Deploy to the test environment. deploy-test: uses: ./.github/workflows/deploy.yml needs: [build, lint] with: environmentType: Test resourceGroupName: ToyWebsiteTest reviewApiUrl: https://sandbox.contoso.com/reviews secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} reviewApiKey: ${{ secrets.REVIEW_API_KEY_TEST }}
同様に、built ジョブと lint ジョブにも依存するように deploy-production ジョブを更新します。
# Deploy to the production environment. deploy-production: uses: ./.github/workflows/deploy.yml needs: - lint - build - deploy-test with: environmentType: Production resourceGroupName: ToyWebsiteProduction reviewApiUrl: https://api.contoso.com/reviews secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} reviewApiKey: ${{ secrets.REVIEW_API_KEY_PRODUCTION }}
運用環境デプロイはテスト デプロイに依存するので、厳密には、依存関係を指定する必要はありません。 しかし、ジョブや環境を並べ替えたり削除したりした場合のワークフローの誤動作を防ぐためにも、明示的に記述することをお勧めします。
needs
の内容が 2 とおりの方法で指定されていることに注目してください。デプロイの依存関係が、テスト環境では 1 行で列挙されているのに対し、運用環境では複数行で入力されています。 2 つの方法は等価です。ファイルに加えた変更を保存します。
スモーク テスト ファイルを更新する
Web サイト開発者は Web サイトに正常性エンドポイントを追加済みです。 このエンドポイントは、Web サイトがオンラインであり、データベースにアクセスできることを確認します。 ここで、デプロイ ワークフローから正常性チェックを呼び出す新しいスモーク テストを追加します。
deploy フォルダーの Website.Tests.ps1 ファイルを開きます。
正常性チェックを呼び出す新しいテスト ケースを追加します。 このテスト ケースは、応答コードが 200 (成功を示す応答コード) でない場合に失敗します。
param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $HostName ) Describe 'Toy Website' { It 'Serves pages over HTTPS' { $request = [System.Net.WebRequest]::Create("https://$HostName/") $request.AllowAutoRedirect = $false $request.GetResponse().StatusCode | Should -Be 200 -Because "the website requires HTTPS" } It 'Does not serves pages over HTTP' { $request = [System.Net.WebRequest]::Create("http://$HostName/") $request.AllowAutoRedirect = $false $request.GetResponse().StatusCode | Should -BeGreaterOrEqual 300 -Because "HTTP is not secure" } It 'Returns a success code from the health check endpoint' { $response = Invoke-WebRequest -Uri "https://$HostName/health" -SkipHttpErrorCheck Write-Host $response.Content $response.StatusCode | Should -Be 200 -Because "the website and configuration should be healthy" } }
ファイルに加えた変更を保存します。
出力を Bicep ファイルに追加する
Web サイトを Azure App Service に発行するデプロイ ステップを、もう少し後で追加します。 発行ステップでは App Service アプリの名前を必要とします。 ここで、アプリ名を Bicep ファイルからの出力として公開します。
deploy フォルダーの main.bicep ファイルを開きます。
ファイルの内容の最後に、出力として App Service アプリの名前を追加します。
output appServiceAppName string = appServiceApp.name output appServiceAppHostName string = appServiceApp.properties.defaultHostName
ファイルに加えた変更を保存します。
出力を伝達するようにデプロイ ジョブを更新する
今度は、Bicep デプロイから得られた出力の値を受け取って残りのワークフローから利用できるよう、deploy ジョブを更新する必要があります。
.github/workflows フォルダーにある deploy.yml ファイルを開きます。
deploy ジョブの定義に、
appServiceAppName
用の新しい出力を追加します。deploy: needs: validate environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest outputs: appServiceAppName: ${{ steps.deploy.outputs.appServiceAppName }} appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }} steps:
Note
Visual Studio Code で YAML ファイルの編集を始めると、問題があることを示す赤い波線が表示されることがあります。 これは、YAML ファイル用の Visual Studio Code 拡張機能がファイルのスキーマを誤って判断することがあるからです。
拡張機能が指摘する問題は無視してかまいません。 または、次のコードをファイルの上部に追加して拡張機能が推測しないようにすることもできます。
# yaml-language-server: $schema=./deploy.yml
Web サイトをデプロイするためのジョブを追加する
deploy ジョブ定義と smoke-test ジョブ定義の間に、Web サイトを App Service にデプロイするための新しいジョブを定義します。
deploy-website: needs: deploy environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest steps: - uses: actions/download-artifact@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/webapps-deploy@v2 name: Deploy website with: app-name: ${{ needs.deploy.outputs.appServiceAppName }} package: website/publish.zip
Note
新しいジョブが
deploy
ジョブと同じレベルでインデントされるように、YAML ファイルのインデントに注意してください。 不明な場合は、次の手順の例から deploy.yml ファイルの内容全体をコピーしてください。このジョブは、
needs
キーワードを使用して deploy ジョブに依存していることに注目してください。 インフラストラクチャの準備が整うまで Web サイトがデプロイされないことが、この依存関係によって保証されます。 また、そうすることで、appServiceAppName
の出力に deploy ジョブからアクセスできるようになります。さらに、このジョブには、ワークフロー成果物をダウンロードするステップと Azure にサインインするステップが含まれていることに注目してください。 ジョブはそれぞれのランナーで実行されるため、自己完結していることが必要です。
ファイルに加えた変更を保存します。
deploy.yml ファイルの内容を確認し、変更をコミットする
deploy.yml ファイルが、次の例のようになっていることを確認します。
name: deploy on: workflow_call: inputs: environmentType: required: true type: string resourceGroupName: required: true type: string reviewApiUrl: required: true type: string secrets: AZURE_CLIENT_ID: required: true AZURE_TENANT_ID: required: true AZURE_SUBSCRIPTION_ID: required: true reviewApiKey: 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 }} reviewApiUrl=${{ inputs.reviewApiUrl }} reviewApiKey=${{ secrets.reviewApiKey }} 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 }} reviewApiUrl=${{ inputs.reviewApiUrl }} reviewApiKey=${{ secrets.reviewApiKey }} additionalArguments: --what-if deploy: needs: validate environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest outputs: appServiceAppName: ${{ steps.deploy.outputs.appServiceAppName }} 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 }} reviewApiUrl=${{ inputs.reviewApiUrl }} reviewApiKey=${{ secrets.reviewApiKey }} deploy-website: needs: deploy environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest steps: - uses: actions/download-artifact@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/webapps-deploy@v2 name: Deploy website with: app-name: ${{ needs.deploy.outputs.appServiceAppName }} package: website/publish.zip 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
ファイルに加えた変更を保存します。
Visual Studio Code ターミナルで次のコマンドを実行して、変更を Git リポジトリにコミットしてプッシュします。
git add . git commit -m "Build and deploy website application" git push
このリポジトリにプッシュしたのは初めてなので、サインインを求めるメッセージが表示される場合があります。
Windows の場合、「1」と入力して Web ブラウザーの使用を認証し、Enter キーを押します。
macOS の場合は、[承認] を選択します。
ブラウザー ウィンドウが開きます。 場合によっては、再度 GitHub にサインインする必要があります。 [承認] を選択します。
ワークフローを実行する
ブラウザーで、Actions に移動します。
Initial commit というラベルが付いたワークフローの初めての実行が失敗として表示されます。 GitHub が、リポジトリの作成時にワークフローを自動的に実行しました。 その時点でシークレットの準備が整っていなかったため、失敗しました。 この失敗は無視してかまいません。
deploy-toy-website-end-to-end ワークフローを選択します。
ワークフローの最新の実行を選択します。
build ジョブが正常に完了するまで待ちます。
deploy-test / deploy ジョブが正常に完了するまで待ちます。
[注釈] パネルにいくつかの警告がリストされています。 これらの警告すべては、Bicep が情報メッセージをワークフロー ログに書き込む方法が原因です。 これらの警告は無視してかまいません。
その後、ワークフローによって deploy-test / smoke-test ジョブが実行されますが、スモーク テストは失敗します。
[deploy-test / smoke-test] ジョブを選択してワークフロー ログを開きます。
[Run smoke tests](スモーク テストの実行) ステップを選択して、ワークフロー ログの関連セクションを表示します。
Web サイトと構成が正常ではないというワークフロー ログが表示されていることに注目してください。 Azure SQL Database とのアプリケーションの通信に問題があります。 データベースのデプロイも構成もまだ完了していません。このため、Web サイトからアクセスできません。 この問題はすぐに解決します。