Azure Container Registryへのアクセスは、アクセスキーを使うのではなくManaged IDを使った方がセキュアな構成をとることができます。
以前 Web App for Containers vNet統合経由でプライベートエンドポイント先のACRからイメージPullする という記事を書いて、Portalからポチポチ設定するやり方はまとめていたのですが、今回はBicepで実現する方法を残します。
なお、プライベートエンドポイントとvNet統合のコードは割愛しています。
リポジトリ構成
- 以下のようにモジュール化、パラメータ化しています。
.
├── main.bicep
├── main.bicepparam
└── modules
├── acr.bicep
└── appservice.bicep
Bicepコード
- 全てモジュールを呼び出すようにしています。App Service Managed IDのService Principal IDをACRモジュールに渡しています。
main.bicep
param location string
// App Service Parameters
param webAppName string
param appServicePlanSku string
param appServicePlanTier string
param appServicePlanName string
param imageRepositoryName string
// ACR Parameters
param acrName string
param acrSku string
module acrModule 'modules/acr.bicep' = {
name: 'acrModule'
params: {
location: location
acrName: acrName
acrSku: acrSku
webAppPrincipalId: appServiceModule.outputs.webAppPrincipalId
}
}
module appServiceModule './modules/appservice.bicep' = {
name: 'appServiceModule'
params: {
location: location
webAppName: webAppName
appServicePlanName: appServicePlanName
appServicePlanSku: appServicePlanSku
appServicePlanTier: appServicePlanTier
imageRepositoryName: imageRepositoryName
}
}
- パラメータは適宜置き換えます。
main.bicepparam
using 'main.bicep'
param location = 'japaneast'
// App Service Parameters
param webAppName = '[Your WebAppName]'
param appServicePlanSku = 'B1'
param appServicePlanTier = 'Basic'
param appServicePlanName = '${webAppName}-plan'
param imageRepositoryName = '${acrName}.azurecr.io/test/nginx:v1'
// ACR Parameters
param acrName = '[Your ACR Name]'
param acrSku = 'Basic'
- App Service Managed IDに[AcrPull]権限を与えているのがポイントです。roleDefinitionsのnameは、Azureサブスクリプション共通のカスタムロールIDなので固定値となります。
acr.bicep
param location string
param acrName string
param acrSku string
param webAppPrincipalId string
resource acrResource 'Microsoft.ContainerRegistry/registries@2023-06-01-preview' = {
location: location
name: acrName
sku: {
name: acrSku
}
properties: {
adminUserEnabled: false
publicNetworkAccess: 'Enabled'
}
}
resource acrPullRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-05-01-preview' existing = {
scope: acrResource
name: '7f951dda-4ed3-4680-a7ca-43fe172d538d'
}
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(acrResource.id, webAppPrincipalId, acrPullRoleDefinition.id)
scope: acrResource
properties: {
principalId: webAppPrincipalId
roleDefinitionId: acrPullRoleDefinition.id
principalType: 'ServicePrincipal'
}
}
- acrUseManagedIdentityCreds=trueの設定を忘れずに。
appservice.bicep
param location string
param webAppName string
param appServicePlanSku string
param appServicePlanTier string
param appServicePlanName string
param imageRepositoryName string
resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = {
name: appServicePlanName
location: location
kind: 'linux'
properties: {
reserved: true
}
sku: {
name: appServicePlanSku
tier: appServicePlanTier
}
}
resource webApp 'Microsoft.Web/sites@2022-09-01' = {
name: webAppName
location: location
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
publicNetworkAccess: 'Enabled'
siteConfig: {
appSettings: []
linuxFxVersion: 'DOCKER|${imageRepositoryName}'
acrUseManagedIdentityCreds: true
vnetRouteAllEnabled: true
http20Enabled: true
ftpsState: 'Disabled'
}
}
identity: {
type: 'SystemAssigned'
}
}
output webAppPrincipalId string = webApp.identity.principalId
デプロイ
- 以下のようにデプロイします。リソースグループは事前に作成済みであること前提です。
az login
az account list --output table --all
az account set --subscription [Subscrption ID]
az deployment group what-if --resource-group [Your ResourceGroup Name] --template-file main.bicep --parameters main.bicepparam
az deployment group create --resource-group [Your ResourceGroup Name] --template-file main.bicep --parameters main.bicepparam
サンプルアプリケーション準備
- サンプルアプリをACRにPushします。az acr buildであれば、ACRのアクセスキーが無効でもpushできます。
echo '<h1>ACR Test v1</h1>' > index.html
echo 'FROM nginx:latest' > Dockerfile
echo 'COPY index.html /usr/share/nginx/html' >> Dockerfile
az login
az account list --output table --all
az account set --subscription [Subscrption ID]
az acr build --registry [Container Registry Name] --image test/nginx:v1 --file Dockerfile .
稼働確認
以上です