How to use Azure Portal blades in the Template Specs UI

How to use Azure Portal blades in the Template Specs UI

Template specs are a great way to share templates across the organization so that users and developers can deploy approved workloads within the organization. Access to them can be controlled with Azure RBAC.

By default, the Azure Portal will create some default look and feel by inferring the parameters of your template spec. But if you want greater control, you can define the UI by defining a UI form definition in JSON that you attach to your template spec. You can do so via Azure CLI or Azure PowerShell.

About UI Definitions

The template specs UI definition has a lot in common with Azure Managed Applications. But there are differences. The most important is that there are 2 JSON schemas for defining Portal UI - CreateUIDefinition.MultiVm.json and uiFormDefinition.schema.json. Although they have a lot of similarities, the former is considered the old format and it's used for Azure Managed Application, while the latter is the newer format used by Template Specs.

You can find the documentation of most of the supported UI elements here. If you ask me, we need a lot more to be exposed.

Extensions and blades

But if you closely examine the uiFormDefinition.schema.json you'll find an intriguing type that is, well, mostly undocumented in the official docs: Microsoft.Solutions.BladeInvokeControl.

Most of the visual elements in Azure Portal are combined into panes, the so-called blades. Blades belong to an extension that usually provides multiple blades and typically implements the Portal functionality needed by a particular provider, e.g. the Microsoft_Azure_KeyVault extension.

The BladeInvokeControl opens a blade and provides the output values of that blade as a result. It is also capable of doing transformations using JMESPath which allows you to massage the resultant objects.

The BladeInvokeControl is typically used in conjunction with another element like Microsoft.Common.Selector which is a common pattern you see across the Portal. The selector can display certain properties of the blade output and has a color-coded state that shows success or error.

Here is a basic example of selecting a secret from a Key Vault where you can see the interplay between the blade and the selector:

{
    "name": "keyVault",
    "label": "Key Vault",
    "elements": [
        {
            "name": "secretSection",
            "type": "Microsoft.Common.Section",
            "label": "Secret selection",
            "elements": [
                {
                    "name": "secretPickerBlade",
                    "type": "Microsoft.Solutions.BladeInvokeControl",
                    "openBladeStatus": "[steps('keyVault').secretSection.secretSelector.changing]",
                    "bladeReference": {
                        "name": "SecretPickerV2ViewModel",
                        "extension": "Microsoft_Azure_KeyVault",
                        "parameters": {
                            "subscriptionId": "[steps('basics').resourceScope.subscription.subscriptionId]",
                            "showSubscriptionDropdown": true
                        },
                        "inFullScreen": false
                    }
                },
                {
                    "name": "secretSelector",
                    "type": "Microsoft.Common.Selector",
                    "label": "Secret",
                    "keyPath": "secretId",
                    "value": "[steps('keyVault').secretSection.secretPickerBlade]",
                    "visible": true,
                    "barColor": "[if(empty(steps('keyVault').secretSection.secretPickerBlade), '#FF0000', '#7fba00')]",
                    "constraints": {
                        "required": true
                    },
                    "link": "Select a secret"
                }
            ]
        }
    ]
}

It looks like this:

Select a key vault secret using blade invoke control

You can check all the parameters of BladeInvokeControl in Azure/portaldocs.

How to try a UI definition?

You can find a full working example of all blades from this blog post here. The easiest way to play with the UI definition is to copy the JSON contents and paste it into the Form view Sandbox, then hit Preview.

Blades reference

Some blades are very useful and I want to keep track of their parameters in this blog post. I already had to explore their implementation a couple of times because I tend to forget about the specifics. That was one of the reasons for writing that blog post.

Below, you will find some of the blades that I see as universal and will be needed in most Template Specs sooner rather than later. I've documented their inputs but if you'd like to see the outputs, make sure to play with them because I did put a text field to show the entire output of every blade.

Entra ID object picker

Extension: Microsoft_AAD_IAM
Blade Name: ObjectPickerBlade

Entra ID Object picker

I'm sure you used this one many times to select users, groups, and applications. Although the blade looks simple, it offers a lot of parameters that you can set:

Parameter Value Description
queries int (required) The query or queries to be performed by the object picker blade. Multiple queries can be combined with bitwise OR. See the Queries table below.
additionalQueriesOnSearch int Queries to be tried upon typing some text in the search field. See the Queries table below.
advancedQueryOptions object Some of the queries support passing additional options. It is best to check the implementation of a given query.
bladeSubtitle string Blade subtitle
bladeTitle string Blade title
disabledObjectIds [string] Array of object IDs not to be offered for selection
disablers int What information to be excluded from results of the queries. Multiple disablers can be combined with bitwise OR. See the Disablers table below.
informationHeader {"informationText": "Longer informational header", "informationLink": "https://example.com"} Text and link for the information header.
inviteEnabled bool It can be used to invite users. It's not clear what query one should use but presumably some type that allows entering the email addresses of guest users.
searchBoxLabel string Label of the search input.
searchBoxPlaceHolderText string Placeholder to display in the search input.
searchBoxTooltip string The text of the tooltip that appears next to the label.
searchGridNoRowsMessage string Text of the message to be displayed when no results were found.
selectButtonText string Text of the select button.
selectedGridLabel string Label for the selected objects grid
selectedGridNoRowsMessage string Message to be displayed in the selected object grid when no records are selected.
selectedObjectIds [string] Array of object IDs to be pre-selected when the object picker is opened.
selectionMaximum int Maximum number of objects to be selected
selectionMinimum int Minimum numbers of objects to be selected
suggestedObjectsOptions object It is best to check the implementation of the queries you want to use. To use the SuggestedObjectsQuerier, the suggestedObjectsOptions parameter must be defined.

Queries

If you would like to enable selection for users, groups, and service principals, for example, that would be 1 | 2 | 4 = 7.

Flag Query
1 AllUsersBatchFormer
2 AllGroupsBatchFormer
4 AllServicePrincipalsBatchFormer
8 AllDevicesBatchFormer
16 AllContactsQuerier / AllContactsBatchFormer
32 SecurityEnabledGroupsBatchFormer
64 MailEnabledGroupsBatchFormer
128 TeamsGroupsBatchFormer
256 UnifiedGroupsBatchFormer
512 GroupsAssignableToRoleBatchFormer
1024 DynamicGroupsBatchFormer
2048 GuestUsersBatchFormer
4096 TransitiveMembersBatchFormer
8192 AllAdministrativeUnitsBatchFormer
16384 RoleMembersBatchFormer
32768 AADIntegratedServicePrincipalsBatchFormer
65536 ThirdPartyServicePrincipalsQuerier
131072 AllUnifiedRoleDefinitionsQuerier
262144 AllApplicationsBatchFormer
524288 OwnedObjectsBatchFormer
1048576 SuggestedObjectsQuerier
2097152 AccessPackagesBatchFormer
4194304 OnPremSecurityEnabledGroupsBatchFormer
8388608 CrossTenantApplicationsQuerier
16777216 FirstPartyServicePrincipalsQuerier

Disablers

Disablers offer a way to exclude certain objects from the results of the active Queries.

Flag Disabler
1 DirectorySyncedDisabler
2 DynamicGroupDisabler
4 DistributionGroupDisabler / UnifiedGroupDisabler
16 TeamsGroupDisabler
32 ExoGroupDisabler
64 GuestUserDisabler
128 SelfDisabler
256 RoleAssignableGroupDisabler
512 MailEnabledSecurityGroupDisabler
1024 MSAUserDisabler
2048 NonGuestMSAUserDisabler
4096 NoMailboxUserDisabler
8192 FederatedUserDisabler
16384 CustomRoleDisabler
32768 RestrictedAdminUnits

Key Vault - Key Picker blade

Extension: Microsoft_Azure_KeyVault
Blade Name: KeyPickerV2ViewModel

Key vault key picker blade
Parameter Value Description
subscriptionId string (required) The default subscription ID to list Key Vaults from.
showSubscriptionDropdown bool Whether to display the subscriptions dropdown.
showCreateNew bool Whether to show a hyperlink that allows the creation of a new key vault, key, or version.
keyAndVersionDropdownOptional bool Set to true if the key and version are optional fields, i.e. the blade can be used for selecting a key vault only.
requiredKeyTypes [int] 0-3 where 0 - "RSA", 1 - "RSA-HSM", 2 - "EC", 3 - "EC-HSM" What key types are to be allowed for selection. Note: all keys will appear in the dropdown; however, selection will be possible only for the keys of the required types.
requiredKeySizes [int] 0-2 where 0 - 2048, 1 - 3072, 2 - 4096 What key sizes to allow for selection
requiredCurveNames [int] 0-3 where 0 - "P-256", 1 - "P-384", 2 - "P-521", 3 - "P-256K" The elliptic curve names to be available for selection.
requiredKeyOperations [int] 0-5 respectively ["sign", "verify", "wrapKey", "unwrapKey", "encrypt", "decrypt"] The permitted operations that are required for a version to be available for selection.
enableMHSM bool Displays a filter for the key vault type - Key Vault or Managed HSM
location string The name of the region to list key vaults from.
showVersionPicker bool Allow versions to be selected.
supportAlwaysUseCurrentKeyVersion bool Displays a checkbox to opt to use the latest version. showVersionPicker needs to be true.
defaultVaultId string Resource ID of the Key Vault to be selected upon opening the blade.

Key Vault - Secret Picker blade

Extension: Microsoft_Azure_KeyVault
Blade Name: SecretPickerV2ViewModel

Sure, there is Microsoft.KeyVault.KeyVaultCertificateSelector available for use, but it is not that configurable.

Key Vault secret picker blade
Parameter Value Description
subscriptionId string (required) The default subscription ID to list Key Vaults from.
showSubscriptionDropdown bool Whether to display the subscriptions dropdown.
location string The name of the region to list key vaults from.
showCreateNew bool Whether to show a hyperlink that allows the creation of a new key vault, secret, or version.
showVersionPicker bool Allow versions to be selected.
defaultVaultId string Resource ID of the Key Vault to be selected upon opening the blade.

Key Vault - Certificate Picker blade

Extension: Microsoft_Azure_KeyVault
Blade Name: CertPickerV2ViewModel

Key Vault certificate picker blade
Parameter Value Description
subscriptionId string (required) The default subscription ID to list Key Vaults from.
requiredSubjectName string X.500 distinguished name
defaultCertId string A default certificate to be pre-selected in the format "https://{key-vault-name}.vault.azure.net/certificates/{certificate-name}"
showSubscriptionDropdown bool Whether to display the subscriptions dropdown.
location string The name of the region to list key vaults from.
showCreateNew bool Whether to show a hyperlink that allows the creation of a new key vault, certificate, or version.
showVersionPicker bool Allow versions to be selected.
defaultVaultId string Resource ID of the Key Vault to be selected upon opening the blade.

An important disclaimer

Although it's quite handy to reuse functionality you are already familiar with because it comes from the Azure Portal, keep in mind that Microsoft can change those blades at any given time and at their own discretion. As you might notice in the BladeInvokeControl, we don't specify a version of the blade. Blades are simply not versioned for external invocation. The Azure Portal application goes hand in hand with its blades, so it intrinsically knows how to work with the "current" version.

Based on my experience in the last year, you won't see a lot of changes on the existing blades. But be prepared for parameters, functionality, and outputs to change. If it is a breaking change, Microsoft will likely change the name of the blade, for reference CertPickerV2ViewModel.

What blades are useful to you?

Let me know in the comments what blades can come in handy for you. If they can be massively reused I can consider adding them to this post.