Azure Container Appsの従量課金ワークロード プロファイルをbicepでプロビジョニング

最近は今後の開発作業を効率的に進めるために、CI/CD/IaC用の基盤(サンプル?)的なものを作ったしてます。今までやりたいなと思っていても、様々な理由で取り組めていなかったことも色々盛り込んでいるので、諸々知見が溜まってきました。今回は、その中からContainer Appsを取り上げようと思います。

Container Appsの実行環境

Container Appsは元々従量課金プランのみでの提供でしたが、2023年8月dedicated plan(専用プラン)がGAしました。

従来の従量課金プランでは、CPU/Memoryの組み合わせで最小 0.25 / 0.5Gi から 最大 2vCPU / 4.0Giのサイズが用意されていましたが、dedicated planでは、従来の従量課金プランとよく似た、"従量課金ワークロード プロファイル"が用意されておりこちらでは 最大 4vCPU / 8Gi まで拡張されていいます。

また、必要に応じて専用ワークロードプロファイルを追加することで、専用のハードウェア上でContainer Appを実行することができるようになりました。参考

今回は、この新しいdedicated planに対応したContainer App Environmentをbicepでプロビジョニングする方法を調査した結果をまとめようと思います。

dedicated plan環境の作成

dedicated plan版のContainer Apps Environmentを作成するには以下のようなbicepファイルを用意します

param logAnalyticsWorkspaceName string = 'example-log'
param appInsightsName string = 'example-app-insights'
param environmentName string = 'example-container-apps-env-test'

param location string = resourceGroup().location

// Create a Log Analytics workspace
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
  name: logAnalyticsWorkspaceName
  location: location
  properties: any({
    retentionInDays: 30
    features: {
      searchVersion: 1
      legacy: 0
      enableLogAccessUsingOnlyResourcePermissions: true
    }
    sku: {
      name: 'PerGB2018'
    }
  })
}

// Create an Application Insights resource
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: appInsightsName
  location: location
  kind: 'web'
  properties: { 
    Application_Type: 'web'
    WorkspaceResourceId:logAnalyticsWorkspace.id
  }
}

// Create a managed environment
resource environment 'Microsoft.App/managedEnvironments@2023-05-01' = {
  name: environmentName
  location: location
  properties: {
    appLogsConfiguration: {
      destination: 'log-analytics'
      logAnalyticsConfiguration: {
        customerId: logAnalyticsWorkspace.properties.customerId
        sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
      }
    }
    daprAIInstrumentationKey: appInsights.properties.InstrumentationKey
    zoneRedundant: false
    peerAuthentication: {
      mtls: {
        enabled: false
      }
    }
    workloadProfiles: [{
      name: 'Consumption'
      workloadProfileType: 'Consumption'
    }]
  }
}

今回の肝になるのは、以下の部分です

...
    workloadProfiles: [{
      name: 'Consumption'
      workloadProfileType: 'Consumption'
    }]
...

追加された workloadProfiles プロパティを指定することで、"従量課金ワークロード プロファイル"を作成することができます。また、ここに以下のように独自のワークロードを定義することで、専用サーバー上にアプリを配置することができるようになります。

    {
      name: 'myworkload'
      maximumCount: 10
      minimumCount: 3
      workloadProfileType: 'D4'
    }

現時点で指定可能なworkloadProfileTypeは以下に記載があります

Azure Container Apps のワークロード プロファイル - プロファイルの種類

(minimumCount は可用性を保証するために3以上を指定することが推奨されています)

プロビジョニング

以下のコマンドでプロビジョンングすることができます

$ export RESOURCE_GROUP=[リソースグループ名]
$ az deployment group create \
    --resource-group $RESOURCE_GROUP \
    --template-file bicep/container-apps-env.bicep

正常に処理が完了すると、以下のようにportalでも設定を確認することができます

dedicated plan環境にアプリをデプロイ

dedicated plan版のContainer Apps Environmentにアプリをデプロイするには以下のようなbicepファイルを用意します

param location string = resourceGroup().location
param environmentName string = 'example-container-apps-env-test'
param containerAppName string = 'example-app'

@allowed([
  'multiple'
  'single'
])
param revisionMode string = 'single'

resource environment 'Microsoft.App/managedEnvironments@2023-05-01' existing = {
  name: environmentName
}

resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
  name: containerAppName
  location: location
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    workloadProfileName: 'Consumption'
    managedEnvironmentId: environment.id
    configuration: {
      activeRevisionsMode: revisionMode
      dapr:{
        enabled:false
      }
      ingress: {
        external: true
        targetPort: 80
        transport: 'auto'
        allowInsecure: false
        traffic: [
          {
            weight: 100
            latestRevision: true
          }
        ]
      }
    }
    template: {
      containers: [
        {
          image: 'nginx:latest'
          name: containerAppName
          resources: {
            cpu: any('4.0')
            memory: '8Gi'
          }
        }
      ]
      scale: {
        minReplicas: 0
        maxReplicas: 10
        rules: [
          {
            name: 'http-scaling-rule'
            http: {
              metadata: {
                concurrentRequests: '10'
              }
            }
          }
        ]
      }
    }
  }
}

output fqdn string = containerApp.properties.configuration.ingress.fqdn

従来の従量課金プランと異なるのは、プロパティの以下の部分です

...
  properties: {
    workloadProfileName: 'Consumption'
...

workloadProfileName にワークロードプロファイル名を指定することで、実行環境を指定することができます。

デプロイ

以下のコマンでデプロイできます

$ az deployment group create \
      --resource-group $RESOURCE_GROUP \
      --template-file bicep/app.bicep

無事作成が完了すると、portalでも以下のように設定内容を確認することができます

おまけ

先日まで存在を知らなかったのですが、az deployment group には what-if というコマンドが存在します。このコマンドを利用することで、bicepファイルと実際のリソースの差分を表示することができます

例えば、上記アプリのCPU / メモリを以下のように修正します

...
          resources: {
            cpu: any('2.0')
            memory: '4Gi'
          }
...

この状態で下記のコマンドを実行すると、以下のように差分が表示されます

$ az deployment group what-if \
      --resource-group $RESOURCE_GROUP \
      --template-file bicep/app.bicep

Note: The result may contain false positive predictions (noise).
You can help us improve the accuracy of the result by opening an issue here: https://aka.ms/WhatIfIssues

Resource and property changes are indicated with these symbols:
  - Delete
  ~ Modify
  * Ignore

The deployment will update the following scope:

Scope: /subscriptions/ac25fc44-3b4d-4b2f-917e-672509e414ca/resourceGroups/kaz29-key-vault-test-rg

  ~ Microsoft.App/containerApps/example-app [2023-05-01]
    - properties.configuration.ingress.exposedPort: 0
    - properties.runningStatus:                     "Running"
    ~ properties.template.containers: [
      ~ 0:

        ~ resources.cpu:    4.0 => 2.0
        ~ resources.memory: "8Gi" => "4Gi"

      ]

  * Microsoft.App/managedEnvironments/example-container-apps-env-test
  * Microsoft.Insights/components/example-app-insights
  * Microsoft.OperationalInsights/workspaces/example-log
  * microsoft.alertsmanagement/smartDetectorAlertRules/Failure Anomalies - example-app-insights

この機能を使えば、stateを持たないbicepでもIaC的なことを比較的安心に組めそうです。 例えば、PR作成時にdiffを取って自動で差分をPRコメントに投稿するようにすれば、bicepファイルの変更と実際の差分を確認して安心してレビューができそうです

まとめ

いかがでしたか、dedicated planプランを利用すると従量課金ワークロード プロファイルでも、以前より豊富なリソースサイズの中からアプリの特性に合わせたものを選択できるようになりますし、専用ワークロードプロファイルを作ればさらに自由度が高い環境を構築することもできます。

Container Appsはとても便利なので、ぜひ試してみてください。

参考リンク