ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

GitHub Actions w/ OIDC で ACR に docker push する

f:id:horihiro:20220321154822p:plain

TL; DR

azure/docker-login など docker login 系の Action ではなく az acr login コマンドでログインする。

name: Run Login to ACR w/ OpenID Connect

on:
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  ACRJob:
    runs-on: ubuntu-18.04

    steps:
      - uses: actions/checkout@main
      - uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 

      - name: docker login, build and push
        run: |
          az acr login -n ${{ secrets.ACR }}  # <--- **これ**
          docker build ./target -t ${{ secrets.ACR }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ github.run_number }}
          docker push ${{ secrets.ACR }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ github.run_number }}
        env:
          IMAGE_NAME: minimalserver

あ、Azure AD アプリケーションに AcrPull のロールを割り当てることを忘れずに。

以下、背景的な何か

GitHub Actions が OpenID Connect に対応してた

もう半年近く前、GitHub Actions が OpenID Connect に対応していた。
これで azure/login のアクションも資格情報として Azure AD アプリケーションの clientSecret を使わなくて済むようになった。

詳細はここに全て書いてある。

blog.haniyama.com

ただし Azure Container Regisitry & GitHub Actions のドキュメントを見ると、azure/docker-login で昔ながら?の clientSecret を使って ACR にログインする方法で書かれている。

ここと、

f:id:horihiro:20220319200022p:plain

ここ。

f:id:horihiro:20220319195916p:plain

できることなら clientSecret はあまり管理したくないので、何とか OIDC の仕組みを使って、GitHub Actions 内で clientSecret を使わない方法がないかにチャレンジ。

(おさらい) ACR にログインする

ACR は Docker の API (でいいの?)と互換性を持っているので、

docker login -u <ユーザー名> -p <パスワード> <ACR ログイン サーバー>

でログインできる。<ユーザー名> / パスワード は、

  1. Azure AD アプリケーションの場合は、
    • ユーザー名: アプリケーション ID (ClientID)
    • パスワード: clientSecret
  2. ACR の管理者ユーザーを有効にした場合は、
    • ユーザー名: ACR リソース名
    • パスワード: [アクセス キー] ブレード内の password or password2
      f:id:horihiro:20220319195524p:plain

のどちらかのペアを使うことになる。

今回は、OIDC を使って azure/login アクションで取得した認証情報を、ここのユーザー名/パスワードとして使う方法がないか調べたら、そこまでしなくていい方法がここに書いてあった。

github.com

曰く、

az acr login -n <ACR リソース名>

を使えばいい、と。

これを実行すると、

  • ユーザ名は null GUID 00000000-0000-0000-0000-000000000000
  • パスワードは、azure/login からの認証情報を元に(なんやかんやで)取得してきた ACR の refresh token

を使って docker login を実行してくれるらしい。
azure/docker-login アクションすら必要ないので、冒頭yaml になる。

サンプル リポジトリー。

github.com

ちなみに azure/docker-login がやっていること

azure/docker-loginwith で与えられた clientSecret などを使って何しているか見てみると、

github.com f:id:horihiro:20220320092328p:plain

なんと直接 config.json に認証情報を追記している。docker login すら実行していないとは。