3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Bicep編】App ServiceのManaged IDを使ってACRからコンテナイメージをpullする

Posted at

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 .
  • Azure PortalからリポジトリにイメージがPushされていることを確認します。
    image.png

稼働確認

  • App Serviceを再起動し、WebブラウザからURLにアクセスします。以下の画面が表示されればOKです。
    image.png

  • ACRのIAMを見てみると、[AcrPull]ロールがこのリソースのみに割当たっていることが分かります。
    image.png

以上です

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?