Azure Kubernetes Service 関連のGitHub Actions カスタムアクションを使ってデプロイをする
Azure Kubernetes Service (以下AKS) のデプロイについて、手動でkubectl のようなコマンドをあれこれ準備するのは大変です。今回はMicrosoft が提供している公式のカスタムアクションを利用し、既存のAKS にマニフェストを適用する方法について説明します。

実施環境
Azure CLI | 2.81.0 |
|---|---|
Kubernetes | 1.34.1 |
前提条件
- Azure アカウントおよびAzure CLI の実行環境があること
- GitHub アカウントがあること
- 認証用のGitHub Apps のトークンがあること
Azure Kubernetes Service におけるGitHub Actions のカスタムアクション
Azure Kubernetes Service (以下AKS) 関連のGitHub Actions カスタムアクションについて、2026年1月現在では以下のカスタムアクションがあります。ドキュメントでは azure/aks-github-runner というリポジトリも触れていますが、こちらはTerraform やHelm を使ってセルフホステッドランナーを設定するサンプルのため除外します。また、一部アクションは現時点で更新されていないアクションもあるため、利用する場合はこの点も考慮した上で利用してください。
アクション名 | 概要 |
|---|---|
AKS 用のKubernetes コンテキストを設定するアクション。内部の処理ではaz aks get-credentials で資格情報を取得しkubeconfig を作成している。Azure CLI が必要となるため、セルフホステッドランナーで利用する場合は事前にインストールが必要。 | |
AKS 以外のKubernetes (Azure VM やAzure Arc on Kubernetes など) の資格情報を設定するアクション。aks-set-context と違い、シークレットの値を直接指定してkubeconfig を設定する。Base64、サービスアカウント、サービスプリンシパルの3種類で設定可能。 | |
Helm チャート、Kustomize、Kompose のファイルをAKS 用のマニフェストに変換するアクション。アクション実行時に各種ツールをダウンロードするため、特定のバージョンを使いたい場合はバージョン指定を行う。マニフェストの変換のみとなるため、デプロイには別途デプロイ用のアクションかコマンドが必要。 | |
Kubernetes クラスター用の汎用またはDocker レジストリ用のシークレットを作成するアクション。ストレージアカウントの接続文字列やKey Vault のシークレットをコンテキストに設定したり、Docker レジストリのユーザー名、パスワードからDocker レジストリ用のシークレットも作成可能。内部的な処理はKubernetes のAPI を使いkubeconfig にシークレットを設定するため、azure/aks-set-context またはazure/k8s-set-context のようなアクションでコンテキストを設定していないとエラーになる。 | |
AKS にコンテナアプリケーションをデプロイするアクション。デプロイは基本的なkubectl apply を行うbasic に加え、カナリアデプロイ、ブルーグリーンデプロイも可能。カナリアデプロイ、ブルーグリーンデプロイを行う場合、切り替え用のロードバランサー、各種オプションの指定が必要。デプロイはマニフェストの適用に加え、マニフェスト内のイメージ置換も可能。private-cluster をtrue に指定すれば、プライベートクラスターへのデプロイも可能 (内部的にはaz aks invoke コマンドでデプロイを実行している) | |
Kubernetes のマニフェストに対し、kubectl のdry-run またはkubeconform を使い構文などの検証を実施するアクション。単一または複数のマニフェストを指定可能。内部的にはdry-run はkubectl apply コマンドにdry-run=server を指定して実行し、kubeconform は実行直前にGitHub 上からインストールし実行している。kubeconform はwith 句でオプションを指定でき、実行結果のダウンロードも可能。 | |
特定のバージョンのHelm をダウンロードしパスを設定するアクション。内部の処理ではInput で指定したHelm のバージョンをダウンロードし、actions/core のaddPath 関数でパスを設定する。GitHub ホステッドランナーに導入されているHelm のバージョンより最新のバージョンを使いたい、指定したバージョンを使いたい場合に使用する。 | |
特定のバージョンのkubectl をダウンロードしパスを設定するアクション。内部の処理ではInput で指定したkubectl のバージョンをダウンロードし、actions/core のaddPath 関数でパスを設定する。GitHub ホステッドランナーに導入されているkubectl のバージョンより最新のバージョンを使いたい、特定のバージョンを使いたい場合に使用する。 | |
Kubernetes マニフェスト内のコンテナイメージタグを一括で置換するアクション。単一または複数のマニフェストを指定可能。内部的にはforeach でマニフェスト内の指定したイメージタグをループして置換するため、特定の箇所だけイメージタグを更新することは不可。また、タグの置換をするだけのため、置換したタグのコンテナイメージが存在しなくても置換されるため注意。置換後のマニフェストのパスはoutput のmanifest に出力される。 | |
Terraform またはPulumi を実行してAKS クラスターを作成するアクション。ARM (Bicep) は利用できない。デフォルトではTerraform が指定されている。最初にsetup 用スクリプトでリソースグループ、ストレージアカウント、サービスプリンパルの作成が必要となる。tfstate ファイルがストレージアカウントに配置され変更できない。内部的にはDocker カスタムアクションで、「terraform init」→「terraform plan」「terraform apply」を実行している。dev かtest のフォルダにあるtf ファイルを実行している。事前にディレクトリを配置しCLUSTER_SIZE でフォルダ名を指定すれば、特定のディレクトリ内のテンプレートファイルを実行できる。 | |
Dockerfile からコンテナイメージを作成しAzure Container Registry に公開するアクション。Docker カスタムアクションを使い、コンテナ上でaz acr build コマンドを実行しACR に格納する。Azure へのログインやACR へアクセス、GitHub リポジトリ取得を行うため、サービスプリンシパルの情報とGitHub Apps のようなトークンが必要。ACR のタスク機能を使うため、サービスプリンシパルに対象ACR のContributor 権限またはタスク実行用の権限を設定したカスタムロールが必要となる。 |
今回の構成
今回は事前に作成したAzure Container Registry (以下ACR) にコンテナイメージを格納し、格納したコンテナイメージをAKS クラスターにデプロイするところまでを行います。本構成のフォルダ構成は以下となります。
.
├── .github
│ └── workflows
│ └── aks-build-and-deploy.yaml
├── Dockerfile
├── README.md
├── html
│ └── index.html
├── manifests
│ └── aks-demo.yaml
└── nginx
└── nginx.conf今回使うDockerfile とサンプルHTML ファイル、Nginx 設定ファイル、Kubernetes マニフェストは以下となります。
FROM nginx:alpine
HTML、Nginx設定ファイルを配置する
COPY html /usr/share/nginx/htmlCOPY nginx/nginx.conf /etc/nginx/nginx.conf
80番ポートで待ち受けする
EXPOSE 80
Nginxを起動する
CMD ["nginx", "-g", "daemon off;"]<!DOCTYPE html><html lang="ja"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Hello World</title></head><body> <h1>Hello World!</h1></body></html>user nginx;worker_processes auto;
events { worker_connections 1024; }
http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
}apiVersion: apps/v1kind: Deploymentmetadata: name: aks-demo namespace: default labels: app: aks-demospec: replicas: 2 selector: matchLabels: app: aks-demo template: metadata: labels: app: aks-demo spec: containers: - name: aks-demo image: acraksghatest.azurecr.io/repos/aks-demo:latest imagePullPolicy: Always ports: - containerPort: 80
apiVersion: v1kind: Servicemetadata: name: aks-demo-svcspec: type: LoadBalancer selector: app: aks-demo ports:
protocol: TCPport: 80targetPort: 80今回作成するGitHub Actions ワークフローの処理の流れは以下となります。
- コンテナイメージをビルドしACR に格納する (acr-build)
- AKS の資格情報を取得する (aks-set-context)
- Kubernetes マニフェストのイメージタグを書き換える (k8s-artifact-substitute)
- kubeconform、dry-run で動作に問題が無いか確認する (k8s-lint)
- AKS にKubernetes マニフェストをデプロイする (k8s-deploy)
GitHub Actions 用の各種リソースの作成
初めに、GitHub Actions でAKS およびACR 関連のタスクを実行するために必要なAzure リソースを作成します。
# 各種変数を定義するRESOURCE_GROUP_NAME="rg-aksghatest"CONTAINER_REGISTRY_NAME="acraksghatest"KUBERNETES_SERVICE_NAME="aks-aksghatest"SERVICE_PRINCIPAL_NAME="sp-aksghatest"LOCATION="japaneast"
リソースグループを作成する
az group create --name $RESOURCE_GROUP_NAME --location $LOCATION
ACRを作成する
ACR_ID=$(az acr create --resource-group $RESOURCE_GROUP_NAME --name $CONTAINER_REGISTRY_NAME --sku Basic --location $LOCATION --query id -o tsv)
AKSクラスターを作成する
ACRからイメージを取得するためAKS作成時にアタッチしAcrPull権限を付与する
AKS_ID=$(az aks create --resource-group $RESOURCE_GROUP_NAME --name $KUBERNETES_SERVICE_NAME --kubernetes-version 1.34.1 --node-count 1 --enable-cluster-autoscaler --min-count 1 --max-count 1 --node-vm-size Standard_D4s_v4 --nodepool-name nodepool1 --vm-set-type VirtualMachineScaleSets --generate-ssh-keys --attach-acr $CONTAINER_REGISTRY_NAME --query id -o tsv)リソース作成後、GitHub Actions で利用するサービスプリンシパルを作成します。今回はACR へのイメージ格納のためにACR の共同作成者とAKS デプロイのためにAKS 共同作成者を付与します。
# GitHub Actions用のサービスプリンシパルを作成する
appId、password、tenantの値が表示されるためメモする
SUBSCRIPTION_ID=$(az account show --query id -o tsv)RESOURCEGROUP_SCOPE="/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP_NAME}"az ad sp create-for-rbac --name "$SERVICE_PRINCIPAL_NAME" --role Reader --scopes "$RESOURCEGROUP_SCOPE" --query "{appId: appId, password: password, tenant: tenant}" -o jsonAPP_ID="<appIdで出力された値>"
ACR、AKSのリソースIDを取得する
CONTAINER_REGISTRY_SCOPE=$(az acr show --resource-group "$RESOURCE_GROUP_NAME" --name "$CONTAINER_REGISTRY_NAME" --query id -o tsv)
KUBERNETES_SERVICE_SCOPE=$(az aks show --resource-group "$RESOURCE_GROUP_NAME" --name "$KUBERNETES_SERVICE_NAME" --query id -o tsv)
コンテナイメージをACRにPull/Pushするための権限を付与する
ArcPushではACRのタスクを実行できないため、ACRを指定してContributor権限を付与する
az role assignment create --assignee "${APP_ID}" --role "Contributor" --scope "${CONTAINER_REGISTRY_SCOPE}"
AKSクラスターへデプロイするための権限を付与する
az role assignment create --assignee "${APP_ID}" --role "Azure Kubernetes Service Cluster User Role" --scope "${KUBERNETES_SERVICE_SCOPE}"デプロイ用のGitHub Actions ワークフローを作成
Azure リソース、リポジトリの準備後、GitHub Actions のワークフローを作成します。今回はコンテナイメージのビルド、Push とAKS へのデプロイでジョブを分割します。
name: Build and Deploy to AKS
on: workflow_dispatch: inputs: image_tag: description: 'Image tag' required: trueenv: AZURE_CREDENTIALS: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
jobs: image-build: name: Build and Push Docker Image to ACR runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v6
# コンテナイメージをビルドしACRに格納する
# Dockerカスタムアクション内でAzureのログインをするため事前のログインは不要
- name: Build and Push Docker Image to ACR
uses: azure/acr-build@v1
with:
service_principal: ${{ secrets.AZURE_CLIENT_ID }}
service_principal_password: ${{ secrets.AZURE_CLIENT_SECRET }}
tenant: ${{ secrets.AZURE_TENANT_ID }}
registry: "acraksghatest"
repository: "repos"
image: "aks-demo"
tag: ${{ github.event.inputs.image_tag }}
dockerfile: ./Dockerfile
git_access_token: ${{ secrets.GIT_ACCESS_TOKEN }}
folder: ./
branch: main
deploy: name: Deploy to AKS runs-on: ubuntu-latest needs: image-build env: RESOURCE_GROUP_NAME: 'rg-aksghatest' AKS_CLUSTER_NAME: 'aks-aksghatest' timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v6
# サービスプリンシパルを使いAzure にログインする
- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ env.AZURE_CREDENTIALS }}
# AKSの資格情報を取得する
- name: Set AKS context
uses: azure/aks-set-context@v4
with:
resource-group: ${{ env.RESOURCE_GROUP_NAME }}
cluster-name: ${{ env.AKS_CLUSTER_NAME }}
# Kubernetesマニフェストのタグを書き換える
- name: Update image tag in Kubernetes manifest
id: update-manifest
uses: Azure/k8s-artifact-substitute@v2
with:
manifests: |
manifests/aks-demo.yaml
images: |
acraksghatest.azurecr.io/repos/aks-demo:${{ github.event.inputs.image_tag }}
# 書き換え後のKubernetesマニフェストをチェックする
# azure/k8s-lintはkubeconformとdry-runを同時実行できないため分割する
- name: Check updated Kubernetes manifest with kubeconform
uses: azure/k8s-lint@v3
with:
lintType: kubeconform
manifests: |
${{ steps.update-manifest.outputs.manifests }}
kubeconformOpts: -summary
- name: Dry-run updated Kubernetes manifest
uses: azure/k8s-lint@v3
with:
lintType: dryrun
manifests: |
${{ steps.update-manifest.outputs.manifests }}
# AKSにデプロイする
- name: Deploy to AKS
uses: azure/k8s-deploy@v5
with:
resource-group: ${{ env.RESOURCE_GROUP_NAME }}
name: ${{ env.AKS_CLUSTER_NAME }}
action: deploy
strategy: basic
manifests: |
${{ steps.update-manifest.outputs.manifests }}</code></pre></div><p>Azure へログインするためのシークレットにつきましては、GitHub リポジトリのシークレットとして登録しています。各シークレットには以下の値を登録してください。また、今回はACR のビルドアクションを利用するため、GitHub Apps のトークンを作成しておいてください。</p><table><tbody><tr><th colspan="1" rowspan="1"><p>シークレット名</p></th><th colspan="1" rowspan="1"><p>値</p></th></tr><tr><td colspan="1" rowspan="1"><p>AZURE_CLIENT_ID</p></td><td colspan="1" rowspan="1"><p>サービスプリンシパルのappID の値</p></td></tr><tr><td colspan="1" rowspan="1"><p>AZURE_CLIENT_SECRET</p></td><td colspan="1" rowspan="1"><p>サービスプリンシパルのpassword の値</p></td></tr><tr><td colspan="1" rowspan="1"><p>AZURE_TENANT_ID</p></td><td colspan="1" rowspan="1"><p>サービスプリンシパルのtenant の値</p></td></tr><tr><td colspan="1" rowspan="1"><p>AZURE_SUBSCRIPTION_ID</p></td><td colspan="1" rowspan="1"><p>サブスクリプションのID</p></td></tr><tr><td colspan="1" rowspan="1"><p>GIT_ACCESS_TOKEN</p></td><td colspan="1" rowspan="1"><p>GitHub Apps のトークン</p></td></tr></tbody></table><p>もしコンテナイメージの取得やPod が正常に起動しない場合、以下の項目を確認してみてください。</p><ul><li>各種設定ファイルの内容を適切に設定できているか?</li><li>ACR をAKS にアタッチできているか?</li><li>ACR のサーバー名、リポジトリ名、タグが適切に設定できているか?</li></ul><h2 id="he1a8e657e8">動作検証</h2><p>デプロイ後、ServiceのIPアドレスでアクセスすると、デプロイしたHTML ファイルが表示されます。</p><figure><img src="https://images.microcms-assets.io/assets/a240beb4c23f4e25ab22fb3353815c7d/81b0e9e67bb945d18b2405fc76bedc80/aksgha1.webp" alt="" width="2906" height="1743"></figure><h2 id="h7edc5d3198">リソースのクリーンアップ</h2><p>AKS のコンテナイメージ作成からデプロイまで確認後、リソースが不要な方は検証で使ったリソースを削除します。</p><div data-filename="コマンド"><pre><code class="language-bash"># サービスプリンシパルを削除する
az ad sp delete --id $(az ad sp list --display-name "$SERVICE_PRINCIPAL_NAME" --query "[0].appId" -o tsv)
リソースグループを削除する
az group delete --name $RESOURCE_GROUP_NAME --yesまとめ
- GitHub Actions ではMicrosoft が提供するAzure Container Registry のビルドやAzure Kubernetes Service のデプロイに関するカスタムアクションが提供されている
- カスタムアクションを利用することで、GitHub Actions ワークフローの記述を簡素化できる
- az acr build はAzure Container Registry のタスク機能を利用しているため、AcrPull ではなくContributor 権限が必要となる
- AKS のデプロイアクションでは、基本的なkubectl apply だけでなくカナリアやブルーグリーンといったデプロイもできる
