Check! GitHub Actions で OpenID Connect(OIDC) で Azure に安全に接続する
Prologue
こんにちは、@dz_ こと、岩永かづみです。
Microsoft Azure を外部から使うときは、サービス プリンシパル(Service principal)を利用することが多いですが、後述のワークロード ID フェデレーションを利用し OpenID Connect(OIDC)で接続する方が安全&簡単だと気づいたので、使えるときは積極的に使っていきたく、知見を共有します。
サクッと手順を知りたい方は、後述の GitHub Actions から OIDC で Azure に安全に接続する へお進みください。
Microsoft Azure で OpenID Connect(OIDC)を利用する概要
Microsoft Azure では、Azure Active Directory(Azure AD)を使用して OpenID Connect による認証を行うことができます。さらに、Azure AD のワークロード ID フェデレーションを使用することで、GitHub などのサポートされている IdP からのトークンを信頼するよう構成することができ、これによりシークレットを扱うことなく短期のアクセストークンを用いた接続を利用できるようになります。利用できるシナリオは、以下が挙げられており、ここでは GitHub Actions からの接続について取り上げます。
- GitHub Actions からの Azure リソースのデプロイ
- Google Cloud からの接続
- Kubernetes で実行されているワークロード
- 信頼関係を構成したその他の IdP を使用したワークロード
GitHub Actions で OpenID Connect (OIDC) を利用する
GitHub Actions からみた OpenID Connect(OIDC)の情報は、こちらをご参考ください。
ドキュメントでは、Microsoft Azure, Amazon Web Services, Google Cloud Platform, HashiCorp Vault に対する接続について記載されており、またその他のクラウド プロバイダー においても手順が解説されています。
なお、Microsoft Azure への接続についてのドキュメントがわかりにくいので、ご紹介するのがこの記事の主な目的です🎯
GitHub Actions から OIDC で Microsoft Azure のリソースに安全に接続する
ここでは Azure ポータルでの操作をご紹介します。大まかな手順は以下の通りです。
- Microsoft Azure で Azure AD アプリケーションを作成する
- 作成した Azure AD アプリケーションにフェデレーション資格情報を追加する
- Azure で認可させたいリソースにロールを割り当てる
- GitHub Actions のシークレットに、下記を設定する
- Azure AD アプリケーションのクライアントID, Azure のテナントID, Azure のサブスクリプションID
- GitHub Actions ワークフローで
Azure/login
アクションでログインする
Azure ポータルで、Azure AD アプリケーションを作成する
まず、Azure ポータル( https://portal.azure.com )で「Active Directory」を開きます。
ポータル上部の検索ボックスで検索すると素早く移動できます。
「Active Directory」画面の左のメニューから「アプリの登録」(App registrations)を開きます。
上部のメニューから「+新規登録」(New registration)を選択します。
任意の「名前」(Name)を入力し、「サポートされているアカウントの種類」(Supported account types) を選択し、「登録」ボタンから登録します。
「サポートされているアカウントの種類」は、特に理由がなければ「この組織ディレクトリのみに含まれるアカウント ( {ディレクトリ名} のみ - シングル テナント)」を選択してください。
アプリケーションの新規作成が完了すると、作成されたアプリケーションの画面に遷移します。
ここに表示されている、「アプリケーション(クライアント)ID」と「ディレクトリ(テナント)ID」は、後述の手順で必要なので控えておいてください。
Azure ポータルで、作成した Azure AD アプリケーションにフェデレーション資格情報を追加する
つぎに、フェデレーション資格情報の設定を行います。
作成したアプリケーションの画面で、左のメニューから「証明書とシークレット」(Certificates & secrets)を開き、「フェデレーション資格情報」(Federated credentials)タブから、「+資格情報の追加」(+ Add credential)を選択します。
「フェデレーション資格情報のシナリオ」(Federated credential scenario)に「Azure リソースをデプロイする GitHub Actions」(GitHub Actions deploying Azure resources)を選択します。
「GitHub アカウントを接続する」(Connect your GitHub account)の項目で、「組織」(Organization)、「リポジトリ」(Repository)を入力します。
「エンティティ型」(Entity type)は、「環境」「ブランチ」「Pull request」「タグ」から選択でき、「サブジェクト識別子」に対応した文字列を入力します。筆者がよく使うのは「環境」(Environment)で、GitHub 側の Environment for deployments に対応させています。エンティティ型についての詳細は、subject 要求の例 をご参照ください。ここでは、エンティティ型に「環境」を指定し、サブジェクト識別子に staging
と入力したとして進めます。
「資格情報の詳細」(Credential details)の項目で、「名前」(Name)に任意の名前を入力し、「追加」ボタンを選択して追加を完了します。
Azure ポータルで、認可させたいリソースにロールを割り当てる
つぎに、作成したアプリケーションに、必要なロールを割り当てます。
ここでは、リソース グループに割り当てる手順を紹介します。他のリソースでも同様です。
Azure ポータルで、割り当てたいリソース グループを開き、「アクセス制御(IAM)」(Access control (IAM))を開きます。
「+追加」(+Add)から「ロールの割り当ての追加」(Add role assignment)を選択します。
「ロール」(Role)タブで、割り当てるロールを選択します。ここでは、「共同作成者」(Contributor)を選択します。実際には適切なロールを割り当ててください。
「メンバー」(Members)タブで、「メンバーを選択する」(Select members)から作成した Azure AD アプリケーションを選択します。
「レビューと割り当て」(Review + assign)ボタンを選択し、内容を確認し再度「レビューと割り当て」(Review + assign)ボタンを選択し、ロール割り当てを完了します。
Azure のサブスクリプションIDを取得する
サブスクリプションIDは、各リソースの概要画面で確認できるので、ここでついでに取得しておきます。
上記のリソース グループで「概要」(Overview)を開き、「サブスクリプションID」を控えておきます。
GitHub Actions のシークレットに、下記を設定する
つぎに、GitHub Actions のシークレットに下記を設定します。
- Azure AD アプリケーションのクライアントID
- Azure のテナントID
- Azure のサブスクリプションID
ここでは、下記のシークレット名で設定したとして進めます。
シークレット名(例) | 説明 |
---|---|
AZURE_CLIENT_ID |
前述で控えた「アプリケーション(クライアント)ID」を入力 |
AZURE_TENANT_ID |
前述で控えた「ディレクトリ(テナント)ID」を入力 |
AZURE_SUBSCRIPTION_ID |
前述で控えた「サブスクリプションID」を入力 |
Azure/login
アクションでログインする
GitHub Actions ワークフローで、さいごに、GitHub Actions ワークフローで Azure にログインする処理を記述します。
Azure へのログインは azure/login
アクションを利用できます。下記のように、client-id
, tenant-id
, subscription-id
を指定します。詳細については、下記をご参考ください。
jobs:
login:
runs-on: ubuntu-latest
# この例では、エンティティ型で environment を指定したので、
# environment の名前がサブジェクト識別子に指定した文字列と一致する必要がある
environment:
name: staging
permissions:
# OIDC 接続を実行するために必要
id-token: write
steps:
- name: Login in to Azure
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Test access to Azure
run: |
az account show --query name
permissions
の id-token: write
は、OIDC 接続において JWT ID トークンを要求するために必要です。詳しくは下記をご参照ください。
また、この例では staging
という名前で environment を作成している前提で記述してます。environment は、リポジトリの Settings から作成してください。
azure/login
アクションでログインができたら、以降の step でその接続をもって Azure CLI や他の azure/*
アクションを利用できるようになります🙆🏻♀️
Epilogue
一度覚えると、以降は OIDC による接続を選択すること間違いなしです。ぜひお試しください。
なお、実は同じ内容について、所属先の仲間 @BEACH_SIDE さんのブログでも紹介されているので、共にご参考ください🔍
Discussion