🍇

Github ActionsからAzureへのLoginの簡潔なまとめ

2023/09/01に公開

Github ActionsからAzureへのデプロイなどを行う際にはGithub ActionsのJobごとに
AzureへのLoginが必要です。

GitHub と Azure を接続する | Microsoft Learn

にやり方は書かれているのですが、省略や他ページへのジャンプが多く分かりづらいので以下にまとめます。

大きく分けて2つの方法があります。

  1. サービスプリンシパルを用いる方法
    • メリット: 設定が簡潔
    • デメリット: シークレット自体をGithubに登録する必要がある
      (そのためシークレットのローテーションなどのメンテナンスも必要)
  2. OpenID Connect(OIDC)を用いる方法
    • メリット: シークレットをGithubに登録しなくてもよい
      環境やタグ、ブランチなどを限定して実行許可を与えられることも含め組織的な権限管理に向く
    • デメリット: 設定が多少煩雑

という形なので、開発等で軽く試すならサービスプリンシパルを、本番環境等で厳密に権限管理を行いたい場合にはOIDCがおすすめとなります。

サービスプリンシパルを用いる方法

https://github.com/Azure/login#configure-a-service-principal-with-a-secret

Github Actionsのワークフローの書き方は

    - uses: azure/login@v1with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

AZURE_CREDENTIALSは以下で作成するサービスプリシパルのsecretです。

サービスプリンシパル自体は

   az ad sp create-for-rbac --name "myApp" --role contributor \
                            --scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group} \
                            --json-auth

というコマンドで発行でき、レスポンスのclient secretsをAZURE_CREDENTIALSに登録すればOKです。(上のコマンドは実際にはリソースグループ全体への共同編集者権限でかなり強いので本番運用ではもっと権限を絞ったほうがよいでしょう)

また、一つのたくさんのサブスクリプションやテナントを管理しておりログイン先を明示的に指定したい場合には

    - name: Login to Azure CLI
      uses: azure/login@v1
      with:
        creds: creds: '{"clientId":"${{ secrets.CLIENT_ID }}","clientSecret":"${{ secrets.CLIENT_SECRET }}","subscriptionId":"${{ secrets.SUBSCRIPTION_ID }}","tenantId":"${{ secrets.TENANT_ID }}"}'

という書式で指定できます。

OpenID Connect(OIDC)を用いる方法

もう一つがAzure ADのOpenID Connect認証を用いる方法となります。
この場合のworkflowの指定方法は

      - name: Az CLI login
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

という指定となっています。
また、ワークフローのpermisssion定義で以下のような記述も必要です。

on: ...

permissions:
      id-token: write
      contents: read
      
jobs: 
  ...

Azure側の設定手順は以下となります。

  1. サービスプリンシパルの発行: 上記と同じ手順でサービスプリンシパルを発行します。
az ad sp create-for-rbac --name "myApp" --role contributor \
                            --scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group} \
                            --json-auth

実はここで作成する「サービスプリンシパル」とAzure ADで登録される 「アプリの登録」のアプリ とは同一のものを指します(大変分かりづらいですが)

  1. Azure ADに[アプリの登録]を開き、作成したサービスプリンシパルのClient IDを投入します
    アプリ(サービスプリンシパル)が見つかったら、その詳細画面を開き、「証明書とシークレット」を選択します。

「フェデレーション資格情報」から「資格情報の追加」を押します。

シナリオから「Azure リソースをデプロイする Github Actions」を選択します。

ここまでで、「Githubの特定のリポジトリを信頼した、リソースグループへの権限を持ったサービスプリンシパル(アプリ)」ができました。

Githubのsecretとしてそれぞれ以下を登録してください。

  • AZURE_CLIENT_ID: このアプリの「概要」から確認できるアプリケーション(クライアント)ID
  • AZURE_TENANT_ID: 同画面から確認できるディレクトリ(テナント)ID
  • AZURE_SUBSCRIPTION_ID : サービスプリンシパル発行時に指定したサブスクリプションID

ここまでを正しく指定できていれば以下のようなworkflowでGithub ActionsでAzure Loginが成功するかと思います。

name: Run Azure Login with OpenID Connect
on: [push]

permissions:
      id-token: write
      contents: read
      
jobs: 
  build-and-deploy:
    runs-on: ubuntu-latest
    environment: development
    steps:
    - name: 'Az CLI login'
      uses: azure/login@v1
      with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
  
    - name: 'Run Azure CLI commands'
      run: |
          az account show
          az group list
          pwd

Discussion