Authoring templates
Azure TRE workspaces, workspace services, shared services, and user resources are Porter bundles. Porter bundles are based on Cloud Native Application Bundles (CNAB).
Authors are free to choose the technology stack for provisioning resources (e.g., ARM templates, Terraform etc.), but the Azure TRE framework sets certain requirements for the bundle manifests, which specify the credentials, input and output parameters, deployment actions among other things.
This document describes the requirements, and the process to author a template.
Tip
Use the base workspace bundle as reference or as the basis for the new bundle.
To create a bundle from scratch follow the Porter Quickstart Guide (porter create CLI command will generate a new bundle in the current directory).
Read more about Porter in Resource Processor doc.
Prerequisites
- Docker installed
- Porter installed
- Azure TRE instance deployed to test against
Workspace bundle manifest
The manifest of a workspace bundle is the porter.yaml file (see Author Bundles in Porter documentation). This section describes the mandatory credentials, input and output parameters of a TRE workspace bundle.
Credentials
A workspace bundle requires the following credentials to provision resources in Azure:
- Azure tenant ID
- Azure subscription ID
- The client ID of a service principal with privileges to provision resources
- The client secret (password) of a service principal
The credentials are provided as environment variables by the deployment runner. The bundle author must use the following environment variable names:
ARM_TENANT_ID
ARM_SUBSCRIPTION_ID
ARM_CLIENT_ID
ARM_CLIENT_SECRET
The names of the Porter credentials (name field in porter.yaml) can be freely chosen by the author.
Example:
credentials:
- name: azure_tenant_id
env: ARM_TENANT_ID
- name: azure_subscription_id
env: ARM_SUBSCRIPTION_ID
- name: azure_client_id
env: ARM_CLIENT_ID
- name: azure_client_secret
env: ARM_CLIENT_SECRET
Parameters
This section describes the mandatory (input) parameters of a workspace bundle manifest.
Parameter |
Type | Description | Example value |
|---|---|---|---|
tre_id |
string | Unique ID of for the TRE instance. | tre-dev-42 |
workspace_id |
string | Unique 4-character long, alphanumeric workspace ID. | 0a9e |
azure_location |
string | Azure location (region) to deploy the workspace resource to. | westeurope |
address_space |
string | VNet address space for the workspace services. | 10.2.1.0/24 |
tre_id can be found in the resource names of the Azure TRE instance; for example the resource group name of the Azure TRE instance based on the example in the above table would be "rg-tre-dev-42".
Similarly to tre_id, workspace_id is used in the resource names of the workspace. The resource group name of the workspace must be of form "rg-<tre_id>-ws-<workspace_id>", for example: "rg-tre-dev-42-ws-0a9e".
All the values for the required parameters will be provided by the deployment runner.
Any custom parameters are picked up by Azure TRE API and will be queried from the user deploying the workspace bundle. Custom parameters should also be defined in the template_schema.json file at the root of the bundle.
This file follows the JSON schema standard Draft 2020-12 (https://json-schema.org/draft/2020-12/schema) for the subset supported by Azure TRE and can be used by a user interface to generate a UI for the user to input the parameters.
JSON Schema Version Standard
Azure TRE template schemas (template_schema.json) use the JSON Schema Draft 2020-12 dialect for the keywords supported by the template registration and validation APIs:
{
"$schema": "https://json-schema.org/draft/2020-12/schema"
}
The API preserves the root $schema, $id, and $defs keywords during registration. Other Draft 2020-12 keywords should be used only where supported by the template model and validation engine.
Compatibility with existing templates
| Template declaration | API validation | Resource forms |
|---|---|---|
| Draft 2020-12 | Draft 2020-12 | Draft 2020-12 validator |
| Draft 7 | Draft 7 with Azure TRE's additional unevaluatedProperties restriction |
Draft 7 validator |
No $schema |
Existing default validation, currently Draft 2020-12 | Existing Draft 7 form validation |
Azure TRE rejects unexpected resource properties and PATCH changes to properties that are not updateable, including when a Draft 7 template is registered again. The Draft 7 API validator retains legacy keyword behaviour and adds support for Azure TRE's unevaluatedProperties: false restriction. Conditional properties declared in an active allOf branch remain valid.
Registration preserves the root validation fields properties, required, allOf and $defs, together with $schema and $id. The root type is always object. Other root validation keywords are not preserved.
Put conditional rules inside allOf, rather than using root if, then or else. Property schemas can contain local references such as #/$defs/label, nested object and array constraints, and nullable types. Form rendering remains limited to the features supported by React JSON Schema Form. This is not full JSON Schema conformance.
Keep Azure TRE annotations such as updateable, sensitive and readOnly on the property itself when using a $ref. A reusable definition does not supply these annotations to Azure TRE's resource processing.
An API upgrade does not rewrite stored templates or add missing metadata. To adopt Draft 2020-12, review the custom template's keywords, increment its bundle version and register the updated bundle. Changing only $schema can change validation semantics. Test creation and updates before upgrading existing resources.
Note
$id is not required on individual properties or subschemas. Properties defined under "properties" are natively addressable by standard JSON Pointer (e.g. #/properties/property_name).
* In JSON Schema Draft 2020-12, $id is used for establishing the base URI of schema resources (e.g. at the root schema level). Placing $id on individual properties or subschemas is generally unnecessary and can alter reference resolution context. If custom plain-name anchors are needed within a subschema, use $anchor instead.
Template properties
When authoring a template_schema.json file, you can reference properties from the resource being deployed, or its parent resources. For more information see Pipeline Template Schema.
Output
Todo
After a workspace with virtual machines is implemented this section can be written based on that. (Outputs in Porter documentation to be linked here too.)
Actions
The required actions are the main two of CNAB spec:
install- Deploys/repairs the workspace Azure resources, and must be idempotentuninstall- Tears down (deletes) the Azure resources of the workspace and its services
Workspace service bundle manifests
Workspace service bundles are generated in the same way as workspace bundles.
The mandatory parameters for workspace services are:
| Parameter | Type | Description | Example value |
|---|---|---|---|
tre_id |
string | Unique ID of for the TRE instance. | tre-dev-42 |
workspace_id |
string | Unique 4-character long, alphanumeric workspace ID. | 0a9e |
Workspace services requiring additional address spaces
Some workspace services may require additional address spaces to be provisioned. This may be necessary if they need advanced network security groups, route tables or delegated subnets.
To request an additional address space, the workspace service bundle must define an address_space parameter in the porter.yaml file. The value of this parameter will be provided by API to the resource processor.
The size of the address_space will default to /24, however other sizes can be requested by including an address_space_size as part of the workspace service template.
This parameter accepts the presets small (/24), medium (/22), large (/16), the literal value custom together with an explicit address_space CIDR (e.g. 10.2.1.0/25), or a numeric CIDR mask as a string.
The API has support for allocating CIDR subnet masks from "16" to "29". Workspace templates are configured to support from "16" (65,536 IP addresses) to "24" (256 IP addresses).
Depending on the workspace service you are deploying you may configure a template with a CIDR up to "29" which has only 3 usable IP addresses as Azure reserves the first four and last address of every subnet.
The workspace service IP addresses are in addition to the workspace addresses and the address size is unrelated to the workspace IP address size.
The workspace will be patched to add the additional address space to its vnet.
The address_space allocation will only take place during the install phase of a deployment, as this is a breaking change to your template you should increment the major version of your template, this means a you must deploy a new resource instead of upgrading an existing one.
In your install and uninstall pipelines you also need to include a workspace upgrade step for the workspace to update it's address_spaces property.
"pipeline": {
"install": [
{
"stepId": "efb826a8-71ad-4eb6-aa31-dbe349bb54fb",
"stepTitle": "Upgrade to ensure the workspace is aware of the new address space",
"resourceType": "workspace",
"resourceAction": "upgrade",
"properties": []
},
{
"stepId": "main"
}
User resource bundle manifests
User Resource bundles are generated in the same way as workspace bundles and workspace services bundles. The main difference is that a workspace service type needs to be supplied when registering a user resource template, as it only applies to a given workspace service.
The mandatory parameters for User Resources are:
| Parameter | Type | Description | Example value |
|---|---|---|---|
tre_id |
string | Unique ID of for the TRE instance. | tre-dev-42 |
workspace_id |
string | Unique 4-character long, alphanumeric workspace ID. | 0a9e |
Azure Resources Tagging
TRE Cost Reporting is based on Azure tagging to be able to generate cost report for core services, shared services, workspace, workspace services and user resources. Templates authors need to make sure that underlying Azure resources are tagged with the relevant tags, for more information see cost reporting:
Versioning
Workspace versions are the bundle versions specified in the metadata. The bundle versions should match the image tags in the container registry (see Publishing workspace bundle).
Bundle versions should follow Semantic Versioning, given a version number MAJOR.MINOR.PATCH, increment the:
-
MAJOR version when you make a breaking change, potential data loss, changes that don't easily/automatically upgrade, or significant changes which require someone to review what has changed and take some appropriate action, or functionality of the component has significantly changed and users might need training.
-
MINOR version when you add minor functionality which can be automatically upgraded.
-
PATCH version when you make backward-compatible bug or typo fixes.
For resource version upgrades see Upgrading Resources Version.
Publishing workspace bundle
See Registering workspace templates.
Manual Deployment
Caution
Resources should be deployed using the API (i.e. through the Swagger UI as described in the setup instructions). Only deploy manually for development/testing purposes.
-
Create a copy of the Porter bundle's environment settings from
/templates/<scope>/.env.samplewith the name.envand update the variables with the appropriate values. -
Build and deploy the Porter bundle
make bundle-build DIR=./templates/<scope>/<bundle_name> make bundle-publish DIR=./templates/<scope>/<bundle_name> make bundle-register DIR=./templates/<scope>/<bundle_name> BUNDLE_TYPE=<scope>