GitHub Actionsを使用したAzureリソースのIaCデプロイ
はじめに
Infrastructure as Code (IaC)を用いたAzureリソースのデプロイは、Azure DevOpsだけでなく、GitHub Actions上でも実行可能です。本記事では、GitHub Actionsを用いたIaC(Bicepファイル)デプロイ手法と、その際に用いる資格情報のパターンについて紹介します。また、Azure DevOpsとの比較として、GitHub Actionsで用いる資格情報の動作確認プロセスにも触れます。
本記事の ソースコードは、Gitに登録しています。
デプロイ時に利用する資格情報
Azure上にIaCデプロイを行う際、Azureリソースへの認証には主に以下の2パターンが存在します。
- サービスプリンシパルを用いた認証
- OpenID Connect (OIDC) を用いた Workload Identity による認証
GitHub Actionsで従来から用いられてきたのは、サービスプリンシパルを使用してAzureにログインする方法です。しかし、よりセキュアでトークンの使い捨てが可能なOIDCを利用することで、GitHubリポジトリから直接Azureリソースへのトラストベースなアクセスが可能になります。
OIDCを使用することで、Azure AD(Entra ID)上で特別な秘密情報を保存する必要がなく、GitHubからのアクセスをより安全かつ柔軟に管理できます。
Azure Service Principalの登録とGitHub⇔Azureのコネクション
Entra ID>アプリの登録をしサービスプリンシパルとして構成します。
続いて、証明書とシークレットより、フェデレーション資格情報を構成します。
GitHub シークレットへ登録する情報
GitHub ActionsでAzureへログインする場合、特定のシークレットが必要になります。以下はサービスプリンシパル利用時に必要となる情報と、GitHub シークレットとの対応関係です。なお、OIDCを利用する場合でも、azure/login
Actionで関連パラメータを渡すために同様の値が求められます。
GitHub シークレット | Microsoft Entra アプリケーションの値 |
---|---|
AZURE_CLIENT_ID | アプリケーション (クライアント) ID |
AZURE_TENANT_ID | ディレクトリ (テナント) ID |
AZURE_SUBSCRIPTION_ID | サブスクリプション ID |
これらは GitHubリポジトリ > Settings > Secrets and variables > Actions
から登録可能です。
サンプルワークフロー(OIDC利用時)
以下は、OIDCベースでAzureに認証し、Bicepを用いてリソースをデプロイするGitHub Actionsのサンプルです。
workflow_dispatch
で手動前提としていますが、よしなに変えてください。
name: Deploy Bicep using ARM Deploy
on:
workflow_dispatch:
inputs:
azureRgName:
description: 'Azure Resource Group Name'
required: true
default: 'rg-bicep-osa-test-001'
environmentType:
description: 'Environment type (nonprod or prod)'
required: true
default: 'nonprod'
deployAmeretatManualsStorageAccount:
description: 'Deploy Ameretat Manuals Storage Account (true or false)'
required: true
default: 'true'
# OIDC認証を使用してAzureにログインしている場合(id-token: write が必要)
# リポジトリからBicepファイルを取得している場合(contents: read が必要)
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# Azure CLIでのログイン
- name: 'Login 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: 'Checkout repository'
uses: actions/checkout@v3
# 定義したパラメータを確認
- name: 'Set parameters as environment variables'
run: |
echo "ENVIRONMENT_TYPE=${{ github.event.inputs.environmentType }}"
echo "DEPLOY_AMERETAT_STORAGE=${{ github.event.inputs.deployAmeretatManualsStorageAccount }}"
# ARM Deployを使用したBicepファイルのデプロイ
- name: 'Deploy Bicep file'
uses: azure/arm-deploy@v1
with:
subscriptionId: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resourceGroupName: ${{ github.event.inputs.azureRgName }}
template: deploy/main.bicep
parameters: >
environmentType=${{ github.event.inputs.environmentType }}
deployAmeretatManualsStorageAccount=${{ github.event.inputs.deployAmeretatManualsStorageAccount }}
deploymentMode: Incremental
failOnStdErr: false
ポイント
-
permissions
セクションでid-token: write
とcontents: read
を設定することで、OIDC認証とリポジトリ内容へのアクセスが可能になります。 -
azure/login@v1
Actionを用いてOIDCを使用したAzureログインを実施します。 -
azure/arm-deploy@v1
Actionにより、BicepファイルをARMテンプレートとしてデプロイします。
Azure DevOpsとの違い(サービスコネクション vs GitHub Secrets)
Azure DevOpsでのデプロイ時には、サービスコネクションを用いてAzureリソースへの接続性を事前検証できます。例えば、Azure DevOpsの「Service connections」からAzureへの接続を事前に確認しておけば、ワークフロー実行前に資格情報の有効性を把握できます。
一方、GitHub Actionsでは、SecretsやOIDC設定を行っても、実際にワークフローをトリガーしてみるまで、資格情報が正しくAzureと通信できるかを確実には把握しづらい点があります。つまり、「設定後すぐにボタン一つで接続性をテスト」するような仕組みは現在のところ存在せず、ワークフロー実行(=実運用に近い形)で初めて有効性を確認できます。
これは、GitHub ActionsとAzure DevOpsの運用思想の違いとも言えます。GitHub Actionsの場合、セキュリティや運用設計の中で、事前検証のプロセスを別途用意することを検討する必要があるでしょう。
疎通だけであれば下記のようにCLIを発行するActionsを作成し、確認するのもいいかもしれません。
name: Run Azure Login with OpenID Connect
on:
workflow_dispatch:
# push:
# branches: [ main ]
permissions:
id-token: write
contents: read
jobs:
build-and-deploy:
runs-on: ubuntu-latest
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