Reference Kubernetes apps in the Azure application using a managed app sample

This article gives technical resources and recommendations to help you reference Kubernetes apps in the Azure application using a managed app sample.

Limitations

The managed app offer won't work against an existing managed AKS cluster and Azure Arc-Enabled Kubernetes cluster. The offer needs to create a new managed AKS cluster and install the application on the cluster, otherwise, the offer will fail to deploy.

Prerequisites

You need to set up a Kubernetes offering in Azure Marketplace that you would like to reference in your managed app offer. You can refer to the Getting Started guide to create a Kubernetes offering.

Your UI definition and ARM template in this offer can be really simple, as you'll extend that in your managed app offer.

In this example, we start from k8s-offer-azure-vote folder to create the CNAB bundle for the base Kubernetes offering.

Once your offer is published and available in Azure Marketplace in preview stage, you can start creating your managed app offer.

Screenshot of preview link display to show managed app offer.

Managed app offer

Start with the mainTemplate and createUIDefinition files in this folder.

First, update the variables section:

"variables": {
    "plan-name": "DONOTMODIFY",
    "plan-publisher": "DONOTMODIFY",
    "plan-offerID": "DONOTMODIFY",
    "releaseTrain": "DONOTMODIFY",
    "clusterExtensionTypeName": "DONOTMODIFY"
},

To retrieve the value directly from the Kubernetes offering, follow the guide: Deploy an Azure Kubernetes application by using an ARM template.

Prepare mainTemplate.json

In this sample mainTemplate, we've added extra components to demonstrate how to add more components to the managed app offer.

User-assigned identity:

{
    "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
    "name": "[concat(parameters('clusterResourceName'), '-identity')]",
    "apiVersion": "2023-01-31",
    "location": "[resourceGroup().location]"
},
  • Keyvault, access policy and secret:
{
    "name": "[uniqueString(resourceGroup().id, resourceGroup().location, 'keyvault')]",
    "type": "Microsoft.KeyVault/vaults",
    "apiVersion": "2019-09-01",
    "location": "[resourceGroup().location]",
    "tags": {
        "displayName": "keyVault1"
    },
    "properties": {
        "enabledForDeployment": true,
        "enabledForTemplateDeployment": true,
        "enabledForDiskEncryption": true,
        "tenantId": "[subscription().tenantId]",
        "accessPolicies": [
            {
                "tenantId": "[subscription().tenantId]",
                "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', concat(parameters('clusterResourceName'), '-identity')), '2023-01-31').principalId]",
                "permissions": {
                    "keys": [
                        "Get"
                    ],
                    "secrets": [
                        "List",
                        "Get",
                        "Set"
                    ]
                }
            }
        ],
        "sku": {
            "name": "standard",
            "family": "A"
        }
    },
    "resources": [
        {
            "type": "secrets",
            "name": "secretExample1",
            "apiVersion": "2016-10-01",
            "dependsOn": [
                "[resourceId('Microsoft.KeyVault/vaults', uniqueString(resourceGroup().id, resourceGroup().location, 'keyvault'))]"
            ],
            "properties": {
                "value": "secretValue"
            }
        }
    ],
    "dependsOn": [
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', concat(parameters('clusterResourceName'), '-identity'))]"
    ]
}
  • Assigning the identity to the cluster's node and depends on:
"type": "Microsoft.ContainerService/managedClusters",
"apiVersion": "2022-11-01",
"name": "[parameters('clusterResourceName')]",
"location": "[parameters('location')]",
"dependsOn": [
    "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', concat(parameters('clusterResourceName'), '-identity'))]"
],
"tags": {},
"sku": {
    "name": "Basic",
    "tier": "Free"
},
"identity": {
    "type": "UserAssigned",
    "userAssignedIdentities": {
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', concat(parameters('clusterResourceName'), '-identity'))]": {}
    }
},

UIDefinition

In this sample createUiDefinition, we've removed extra components that aren't applicable for the managed app offer.

Package the files

Add the two files mainTemplate.json and createUiDefinition.json to a zip file.

Create the managed app offer

Now that you have the artifacts required, you can follow the guide: Create an Azure application offer in Azure Marketplace to create the managed app offer.