概要
主に下記を参考にして実装を行った。
Azure Container Apps で最初のコンテナ化された関数を作成する
Bicep解説動画
Azure Container Appsへbicep,Azure Container Registry,GitHub Actionsを使ってデプロイ
環境
ユーザはサブスクリプションの管理者として行う。
lib | version |
---|---|
azure-cli | 2.61.0 |
Bicep CLI | 0.28.1 (ba1e9f8c1e) |
ハンズオン
デプロイ対象のAzure Functionsを作成
お試し用の環境作成
func init --worker-runtime node --language typescript --docker
FROM mcr.microsoft.com/azure-functions/node:4-node18
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
COPY . /home/site/wwwroot
RUN cd /home/site/wwwroot && \
npm install && \
npm run build
Helloを返すAPIを作るAzure Functionsのコード作成。
func new --name HttpExample --template "HTTP trigger"
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
export async function HttpExample(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
context.log(`Http function processed request for url "${request.url}"`);
const name = request.query.get('name') || await request.text() || 'world';
const test = process.env.TEST_ENV || 'default';
return { body: `Hello v1.0.0, ${name}! ${test}` };
};
app.http('HttpExample', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: HttpExample
});
ACRを作成
@minLength(5)
@maxLength(50)
param acrName string = 'acr${uniqueString(resourceGroup().id)}'
param location string = resourceGroup().location
param acrSku string = 'Basic'
resource acrResource 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = {
name: acrName
location: location
sku: {
name: acrSku
}
properties: {
adminUserEnabled: false
}
}
output loginServer string = acrResource.properties.loginServer
targetScope='subscription'
param resourceGroupName string
param resourceGroupLocation string
resource newRG 'Microsoft.Resources/resourceGroups@2024-03-01' = {
name: resourceGroupName
location: resourceGroupLocation
}
#!/bin/bash
BIN_DIR=$(cd $(dirname $0) && pwd)
BICEP_DIR=$(cd $BIN_DIR/../biceps && pwd)
RESOURCE_GROUP_NAME='bicep-test-rg'
LOCATION=japaneast
cd $BICEP_DIR && az deployment sub create \
--name careteTestContainerResourceGroup \
--location $LOCATION \
--template-file resourceGroup.bicep \
--parameters resourceGroupName=$RESOURCE_GROUP_NAME resourceGroupLocation=$LOCATION
cd $BICEP_DIR && az deployment group create \
--name careteTestACR \
--template-file acr.bicep \
-g $RESOURCE_GROUP_NAME
acrhogehoge.azurecr.io
が作成されたとする。
Dockerのイメージを作成
ここでは公式手順の<DOCKER_ID>
と<LOGIN_SERVER>
に同じ値を入れるものとする。
<LOGIN_SERVER>
= acrhogehoge.azurecr.io
とする。
イメージ名はazurefunctionshogeimage
タグ名はv1.0.0
とする。
ビルド対象はカレントディレクトリ.
とする。
docker build --tag acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0 .
ビルドが成功したら動作確認を行う。
docker run -p 8080:80 -it acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0
Helloが返ってくればOK。
ACRにImageをPush
まずはACRにログイン
az acr login --name acrhogehoge
タグを作成。<DOCKER_ID>
と<LOGIN_SERVER>
に同じ値を入れたので一見冗長に見える。
docker tag acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0 acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0
docker push acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0
サービスプリンシパルの作成
作成したACRのPULL権限を持ったサービスプリンシパルを作成する。(参考)
これは、これから作成するContainerAppsではACRからイメージをPULLする必要があるからである。
サービスプリンシパルの意味があいまいだったのでもう多分怖くないサービスプリンシパルを確認した。
この設定を怠って下記のエラーでBicepがしばらく作れなかった。
{"status":"Failed","error":{"code":"DeploymentFailed","target":"/subscriptions/0000-0000-0000-9e21-hogehoge/resourceGroups/bicep-test-rg/providers/Microsoft.Resources/deployments/hogehoge","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details.","details":[{"code":"InvalidParameterValueInContainerTemplate","message":"The following field(s) are either invalid or missing. Field 'template.containers.test-container-app-1.image' is invalid with details: 'Invalid value: "acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0": GET https:?scope=repository%3Aazurefunctionsimage%3Apull&service=acrhogehoge.azurecr.io: UNAUTHORIZED: authentication required, visit https://aka.ms/acr/authorization for more information.';."}]}
#!/bin/bash
ACR_NAME="acrhogehoge"
ACR_ID=$(az acr show --name $ACR_NAME --query id --output tsv)
SERVICE_PRINCIPAL_NAME=$ACR_NAME-pull
PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME --scopes $ACR_ID --role acrpull --query "password" --output tsv)
USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].appId" --output tsv)
echo "Service principal ID: $USER_NAME"
echo "Service principal password: $PASSWORD"
下記が表示されたとして以降は進めていく。
Service principal ID: hogeSPID
Service principal password: hogeSPPASS
App Container Appsの作成
ログアナリティクスとコンテナ環境とコンテナアプリを作成。
param location string = resourceGroup().location
param environmentName string
param containerAppName string
param containerName string
param logAnalyticsWorkspaceName string
param acrName string
param spPass string
param spId string
param imgTag string
// Log Analytics ワークスペース
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: logAnalyticsWorkspaceName
location: location
properties: {
sku: {
name: 'PerGB2018'
}
retentionInDays: 30
}
}
// Container Apps 環境
resource environment 'Microsoft.App/managedEnvironments@2023-11-02-preview' = {
name: environmentName
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logAnalytics.properties.customerId
sharedKey: logAnalytics.listKeys().primarySharedKey
}
}
workloadProfiles: [
{
name: 'Consumption'
workloadProfileType: 'Consumption'
}
]
}
}
param registryPassName string = 'registry-password'
// コンテナアプリ
resource name_resource 'Microsoft.App/containerapps@2023-11-02-preview' = {
name: containerName
location: location
properties: {
environmentId: environment.id
configuration:{
ingress: {
external:true
allowInsecure: false
targetPort: 80
traffic:[{
latestRevision:true
weight:100
}]
}
secrets:[{
name: registryPassName
value: spPass
}]
registries: [
{
server: '${acrName}.azurecr.io'
username: spId
passwordSecretRef: registryPassName
}
]
}
template: {
containers: [
{
name: containerAppName
image: 'acrv623i6lefoy6c.azurecr.io/azurefunctionsimage:${imgTag}'
resources: {
cpu:json('0.25')
memory: '.5Gi'
}
}
]
scale: {
minReplicas: 0
maxReplicas: 1
}
}
workloadProfileName: 'Consumption'
}
}
Service principalの hogeSPID
とhogeSPPASS
はここで使用する。
下記のように実行。
#!/bin/bash
BIN_DIR=$(cd $(dirname $0) && pwd)
BICEP_DIR=$(cd $BIN_DIR/../biceps && pwd)
RESOURCE_GROUP_NAME='bicep-test-rg'
LOCATION=japaneast
cd $BICEP_DIR && az deployment group create \
--name careteTestAppContainer \
--template-file containerApps.bicep \
--parameters environmentName=test-container-env-1 containerAppName=test-container-app-1 containerName=test-container-1 logAnalyticsWorkspaceName=test-log-analytics-1 acrName=acrhogehoge spPass=hogeSPPASS spId=hogeSPID imgTag=v1.0.0 \
-g $RESOURCE_GROUP_NAME
デプロイされたことを確認した。
この次のステップはパイプラインからのデプロイ
更新
- ACRのイメージをタグ名も何も変えずに更新すると、ContainerAppsを再度デプロイしなくても更新される。
docker build --tag acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0 .
docker push acrhogehoge.azurecr.io/azurefunctionshogeimage:v1.0.0
- タグ名を更新したときはbicepもそれに合わせて直してデプロイする必要がある。
上記の手順をおこなった後、createContainerApps.bash
を再実行
Log Analyticsの警告が表示されて調べたメモ
よくある質問で回答されているが、廃止させるのは「エージェント」であり、「ワークスペース」は廃止されない。心配は不要であった。
参考
クイック スタート: Bicep ファイルを使用したコンテナー レジストリの作成
bicep定義
WSL2 に Docker をインストールする ... 古い。
WSL2 でビルドした Docker イメージを Azure Container Registry へ push する
bicep - appcontainer
bicep - loganalytics - Microsoft.OperationalInsights
Log Analytics sku
Bicep解説動画
リソースの視覚化
もう多分怖くないサービスプリンシパル
Azure Container Appsへbicep,Azure Container Registry,GitHub Actionsを使ってデプロイ