クイック スタート: ストレージ持ち込みでの Azure マネージド アプリケーション定義の作成と発行

このクイック スタートでは、Azure マネージド アプリケーション用のストレージ持ち込み (BYOS) の概要について説明します。 組織のメンバーを対象としたマネージド アプリケーション定義を作成してサービス カタログに発行します。 独自のストレージ アカウントを使用する場合、マネージド アプリケーション定義がサービス カタログの 120 MB の制限を超えることがあります。

サービス カタログにマネージド アプリケーション定義を発行するには、次の操作を行う必要があります。

  • マネージド アプリケーションによってデプロイされる Azure リソースを定義する Azure Resource Manager テンプレート (ARM テンプレート) を作成します。
  • マネージド アプリケーションをデプロイするときに、ポータルのユーザー インターフェイス要素を定義する。
  • 必要な JSON ファイルを含む .zip パッケージを作成します。
  • マネージド アプリケーション定義を保存するストレージ アカウントを作成します。
  • マネージド アプリケーション定義を独自のストレージ アカウントにデプロイして、サービス カタログで使用できるようにします。

マネージド アプリケーション定義が 120 MB 未満で、独自のストレージ アカウントを使用しない場合は、「クイック スタート: Azure マネージド アプリケーションの定義を作成および発行する」を参照してください。

Bicep を使用してマネージド アプリケーション定義を開発できますが、Azure で定義を発行する前に ARM テンプレートの JSON に変換する必要があります。 詳細については、Bicep を使用した Azure マネージド アプリケーション定義の作成と発行に関するクイックスタートを参照してください。

Bicep を使用して、サービス カタログからマネージド アプリケーション定義をデプロイすることもできます。 詳細については、Bicep を使用した Azure マネージド アプリケーション定義のデプロイに関するクイックスタートを参照してください。

前提条件

このクイックスタートを実行するには、次のものが必要です。

ARM テンプレートを作成する

各マネージ アプリケーション定義には、mainTemplate.json というファイルが含まれています。 このテンプレートは、デプロイする Azure リソースを定義し、通常の ARM テンプレートと同じ方法で定義します。

Visual Studio Code を開き、大文字と小文字を区別する名前 mainTemplate.json のファイルを作成して保存します。

次の JSON を追加し、ファイルを保存します。 それにより、App Service、App Service プラン、ストレージ アカウントをデプロイするためのマネージド アプリケーションのリソースを定義します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "appServicePlanName": {
      "type": "string",
      "maxLength": 40,
      "metadata": {
        "description": "App Service plan name."
      }
    },
    "appServiceNamePrefix": {
      "type": "string",
      "maxLength": 47,
      "metadata": {
        "description": "App Service name prefix."
      }
    },
    "storageAccountNamePrefix": {
      "type": "string",
      "maxLength": 11,
      "metadata": {
        "description": "Storage account name prefix."
      }
    },
    "storageAccountType": {
      "type": "string",
      "allowedValues": [
        "Premium_LRS",
        "Standard_LRS",
        "Standard_GRS"
      ],
      "metadata": {
        "description": "Storage account type allowed values"
      }
    }
  },
  "variables": {
    "appServicePlanSku": "F1",
    "appServicePlanCapacity": 1,
    "appServiceName": "[format('{0}{1}', parameters('appServiceNamePrefix'), uniqueString(resourceGroup().id))]",
    "storageAccountName": "[format('{0}{1}', parameters('storageAccountNamePrefix'), uniqueString(resourceGroup().id))]"
  },
  "resources": [
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2022-03-01",
      "name": "[parameters('appServicePlanName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[variables('appServicePlanSku')]",
        "capacity": "[variables('appServicePlanCapacity')]"
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2022-03-01",
      "name": "[variables('appServiceName')]",
      "location": "[parameters('location')]",
      "properties": {
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
        "httpsOnly": true,
        "siteConfig": {
          "appSettings": [
            {
              "name": "AppServiceStorageConnectionString",
              "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};Key={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2022-09-01').keys[0].value)]"
            }
          ]
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
      ]
    },
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[variables('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[parameters('storageAccountType')]"
      },
      "kind": "StorageV2",
      "properties": {
        "accessTier": "Hot"
      }
    }
  ],
  "outputs": {
    "appServicePlan": {
      "type": "string",
      "value": "[parameters('appServicePlanName')]"
    },
    "appServiceApp": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Web/sites', variables('appServiceName')), '2022-03-01').defaultHostName]"
    },
    "storageAccount": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2022-09-01').primaryEndpoints.blob]"
    }
  }
}

ポータル エクスペリエンスを定義する

マネージド アプリケーションを作成するためのポータル エクスペリエンスは、発行者が定義します。 ポータルのユーザー インターフェイスは、createUiDefinition.json ファイルによって生成されます。 ドロップダウンやテキスト ボックスなどのコントロール要素を使用して、各パラメーターの入力をユーザーがどのように提供するかを定義します。

この例では、ユーザー インターフェイスから、App Service の名前のプレフィックス、App Service プランの名前、ストレージ アカウントのプレフィックス、ストレージ アカウントの種類を入力するよう求められます。 デプロイ中、mainTemplate.json 内の変数で uniqueString 関数を使用して、名前のプレフィックスに 13 文字の文字列を追加し、名前が Azure 全体でグローバルに一意になるようにします。

Visual Studio Code を開き、大文字と小文字を区別する名前 createUiDefinition.json のファイルを作成して保存します。

次の JSON コードをファイルに追加し、保存します。

{
  "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
  "handler": "Microsoft.Azure.CreateUIDef",
  "version": "0.1.2-preview",
  "parameters": {
    "basics": [
      {}
    ],
    "steps": [
      {
        "name": "webAppSettings",
        "label": "Web App settings",
        "subLabel": {
          "preValidation": "Configure the web app settings",
          "postValidation": "Completed"
        },
        "elements": [
          {
            "name": "appServicePlanName",
            "type": "Microsoft.Common.TextBox",
            "label": "App Service plan name",
            "placeholder": "App Service plan name",
            "defaultValue": "",
            "toolTip": "Use alphanumeric characters or hyphens with a maximum of 40 characters.",
            "constraints": {
              "required": true,
              "regex": "^[a-z0-9A-Z-]{1,40}$",
              "validationMessage": "Only alphanumeric characters or hyphens are allowed, with a maximum of 40 characters."
            },
            "visible": true
          },
          {
            "name": "appServiceName",
            "type": "Microsoft.Common.TextBox",
            "label": "App Service name prefix",
            "placeholder": "App Service name prefix",
            "defaultValue": "",
            "toolTip": "Use alphanumeric characters or hyphens with minimum of 2 characters and maximum of 47 characters.",
            "constraints": {
              "required": true,
              "regex": "^[a-z0-9A-Z-]{2,47}$",
              "validationMessage": "Only alphanumeric characters or hyphens are allowed, with a minimum of 2 characters and maximum of 47 characters."
            },
            "visible": true
          }
        ]
      },
      {
        "name": "storageConfig",
        "label": "Storage settings",
        "subLabel": {
          "preValidation": "Configure the storage settings",
          "postValidation": "Completed"
        },
        "elements": [
          {
            "name": "storageAccounts",
            "type": "Microsoft.Storage.MultiStorageAccountCombo",
            "label": {
              "prefix": "Storage account name prefix",
              "type": "Storage account type"
            },
            "toolTip": {
              "prefix": "Enter maximum of 11 lowercase letters or numbers.",
              "type": "Available choices are Standard_LRS, Standard_GRS, and Premium_LRS."
            },
            "defaultValue": {
              "type": "Standard_LRS"
            },
            "constraints": {
              "allowedTypes": [
                "Premium_LRS",
                "Standard_LRS",
                "Standard_GRS"
              ]
            },
            "visible": true
          }
        ]
      }
    ],
    "outputs": {
      "location": "[location()]",
      "appServicePlanName": "[steps('webAppSettings').appServicePlanName]",
      "appServiceNamePrefix": "[steps('webAppSettings').appServiceName]",
      "storageAccountNamePrefix": "[steps('storageConfig').storageAccounts.prefix]",
      "storageAccountType": "[steps('storageConfig').storageAccounts.type]"
    }
  }
}

詳細については、CreateUiDefinition の概要に関するページを参照してください。

ファイルのパッケージ化

app.zip という名前のパッケージ ファイルに 2 つのファイルを追加します。 2 つのファイルは .zip ファイルのルートに配置する必要があります。 これらのファイルがフォルダー内にある場合、マネージド アプリケーション定義を作成するときに、必要なファイルが存在しないことを示すエラーが発生します。

マネージド アプリケーションの定義をデプロイするときに使用できるように、app.zip を Azure ストレージ アカウントにアップロードします。 ストレージ アカウント名は Azure 全体でグローバルに一意である必要があり、長さは小文字と数字のみで 3 から 24 文字にする必要があります。 コマンドで、山かっこ (<>) を含むプレースホルダー <demostorageaccount> を一意のストレージ アカウント名に置き換えます。

New-AzResourceGroup -Name packageStorageGroup -Location westus3

$storageAccount = New-AzStorageAccount `
  -ResourceGroupName packageStorageGroup `
  -Name "<demostorageaccount>" `
  -Location westus3 `
  -SkuName Standard_LRS `
  -Kind StorageV2

$ctx = $storageAccount.Context

New-AzStorageContainer -Name appcontainer -Context $ctx -Permission blob

Set-AzStorageBlobContent `
  -File "app.zip" `
  -Container appcontainer `
  -Blob "app.zip" `
  -Context $ctx

パッケージ ファイルの URI を packageuri という名前の変数に格納するには、次のコマンドを使用します。 この変数の値は、マネージド アプリケーション定義をデプロイするときに使用します。

$packageuri=(Get-AzStorageBlob -Container appcontainer -Blob app.zip -Context $ctx).ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri

マネージド アプリケーション定義用に独自のストレージを使用する

マネージド アプリケーション定義は、独自のストレージ アカウント内に保存します。これにより、規制に関する組織のニーズに合わせて場所とアクセスを管理できます。 独自のストレージ アカウントを使用すると、サービス カタログのマネージド アプリケーション定義に関する 120 MB の制限を超えるアプリケーションを作成できます。

Note

独自のストレージの使用は、マネージド アプリケーション定義の ARM テンプレートまたは REST API デプロイでのみサポートされます。

ストレージ アカウントを作成する

マネージド アプリケーション定義のストレージ アカウントを作成します。 ストレージ アカウント名は Azure 全体でグローバルに一意である必要があり、長さは小文字と数字のみで 3 から 24 文字にする必要があります。

この例では、byosDefinitionStorageGroup という名前の新しいリソース グループを作成します。 コマンドで、山かっこ (<>) を含むプレースホルダー <definitionstorage> を一意のストレージ アカウント名に置き換えます。

New-AzResourceGroup -Name byosDefinitionStorageGroup -Location westus3

New-AzStorageAccount `
  -ResourceGroupName byosDefinitionStorageGroup `
  -Name "<definitionstorage>" `
  -Location westus3 `
  -SkuName Standard_LRS `
  -Kind StorageV2

次のコマンドを使用して、ストレージ アカウントのリソース ID を storageid という名前の変数に格納します。 この変数の値は、マネージド アプリケーション定義をデプロイするときに使用します。

$storageid = (Get-AzStorageAccount -ResourceGroupName byosDefinitionStorageGroup -Name <definitionstorage>).Id

ストレージ アカウントのロールの割り当てを設定する

マネージド アプリケーション定義をストレージ アカウントにデプロイする前に、共同作成者ロールをアプライアンス リソース プロバイダー ユーザーに、ストレージ アカウント スコープで付与します。 この割り当てにより、この ID で定義ファイルをストレージ アカウントのコンテナーに書き込めるようになります。

変数を使用してロールの割り当てを設定できます。 この例では、前の手順で作成した $storageid 変数を使用し、$arpid 変数を作成します。

$arpid = (Get-AzADServicePrincipal -SearchString "Appliance Resource Provider").Id

New-AzRoleAssignment -ObjectId $arpid `
-RoleDefinitionName Contributor `
-Scope $storageid

アプライアンス リソース プロバイダーは、Microsoft Entra のテナントのサービス プリンシパルです。 Azure portal から、[Microsoft Entra ID][Enterprise アプリケーション] の順に移動し、検索フィルターを Microsoft アプリケーションに変更することで、登録されているかどうかを確認できます。 "アプライアンス リソース プロバイダー" を検索します。 見つからない場合は、Microsoft.Solutions リソース プロバイダーを登録します。

グループ ID とロール定義 ID を取得する

次の手順として、顧客のリソースを管理するためのユーザー、セキュリティ グループ、またはアプリケーションを選択します。 この ID には、割り当てられているロールに従って、管理対象リソース グループに対するアクセス許可が付与されています。 そのロールには、Azure の組み込みロール (所有者、共同作成者など) をどれでも使用できます。

この例ではセキュリティ グループを使用しており、Microsoft Entra アカウントはグループのメンバーである必要があります。 グループのオブジェクト ID を取得するには、山かっこ (<>) を含むプレースホルダー <managedAppDemo> をグループの名前に置き換えます。 この変数の値は、マネージド アプリケーション定義をデプロイするときに使用します。

新しい Microsoft Entra グループを作成するには、[Microsoft Entra グループとグループ メンバーシップの管理] に移動します。

$principalid=(Get-AzADGroup -DisplayName <managedAppDemo>).Id

次に、ユーザー、グループ、またはアプリケーションへのアクセス権を付与する Azure の組み込みロールのロール定義 ID を取得します。 この変数の値は、マネージド アプリケーション定義をデプロイするときに使用します。

$roleid=(Get-AzRoleDefinition -Name Owner).Id

定義のデプロイ テンプレートを作成する

Bicep ファイルを使用して、マネージド アプリケーション定義をサービス カタログにデプロイします。 デプロイ後、定義ファイルは独自のストレージ アカウントに保存されます。

Visual Studio Code を開き、deployDefinition.bicep という名前でファイルを作成して保存します。

次の Bicep コードを追加し、ファイルを保存します。

param location string = resourceGroup().location

@description('Name of the managed application definition.')
param managedApplicationDefinitionName string

@description('Resource ID for the bring your own storage account where the definition is stored.')
param definitionStorageResourceID string

@description('The URI of the .zip package file.')
param packageFileUri string

@description('Publishers Principal ID that needs permissions to manage resources in the managed resource group.')
param principalId string

@description('Role ID for permissions to the managed resource group.')
param roleId string

var definitionLockLevel = 'ReadOnly'
var definitionDisplayName = 'Sample BYOS managed application'
var definitionDescription = 'Sample BYOS managed application that deploys web resources'

resource managedApplicationDefinition 'Microsoft.Solutions/applicationDefinitions@2021-07-01' = {
  name: managedApplicationDefinitionName
  location: location
  properties: {
    lockLevel: definitionLockLevel
    description: definitionDescription
    displayName: definitionDisplayName
    packageFileUri: packageFileUri
    storageAccountId: definitionStorageResourceID
    authorizations: [
      {
        principalId: principalId
        roleDefinitionId: roleId
      }
    ]
  }
}

テンプレートのプロパティの詳細については、Microsoft.Solutions/applicationDefinitions を参照してください。

管理対象リソース グループの lockLevel によって、このリソース グループに対して問題となるような操作を顧客が実行できないようにします。 現在サポートされているロック レベルは ReadOnly だけです。 ReadOnly を指定すると、顧客は管理対象リソース グループに存在するリソースの読み取りしか実行できません。 管理対象リソース グループへのアクセス権が付与されている発行元 ID は、ロック レベルの対象外となります。

パラメーター ファイルを作成する

マネージド アプリケーション定義のデプロイ テンプレートを使用するには、いくつかのパラメーターに対して入力が必要です。 デプロイ コマンドで値の入力が求められます。または、自分で値のパラメーター ファイルを作成できます。 この例では、パラメーター ファイルを使用して、パラメーター値をデプロイ コマンドに渡します。

Visual Studio Code で、deployDefinition.parameters.json という名前の新しいファイルを作成し、保存します。

このパラメーター ファイルに以下を追加し、保存します。 次に、山かっこ (<>) を含む <placeholder values> を、実際の値に置き換えます。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "managedApplicationDefinitionName": {
      "value": "<placeholder for managed application name>"
    },
    "definitionStorageResourceID": {
      "value": "<placeholder for you storage account ID>"
    },
    "packageFileUri": {
      "value": "<placeholder for the packageFileUri>"
    },
    "principalId": {
      "value": "<placeholder for principalid value>"
    },
    "roleId": {
      "value": "<placeholder for roleid value>"
    }
  }
}

マネージド アプリケーション定義のパラメーター値について次の表で説明します。

パラメーター
managedApplicationDefinitionName マネージド アプリケーション定義の名前。 この例では、sampleByosManagedApplication を使用します。
definitionStorageResourceID 定義が保存されているストレージ アカウントのリソース ID。 storageid 変数の値を使用します。
packageFileUri .zip パッケージ ファイルの URI を入力します。 packageuri 変数の値を使用します。 形式は https://yourStorageAccountName.blob.core.windows.net/appcontainer/app.zip です。
principalId 管理対象リソース グループ内のリソースを管理するためのアクセス許可が必要なパブリッシャー プリンシパル ID。 principalid 変数の値を使用します。
roleId 管理対象リソース グループに対するアクセス許可のロール ID。 たとえば、所有者、共同作成者、閲覧者などです。 roleid 変数の値を使用します。

変数の値を取得するには:

  • Azure PowerShell: PowerShell で、「$variableName」と入力して変数の値を表示します。
  • Azure CLI: Bash で、「echo $variableName」と入力して変数の値を表示します。

定義をデプロイする

マネージド アプリケーションの定義は、デプロイするとサービス カタログで使用できるようになります。 このプロセスでは、マネージド アプリケーションのリソースはデプロイされません。

byosAppDefinitionGroup という名前のリソース グループを作成し、マネージド アプリケーション定義をストレージ アカウントにデプロイします。

New-AzResourceGroup -Name byosAppDefinitionGroup -Location westus3

New-AzResourceGroupDeployment `
  -ResourceGroupName byosAppDefinitionGroup `
  -TemplateFile deployDefinition.bicep `
  -TemplateParameterFile deployDefinition.parameters.json

定義ファイルのストレージを確認する

デプロイ中、テンプレートの storageAccountId プロパティはストレージ アカウントのリソース ID を使用し、大文字と小文字が区別される名前 applicationdefinitions で新しいコンテナーを作成します。 デプロイ中に指定した .zip パッケージのファイルは、新しいコンテナーに格納されます。

次のコマンドを使用して、マネージド アプリケーション定義ファイルがストレージ アカウントのコンテナーに保存されていることを確認できます。 コマンドで、山かっこ (<>) を含むプレースホルダー <definitionstorage> を一意のストレージ アカウント名に置き換えます。

Get-AzStorageAccount -ResourceGroupName byosDefinitionStorageGroup -Name <definitionstorage> |
Get-AzStorageContainer -Name applicationdefinitions |
Get-AzStorageBlob | Select-Object -Property Name | Format-List

Note

セキュリティを強化するために、マネージド アプリケーション定義を作成し、暗号化が有効になっている Azure ストレージ アカウント BLOB に保存できます。 定義の内容は、ストレージ アカウントの暗号化オプションを使用して暗号化されます。 そのファイルに対するアクセス許可を持つユーザーのみが、サービス カタログ内の定義にアクセスできます。

ユーザーが定義にアクセスできるようにする

自身がアクセスできるマネージ アプリケーション定義に、組織の他のユーザーもアクセスできることを確認する必要があります。 定義に対して閲覧者以上のロールをユーザーに付与してください。 ユーザーはこのレベルのアクセスをサブスクリプションまたはリソース グループから継承している場合があります。 定義にアクセスできるユーザーを確認したり、ユーザーやグループを追加したりするには、「Azure portal を使用して Azure ロールを割り当てる」を参照してください。

リソースをクリーンアップする

これから定義をデプロイする場合は、記事にリンクしている「次の手順」セクションに進んで定義をデプロイします。

マネージド アプリケーションの定義が終了したら、作成した packageStorageGroupbyosDefinitionStorageGroupbyosAppDefinitionGroup という名前のリソース グループを削除できます。

コマンドを実行すると、リソース グループを削除することを確認するメッセージが表示されます。

Remove-AzResourceGroup -Name packageStorageGroup

Remove-AzResourceGroup -Name byosAppDefinitionGroup

Remove-AzResourceGroup -Name byosDefinitionStorageGroup

次のステップ

マネージド アプリケーション定義を発行しました。 今度は、その定義のインスタンスをデプロイする方法を確認しましょう。