Snabbstart: Använda Bicep för att skapa och publicera en Azure Managed Application-definition

Den här snabbstarten beskriver hur du använder Bicep för att skapa och publicera en Azure Managed Application-definition i tjänstkatalogen. Definitionen i tjänstkatalogen är tillgänglig för medlemmar i organisationen.

Utför följande uppgifter för att skapa och publicera en definition för ett hanterat program i tjänstkatalogen:

  • Använd Bicep för att utveckla mallen och konvertera den till en Azure Resource Manager-mall (ARM-mall). Mallen definierar de Azure-resurser som distribueras av det hanterade programmet.
  • Konvertera Bicep till JSON med Bicep-kommandot build . När filen har konverterats till JSON rekommenderar vi att du verifierar koden för noggrannhet.
  • Definiera användargränssnittselementen för portalen när du distribuerar det hanterade programmet.
  • Skapa ett .zip-paket som innehåller de JSON-filer som krävs. .zip-paketfilen har en gräns på 120 MB för en tjänstkatalogs definition av hanterade program.
  • Publicera definitionen för det hanterade programmet så att den är tillgänglig i tjänstkatalogen.

Om definitionen för det hanterade programmet är mer än 120 MB eller om du vill använda ditt eget lagringskonto av organisationens efterlevnadsskäl går du till Snabbstart: Ta med din egen lagring för att skapa och publicera en Azure Managed Application-definition.

Du kan också använda Bicep för att distribuera en definition av hanterade program från tjänstkatalogen. Mer information finns i Snabbstart: Använd Bicep för att distribuera en Azure Managed Application-definition.

Förutsättningar

För att slutföra uppgifterna i den här artikeln behöver du följande:

Skapa en Bicep-fil

Alla definitioner för hanterade program innehåller en fil med namnet mainTemplate.json. Mallen definierar de Azure-resurser som ska distribueras och skiljer sig inte från en vanlig ARM-mall. Du kan utveckla mallen med Bicep och sedan konvertera Bicep-filen till JSON.

Öppna Visual Studio Code, skapa en fil med skiftlägeskänsligt namn mainTemplate.bicep och spara den.

Lägg till följande Bicep-kod och spara filen. Den definierar det hanterade programmets resurser för att distribuera en App Service, App Service-plan och ett lagringskonto.

param location string = resourceGroup().location

@description('App Service plan name.')
@maxLength(40)
param appServicePlanName string

@description('App Service name prefix.')
@maxLength(47)
param appServiceNamePrefix string

@description('Storage account name prefix.')
@maxLength(11)
param storageAccountNamePrefix string

@description('Storage account type allowed values')
@allowed([
  'Premium_LRS'
  'Standard_LRS'
  'Standard_GRS'
])
param storageAccountType string

var appServicePlanSku = 'F1'
var appServicePlanCapacity = 1
var appServiceName = '${appServiceNamePrefix}${uniqueString(resourceGroup().id)}'
var storageAccountName = '${storageAccountNamePrefix}${uniqueString(resourceGroup().id)}'
var appServiceStorageConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};Key=${storageAccount.listKeys().keys[0].value}'

resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: appServicePlanSku
    capacity: appServicePlanCapacity
  }
}

resource appServiceApp 'Microsoft.Web/sites@2022-03-01' = {
  name: appServiceName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
    siteConfig: {
      appSettings: [
        {
          name: 'AppServiceStorageConnectionString'
          value: appServiceStorageConnectionString
        }
      ]
    }
  }
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: storageAccountType
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

output appServicePlan string = appServicePlan.name
output appServiceApp string = appServiceApp.properties.defaultHostName
output storageAccount string = storageAccount.properties.primaryEndpoints.blob

Konvertera Bicep till JSON

Använd PowerShell eller Azure CLI för att skapa filen mainTemplate.json . Gå till katalogen där du sparade Bicep-filen och kör build kommandot .

bicep build mainTemplate.bicep

Mer information finns i Bicep build.

När Bicep-filen har konverterats till JSON ska filen mainTemplate.json matcha följande exempel. Du kan ha olika värden i metadata egenskaperna för version och templateHash.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.17.1.54307",
      "templateHash": "1234567891234567890"
    }
  },
  "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]"
    }
  }
}

Definiera portalupplevelsen

Som utgivare definierar du portalupplevelsen för att skapa det hanterade programmet. Filen createUiDefinition.json genererar portalens användargränssnitt. Du definierar hur användare anger indata för varje parameter med hjälp av kontrollelement som listrutor och textrutor.

I det här exemplet uppmanas du i användargränssnittet att ange prefixet App Service-namn, App Service-planens namn, lagringskontoprefix och lagringskontotyp. Under distributionen använder uniqueString variablerna i mainTemplate.json funktionen för att lägga till en 13-teckenssträng i namnprefixen så att namnen är globalt unika i Hela Azure.

Öppna Visual Studio Code, skapa en fil med skiftlägeskänsligt namn createUiDefinition.json och spara den.

Lägg till följande JSON-kod i filen och spara den.

{
  "$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]"
    }
  }
}

Mer information finns i Kom igång med CreateUiDefinition.

Paketera filerna

Lägg till de två filerna i en paketfil med namnet app.zip. De två filerna måste vara på rotnivån för .zip-filen . Om filerna finns i en mapp får du ett felmeddelande om att de filer som krävs inte finns när du skapar definitionen för det hanterade programmet.

Ladda upp app.zip till ett Azure-lagringskonto så att du kan använda det när du distribuerar definitionen för det hanterade programmet. Lagringskontonamnet måste vara globalt unikt i Azure och längden måste vara 3–24 tecken med endast gemener och siffror. I kommandot ersätter du platshållaren <demostorageaccount> inklusive vinkelparenteserna (<>) med ditt unika lagringskontonamn.

Öppna en ny PowerShell-terminal i Visual Studio Code och logga in på din Azure-prenumeration.

Connect-AzAccount

Kommandot öppnar din standardwebbläsare och uppmanar dig att logga in på Azure. Mer information finns i Logga in med Azure PowerShell.

När du har anslutit kör du följande kommandon.

New-AzResourceGroup -Name packageStorageRG -Location westus3

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

$ctx = $storageAccount.Context

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

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

Använd följande kommando för att lagra paketfilens URI i en variabel med namnet packageuri. Du använder variabelns värde när du distribuerar definitionen för det hanterade programmet.

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

Skapa definitionen för det hanterade programmet

I det här avsnittet får du identitetsinformation från Microsoft Entra-ID, skapar en resursgrupp och distribuerar definitionen för det hanterade programmet.

Hämta grupp-ID och rolldefinitions-ID

Nästa steg är att välja en användare, säkerhetsgrupp eller ett program för att hantera kundens resurser. Den här identiteten har behörigheter för den hanterade resursgruppen enligt den tilldelade rollen. Rollen kan vara valfri inbyggd Azure-roll som Ägare eller Deltagare.

I det här exemplet används en säkerhetsgrupp och ditt Microsoft Entra-konto bör vara medlem i gruppen. Om du vill hämta gruppens objekt-ID ersätter du platshållaren <managedAppDemo> inklusive vinkelparenteserna (<>) med gruppens namn. Du använder variabelns värde när du distribuerar definitionen för det hanterade programmet.

Om du vill skapa en ny Microsoft Entra-grupp går du till Hantera Microsoft Entra-grupper och gruppmedlemskap.

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

Hämta sedan rolldefinitions-ID:t för den inbyggda Azure-roll som du vill ge åtkomst till användaren, gruppen eller programmet. Du använder variabelns värde när du distribuerar definitionen för det hanterade programmet.

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

Skapa mallen för definitionsdistribution

Använd en Bicep-fil för att distribuera definitionen av det hanterade programmet i tjänstkatalogen.

Öppna Visual Studio Code, skapa en fil med namnet deployDefinition.bicep och spara den.

Lägg till följande Bicep-kod och spara filen.

param location string = resourceGroup().location

@description('Name of the managed application definition.')
param managedApplicationDefinitionName 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 Bicep managed application'
var definitionDescription = 'Sample Bicep 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
    authorizations: [
      {
        principalId: principalId
        roleDefinitionId: roleId
      }
    ]
  }
}

Mer information om mallens egenskaper finns i Microsoft.Solutions/applicationDefinitions.

lockLevel den hanterade resursgruppen hindrar kunden från att utföra oönskade åtgärder i den här resursgruppen. ReadOnly Är för närvarande den enda låsnivå som stöds. ReadOnly anger att kunden bara kan läsa de resurser som finns i den hanterade resursgruppen. De utgivaridentiteter som beviljas åtkomst till den hanterade resursgruppen är undantagna från låsnivån.

Skapa parameterfilen

Distributionsmallen för den hanterade programdefinitionen behöver indata för flera parametrar. Distributionskommandot frågar efter värdena eller så kan du skapa en parameterfil för värdena. I det här exemplet använder vi en parameterfil för att skicka parametervärdena till distributionskommandot.

I Visual Studio Code skapar du en ny fil med namnet deployDefinition.parameters.json och sparar den.

Lägg till följande i parameterfilen och spara den. Ersätt sedan inklusive <placeholder values> vinkelparenteser (<>) med dina värden.

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

I följande tabell beskrivs parametervärdena för definitionen av det hanterade programmet.

Parameter Värde
managedApplicationDefinitionName Namnet på definitionen för det hanterade programmet. I det här exemplet använder du sampleBicepManagedApplication.
packageFileUri Ange URI:n för .zip-paketfilen . packageuri Använd variabelns värde. Formatet är https://yourStorageAccountName.blob.core.windows.net/appcontainer/app.zip.
principalId Utgivarens huvudnamns-ID som behöver behörighet att hantera resurser i den hanterade resursgruppen. principalid Använd variabelns värde.
roleId Roll-ID för behörigheter till den hanterade resursgruppen. Till exempel Ägare, Deltagare, Läsare. roleid Använd variabelns värde.

Så här hämtar du dina variabelvärden:

  • Azure PowerShell: I PowerShell skriver du $variableName för att visa en variabels värde.
  • Azure CLI: I Bash skriver du echo $variableName för att visa en variabels värde.

Distribuera definitionen

När du distribuerar definitionen för det hanterade programmet blir den tillgänglig i tjänstkatalogen. Den här processen distribuerar inte det hanterade programmets resurser.

Skapa en resursgrupp med namnet bicepDefinitionRG och distribuera definitionen för det hanterade programmet.

New-AzResourceGroup -Name bicepDefinitionRG -Location westus3

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

Verifiera resultatet

Kör följande kommando för att kontrollera att definitionen har publicerats i tjänstkatalogen.

Get-AzManagedApplicationDefinition -ResourceGroupName bicepDefinitionRG

Get-AzManagedApplicationDefinition visar en lista över alla tillgängliga definitioner i den angivna resursgruppen, till exempel sampleBicepManagedApplication.

Kontrollera att användarna kan komma åt din definition

Du har åtkomst till definitionen för hanterade program, men du vill kontrollera att andra användare i din organisation kan komma åt den. Ge dem minst rollen Läsare på definitionen. De kan ha ärvt den här åtkomstnivån från prenumerationen eller resursgruppen. Om du vill kontrollera vem som har åtkomst till definitionen och lägga till användare eller grupper går du till Tilldela Azure-roller med hjälp av Azure-portalen.

Rensa resurser

Om du ska distribuera definitionen fortsätter du med avsnittet Nästa steg som länkar till artikeln för att distribuera definitionen med Bicep.

Om du är klar med definitionen för det hanterade programmet kan du ta bort de resursgrupper som du skapade med namnet packageStorageRG och bicepDefinitionRG.

Kommandot uppmanar dig att bekräfta att du vill ta bort resursgruppen.

Remove-AzResourceGroup -Name packageStorageRG

Remove-AzResourceGroup -Name bicepDefinitionRG

Nästa steg

Du har publicerat definitionen av det hanterade programmet. Nästa steg är att lära dig hur du distribuerar en instans av den definitionen.