BEACHSIDE BLOG

Azure と GitHub と C# が好きなエンジニアの個人メモ ( ・ㅂ・)و ̑̑

GitHub Actions の azure/login 使い方と Tips

GitHub Actions で Azure CLI や PowerShell を使って Azure のリソースを操作したいときには、 azure/login を使って Azure に認証します。

使うだけは簡単なのですが、認証時に使う credentials について知っておくべきのことを書きたかったのでブログにしたって感じです。

余談ですが、azure/login を使わず Azure Web Apps や Azure Functions では azure/webapps-deployAzure/functions-action の action を使えば Publish profile (発行プロファイル) を使うことで認証するパターンもあります。
単一の Web App や function にデプロイするなら publish profile でもよいし、例えば同一リソースグループの複数の functions にデプロイするなら、それぞれの publish profile を用意するよりも、そのリソースグループをスコープとした credentials を使うことで認証・認可をまかなうことができます。

Azure のリソースにデプロイするための Credentials を取得する

Azure にデプロイするとかリソースを操作するのでもちろん認証をします。そこで必要なのが credentials です。 (docs.microsoft.com の日本語だと 資格情報 って翻訳されてるやつ)。

個人的には、翻訳しても "クレデンシャル (ズ) " でよくねとかいつも思ってしまうのはさておき、azure/login を使うにはまずこの credentials が必要になります。

Azure CLI を使って credentials を作成するところからはじめていきましょう。

Azure CLI の準備とサブスクリプションの確認

Azure CLI の利用準備と、今回操作したいリソースのサブスクリプションを指定するまでの手順が不明の場合は、以下のブログをご参照ください。

blog.beachside.dev

Credentials の作成

ここでは、特定のリソースグループの中にあるリソースを操作できる credentials を作成します。

そうでないユースケースとして後述で「az ad sp create-for-rbac で指定できるスコープ」「複数の Resource group で適用したい場合は?」を後述してます。

Credentials の作成で必要なのは以下の 3 つです。

  • サブスクリプション ID
  • リソースグループ名
  • 登録する credentials の任意の名前。(これは...まぁなんでもいいんですが、作成後のあれこれの都合から url として登録できるフォーマットが好まれます。雑に作るなら英数字とハイフンくらいでつくっておけばいいんじゃないかなと。invalid なフォーマットだとだいたい自動で変換してくれますが、そこら後ほど軽く触れます。)

上記のリンクでも書いてますが、今回操作したい対象のサブスクリプションの "IsDefault" が True になっていることは確認しておきましょう。

az account list -o table

f:id:beachside:20210827144045p:plain

例えばこんな内容で作成したいとすると

  • サブスクリプション ID が xxxxxxxx-xxxx-xxxx-xxxx-1234567890ab
  • リソースグループ名が rg-XXXXXXXXXXX
  • github-actions-demo-1

コマンドはこうなります。

az ad sp create-for-rbac --name "github actions demo 1" --role contributor  --scopes /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg-XXXXXXXXXXX --sdk-auth

実行するとこんな感じ。色々とメッセージがかかれますが、エラーにならずに、クレデンシャル情報の JSON が表示されれば OK です。

f:id:beachside:20210827151528p:plain

GitHub の secret に登録する

GitHub には secret のストアがあります。特定権限を持ったアカウントしかアクセスできず、一度登録すると値はみれない、GitHub Actions からシームレスに利用が可能なストアです。

余談ですが、GitHub Enterprise とか使ってると Organization 共通の Secrets を作れます。また Environments 単位で Secrets を管理できるため、例えば本番環境も開発環境も同じ Secret のキーを指定して GitHub Actions の YAML を書くことができます。YAML を共通化できるってやつですね(共通化する機能はここではさておき...今度試してブログ書こうと思ってます)。

ということで GitHub の secret に登録します。

GitHub の repository を開いて Settings をクリックします。

f:id:beachside:20210827155910p:plain

画面の幅が狭いと "・・・" に隠れていることもあります。

f:id:beachside:20210827160105p:plain

ない場合は、repository に対する権限が足りないので repository の owner に聞いてみましょう。

"Secret" (①) をクリック → "New repository secret" (②) をクリックします。

f:id:beachside:20210827160258p:plain

シークレットの登録画面なので、以下を参考に入力して、最後に "Add secret" ボタンを押せば登録完了です。

  • Name: 任意のものを付けます。複数の credentials を扱わないならシンプルに AZURE_CREDENTIALS でいいと思いますし、複数管理する必要があるならわかりやすい名前にしとくと無難です。
  • Value: にはコマンドを実行したときに出力されたJSONをそのままはります。

f:id:beachside:20210827160909p:plain

GitHub Actions で azure/login を使う

あとはドキュメントでよく書いてある感じでサクッと使えます。簡単ですね♪

on: [push]

name: AzureLoginSample

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Log in with Azure
        uses: azure/login@v1
        with:
          creds: '${{ secrets.AZURE_CREDENTIALS_GITHUB_ACTIONS_DEMO1}}'

基本的には使い方はこれでたりますが、細かい使い方がazure/login の repo の README に書いてあるので参照するとよいと思います。

az ad sp create-for-rbac で指定できるスコープ

作成した credentials には --role contributor と指定しているので contiributor (共同作成者) が割り当たっています。つまりは 五条先生*1 くらいつよい権限ってことです。

前述で作成したコマンドだと -scopes でリソースグループを指定してますので、このスコープは指定したリソースグループに対して有効です。

そうではなく、サブスクリプションは以下すべてのリースを対象にするなら --scopes を以下のように指定することで実現できます。

--scopes /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/

ただ、付与される権限が強いだけに最小限に抑えるのがベストプラクティスだと思っていますので、おすすめはできないなーと感じています。

また、より細かくリソースグループの中の App Service 全てを対象とか特定の App Service だけを対象とかもできます (書き方はこちら) 。

まぁ細かくすれば管理が煩雑になり、運用が面倒になるのはクールじゃありません。以下に運用を最適化して、時間も金も開発にフォーカスした方がプロダクトは成長しますので。

ケースバイケースではありますが、Credentials を管理しやすいように権限も加味してリソースグループの設計方針をしつつ、リソースグループに対して credentials のロールを割り当てていくのが運用的に良いかと思います。

複数の Resource group で適用したい場合は?

複数の credentials を作成して管理をするのも悪くはないですが、Resource group がわかれているだけでサービスのドメインの責務は一緒なら 1 つの credentials で管理したいものです。

そんなときは、その credentials を追加したい Resource group の IAM で権限を付与してあげればよいです。

具体的には、追加したい Resource Group を開いて、IAM (①) → 追加 (②) → ロールの割り当ての追加 (③) をクリックします。

f:id:beachside:20210827154722p:plain

ロールの割り当ての追加が表示されますので以下を参考に設定すればよいです。

  • "役割"は 共同作成者 を選びます。
  • "アクセスの割り当て先" は、デフォルトの ユーザー、グループ、またはサービス プリンシパル
  • "選択" で先ほど作成したものを選択します。

あとは "保存" ボタンをクリックして保存すれば完了です。設定の反映まで数分かかることもあるので、設定後はひと休憩してから GitHub Actions の動作を試しましょう。

f:id:beachside:20210827154557p:plain

credentials の管理

作成した credentials は Azure AD のサービスプリンシパルです。つまり、そのサブスクリプションの Azure AD のリソースを開いて確認することができます。

余談ですが、Azure portal の "外観" の設定ってドッキング使ってますかね。使ってると下図のように Azure portal の左側によく使うアイコンだけを表示させることができるので、私はここの Azure AD のアイコンをぽちっと押します。

Azure AD のリソースを開いたら、"アプリの登録" (②) → "すべてのアプリケーション" (③) をクリックします。ここにコマンドで作成したサービスプリンパルがいます。

コマンドを間違って typo した名前を作成したとかでこの世から抹消したくなったらここから消しましょう。

中身を見たいのでクリックしてみましょう。

f:id:beachside:20210827161654p:plain

開いた画面で "証明書とシークレット" をクリックすると、有効期限が1年でシークレットが作成されたことがわかります。つまり、1年で切れるので更新が必要となります。これを知ってただけで、GitHub Actions で有効期限がきれたぜってエラーが出たら焦らず対応できますね。

f:id:beachside:20210827162137p:plain

シークレットだけ更新ってのもできなくないですが、ほかの JSON の項目なんだっけってとか面倒るので素直にここを削除して作り直した方がいい気がします。

さらには気合 (?) で有効期限長いシークレットつくるとかもできますが、まぁ普通に運用していけばよいのではくらいな感覚です。(といいつつ私が運用してるものの一部では、本番環境のシークレットを更新不要な期限で登録しつつ、開発環境はなんとなく気分で一年で切れるようにしてエラーみて「あれか」って気づけるようにしてますがw

まとめ

Actions で azure/login 使うのは簡単だけど、サービスプリンシパルについて知っておくとよりいい感じに CI/CD ライフが遅れるかもしれないって感じです。

参考

*1:呪術廻戦の五条悟