APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Azure Container AppsでCI/CD(GitHub Actions編)

はじめに

こんにちは、ACS事業部の吉川です。
Azure Container Appsが5月の終わりにGAされ、早くも3か月ほどが経過しました。

techblog.ap-com.co.jp

利用検討する方も増えてきているかと思いますので、本ブログでもいろいろな使い方をご紹介できればと考えています。
過去には以下のような記事も投稿されています。

techblog.ap-com.co.jp

techblog.ap-com.co.jp

techblog.ap-com.co.jp

今回はGitHub Actionsを用いたCI/CDについて解説します。

構成

以下の構成を例として解説を行います。

GitHub ActionsでコンテナイメージをビルドしACRへ格納し、そのイメージをContainer Appsへデプロイします。

このGitHub ActionsはポータルのContainer Apps 継続的デプロイ から簡単に設定することもできるのですが、自分で手を動かしたほうが理解が深まりますし細かなところも設定を変えることができます。
ということで、本記事では 継続的デプロイ の画面は使わず、一つ一つ手で設定していきます。

リソースの作成

まずは必要なリソースを作成していきましょう。
ここではWSL2のUbuntuでAzure CLIを用いて作成していきます。

まずはリソースグループとAzure Container Registry(ACR)を作成します。

# リソース名とリージョンの定義
rgName=rg-sample
acrName=acrsample
location=japaneast

# リソースグループ作成
az group create --location $location --name $rgName

# ACR作成
az acr create --name $acrName -g $rgName -l $location --sku Basic

次にContainer Appsを作成していきますが、まずは Container Apps環境 を作成する必要があります。

# リソース名の定義
caeName=cae-sample

# Container Apps環境作成
az containerapp env create --name $caeName -g $rgName -l $location

Container Apps環境ができあがったらContainer Appsを作成します。
Container Apps作成時に --registry-identity および --registry-server オプションを付与することで、マネージドIDを利用してACRからイメージをPullできるように設定してくれます。

# リソース名の定義
acaName=aca-sample

# Container Apps作成
az containerapp create -n $acaName -g $rgName \
  --environment $caeName \
  --ingress external \
  --target-port 80 \
  --registry-identity system \
  --registry-server ${acrName}.azurecr.io

上記のコマンドでContainer Appsを作成すると、以下のようなサンプル用コンテナが起動した状態となります。

GitHubの準備

土台となる環境が整ったので、GitHub側の準備をします。

GitHub Actionsで使用するサービスプリンシパルを作成します。
今回はGitHub ActionsからのAzureの認証にOpenID Connectを利用します。

# アプリケーションの登録
appId=$(az ad app create --display-name sp-for-githubactions --query appId -o tsv)

# サービスプリンシパルの作成
spObjectId=$(az ad sp create --id $appId --query id -o tsv)

作成したサービスプリンシパルに必要なロールを割り当てます。
今回必要となるのはACRへのPushとContainer Appsへのデプロイのためのロールです。

# ACRのACRPushロールを割り当て
acrId=$(az acr show -n $acrName --query id -o tsv)
az role assignment create --role ACRPush --assignee $spObjectId --scope $acrId

# Container Appsの共同作成者ロールを割り当て
acaId=$(az containerapp show -n $acaName -g $rgName --query id -o tsv)
az role assignment create --role Contributor --assignee $spObjectId --scope $acaId

OpenID Connectのフェデレーション資格情報を作成します。
以下のようなJSONファイルを credential.json という名前で保存し、

{
    "name": "github_federation_for_container_apps",
    "issuer": "https://token.actions.githubusercontent.com",
    "subject": "repo:<GitHubのユーザー名 or Org名>/<リポジトリ名>:ref:refs/heads/main",
    "audiences": [
        "api://AzureADTokenExchange"
    ]
}

以下のコマンドで設定します。

az ad app federated-credential create --id $appId --parameters credential.json

次にGitHubのSecretsにサービスプリンシパルの情報を登録します。以下の3つを登録しましょう。
登録する値は 確認コマンド 欄に記載のコマンドを実行することで確認できます。

名前 確認コマンド
AZURE_CLIENT_ID echo $appId
AZURE_TENANT_ID az account show --query tenantId -o tsv
AZURE_SUBSCRIPTION_ID az account show --query id -o tsv

次にリポジトリ内のファイルですが、以下のようなディレクトリ構成とします。

├── .github
│   └── workflows
│       └── build_and_deploy.yaml
└── Dockerfile

ワークフローファイルは以下のとおりです。
Container Appsの継続的デプロイ機能で生成されるものから、OpenID Connectの利用など一部改変しています。

name: Trigger auto deployment for aca-sample

# When this action will be executed
on:
  # Automatically trigger it when detected changes in repo
  push:
    branches: 
      [ main ]

  # Allow mannually trigger 
  workflow_dispatch:      

permissions:
  id-token: write
  contents: read

env:
  AZURE_CONTAINER_REGISTRY: acrsample
  CONTAINER_NAME: sampleapp
  CONTAINER_APP_NAME: aca-sample
  RESOURCE_GROUP: rg-sample

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout to the branch
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Azure 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: Log in to container registry
        id: acrtoken
        uses: azure/CLI@v1
        with:
          inlineScript: |
            accessToken=$(az acr login -n ${{ env.AZURE_CONTAINER_REGISTRY }} --expose-token --query accessToken -o tsv)
            echo ::set-output name=token::$accessToken
      - name: Login to ACR
        uses: docker/login-action@v2
        with:
          registry: ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io
          username: 00000000-0000-0000-0000-000000000000
          password: ${{ steps.acrtoken.outputs.token }}

      - name: Build and push container image to registry
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }}
          file: ./Dockerfile
          context: ./

  deploy:
    runs-on: ubuntu-latest
    needs: build
    
    steps:
      - name: Azure 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: Deploy to containerapp
        uses: azure/CLI@v1
        with:
          inlineScript: |
            az config set extension.use_dynamic_install=yes_without_prompt
            az containerapp update -n ${{ env.CONTAINER_APP_NAME }} -g ${{ env.RESOURCE_GROUP }} --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }}

GitHub Actionsの起動

前項までの設定で、mainブランチに対するPushをトリガーにGitHub Actionsが動くようになりました。
Dockerfileをリポジトリ配下に配置してPushしてみましょう。
テストということでnginxのPodを利用します。

FROM nginx:latest

これをPushするとGitHub Actionsが起動し、

ビルドされたコンテナイメージがACRに格納され、

Container Appsがnginxに切り替わります。

おわりに

Azure Container Appsの理解を深めるために、簡単なワークフローを作成し動かしてみました。
コンテナイメージをビルドしパッと起動するだけであれば、AKSと比べてかなり楽な印象です。
「Kubernetesはとっつき辛い!」と感じている方も多いと思いますが、ぜひ一度Container Appsをご検討いただければと思います。

Container Appsネタはしばらく続けていこうと思います。お楽しみに!

本記事の投稿者: 吉川 俊甫
AKSをメインにインフラ系のご支援を担当しています。AKS以外のコンテナもぼちぼち触っていきます。
Shunsuke Yoshikawa - Credly