しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

GitHub Actions の Environments が予想通り最高だったので勢いで一通り試した

Universe 2020 で発表された機能の中で一番楽しみだったのが GitHub Actions の Environments です。デプロイ先ごとに環境変数と Protection rule を設定出来るようになります。

Azure Pipelines では Approvals and checks と Environments という同等の機能がありますが、そのまま GitHub にもっていったという感じです。予想通り便利でした。

Using environments for deployment - GitHub Docs

これまで Azure Pipelines を使っていて、デプロイに特化した機能があるのはかなり便利だと実感していたので、Azure Pipelines から GitHub Actions への移行はこの辺りが実装されるまでは難しいと思っていました。

一通り試してみましたが、完全に Azure Pipelines より使い勝手が良かったので、Azure Pipelines を使う理由が Azure AD でログインがし易いという点以外無くなった感があります。

Environment を作成する

設定に Environments という項目が増えています。今は Public リポジトリだけでしか使えないので、Private の場合は一旦諦めましょう。

Environment は最初に書いたように Environment 単位での環境変数と Protection rule の組み合わせなので、設定内容は非常に分かりやすいです。とりあえずいい感じの名前を付けるところから始めます。

Azure Pipelines の Environment は Kubernetes と Virtual Machine への対応でいろいろと設定が必要でしたが、GitHub の Environment では環境変数を追加するだけという分かりやすさです。

Azure App Service へのデプロイを行いたいので、Publish Profile を追加しています。

ちなみに Repository secrets と Environment secrets は同じ名前で登録が出来ますが、基本は Environment secrets が優先されるので上書きされるようです。実際の動きとしては予想通り、実行時にはそれぞれの Secrets がマージされるので分かりやすいです。

GitHub のサービスは大体動きが予想通りなので分かりやすいですね。

作成した Environment は Workflow から参照しないと意味がないので、環境を作成した後は Job の定義に参照を追加します。Job 単位で 1 つだけ Environment を参照できます。

https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idenvironment

参照を追加した Job では Environment secrets が参照できるようになります。分かりやすいですね。

Environment 名を指定する必要があるので、シンプルな名前にしておいた方が良いです。URL を一緒に指定しておくと後で便利に使えるようになります。

Pull Request でステージングへデプロイ

最近は Pull Request を作成すると自動的にステージング用のサイトを作ってくれるサービスが増えてきましたが、あまりカスタマイズする余地が無いのでシンプルなアプリケーション以外では実現が難しい印象です。

Environments は環境毎に認証情報や接続先などの情報を定義出来るので、上手く組み合わせれば PR 単位でのステージング向けデプロイが行えます。とりあえず固定の App Service のスロットへデプロイする Workflow を書いて試しました。

deploy:
  runs-on: ubuntu-latest
  environment:
    name: staging
    url: https://webapp-deploytest-1-staging.azurewebsites.net
  needs: build
  steps:
  - name: Download artifact
    uses: actions/download-artifact@v2
    with:
      name: webapp

  - name: Deploy staging
    uses: azure/webapps-deploy@v2
    with:
      app-name: webapp-deploytest-1
      slot-name: staging
      publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
      package: ./WebApplication1.zip

この例では staging という名前で Environment を作成しています。Workflow 自体は Pull Request トリガーで動かせばよいので特に説明も要らないでしょう。

App Service はデプロイ時に Publish Profile か Service Principal が必要になりますが、Publish Profile は App Serivce 単位の認証情報なので、Environment とは相性が非常に良いです。Service Principal を使う場合は環境毎に作成して、それぞれ必要なリソースだけ操作出来るように RBAC で権限を絞りましょう。

Pull Request を作成すると以下のように Workflow が実行されて、デプロイまで完了します。

この時に environmenturl を設定しておくと、確認用としてリンクが表示されるようになります。

実行結果だけではなく、Pull Request 自体にもデプロイ結果が表示されるようになるので、開発中やレビューの際に Pull Request から直接デプロイされた環境にアクセス出来るようになります。

今回は固定の環境だったのであまりメリットに感じないかもしれませんが、実行時に環境を作成するような場合*1は URL も動的に生成されるはずなので、その URL をコメントなどで残すようにしていると思います。

そういう場合には Environment を使うと、いい感じに確認用の環境をセットで管理できます。

本番デプロイではレビューを必須に

Universe でも発表があったのはレビュー機能でした。Azure Pipelines には昔から実装されていて便利に使っている機能なので、これが実装されないと GitHub Actions への移行は難しいと感じていました。

Environment 単位でユーザーやチームをレビュアーとして追加出来ます。設定はシンプルです。

Azure Pipelines にはもっと機能があったので、この Protection rule は今後追加される気がします。API 連携で独自のルールを定義するような機能も来る予感です。

ここで指定した Protection rule は Environment を参照している Job が走る前に評価されます。

同じ Environment を参照していたとしても、1 回承認すれば全て通るような挙動にはなりません。新しい Job が走る場合は都度承認が必要になります。

レビューにはコメントが追加出来ますが、絵文字入力は出来ないようでした。この例では 1 つの Job なので 1 つだけ出ていますが、複数の Job が Environment を参照している場合は個別に承認出来るようになります。

承認すれば後はこれまで通り Job が実行されます。下の方にレビュアーのログが表示されるようになっているので、承認した人と対象の Environment、そしてコメントを個別に確認できます。

ぶっちゃけ Azure Pipelines の同じ機能より圧倒的に使いやすく、さらにシンプルになっています。上手く Environment を使って環境を抽象化出来ているので、デプロイ先に依存しない作りが更に良いです。

デプロイ履歴を確認

Environment を作成するとリポジトリのサイドバーに Deployments というカテゴリが追加されます。

選択すると Environment 毎のデプロイ履歴が確認できます。この辺りは Deployments API と統合されているからのようで、Actions の履歴から確認するより分かりやすいです。

Environment をデプロイの履歴管理として使うだけでも良さそうです。

ここでも environmenturl を追加しておくと、確認用のボタンが表示されるのでサクッと確認出来るようになっています。デプロイまで統合されているのはメリットが非常に大きいと実感しました。

*1:例えば Azure Static Web Apps のようなもの