Azure CNAB Driver
The Azure CNAB Driver enables the installation of CNAB Bundle using Azure Container Instance as an installation driver, this enables installation of a CNAB bundle from environments where using the Docker driver is impossible
The main purpose of this driver is to enable CNAB operations to be performed using Azure CloudShell.
Requirements to use the Driver
You must have an Azure account to use this driver.
Your Azure user account or the account that you use to execute the driver (see below for details on authentication) needs to have permission to create and use Azure resources for this driver to work. By default the driver will need to create and delete a resource group and create and delete a container group
If you provide a resource group to be used by the driver either by setting a default resource group using
az configure -d group=<resource-group-name> or by setting the environment variable
1. Install the latest Porter and CNAB Azure Driver Releases.
curl https://raw.githubusercontent.com/deislabs/cnab-azure-driver/master/install-in-azure-cloudshell.sh |/bin/bash source .bashrc
This will install the latest porter and azure-cnab-driver releases and update
.bashrc to include these in your path
2. Install a sample bundle:
A simple test bundle that generates outputs can be run to validate the install:
porter install test --tag deislabs/porter-example-exec-outputs-bundle:0.1.0 -d azure porter show test
Default Azure Location and Credentials
The environment variable
CNAB_AZURE_LOCATION can be set to any region where the ACI Service is available, by default in CloudShell the driver will derive the location from the default location set in using
az configure -d location=<location> otherwise it will use the users CloudShell location.
In CloudShell the credentials that you are logged in with will be used to create the ACI Container Group to run the invocation image and it will pick the current default subscription (this can be set or checked using
az account), a specific subscription can be chosen by setting the environment Variable
CNAB_AZURE_SUBSCRIPTION_IDto the subscription ID to be used.
More details on alternative authentication approaches are specified below.
Logging and tracing
To enable trace logs of the driver to be output to the console set the environment variable
true, to get details of the HTTP requests sent to Azure set the environment variable
INFO, to include the request and response bodies of the requests set the value to
DEBUG. Logs are also stored at
Authentication to Azure
The ACI Driver can Authenticate to Azure using the following mechanisms and will evaluate them in this order:
- Service Principal
Setting the environment variables
CNAB_AZURE_TENANT_ID will cause the driver to attempt to login using those credentials as a service principal. More details on how to create a service prinicpal for authentication can be found here
- Device Code Flow
Setting the environment variables
CNAB_AZURE_TENANT_ID will cause the driver to use the Azure Device Code flow, you need to set the AZURE_APP_ID variable to the applicationId of a native application that has been registered with Azure AAD and has access to read user profiles from Azure Graph. To register an application see the documentation here and here
If the driver is running in Azure CloudShell it will automatically login using the logged in users token if no environment variables are set.
If the driver is running in an environment where MSI is available (such as in a VM in Azure) , it will attempt to login using MSI, no configuration is necessary, the driver will detect the MSI endpoint and use it if it is available.
- az cli
If the driver is running in an environment where az CLI is available then the driver will attempt to get an OAuth token using the CLI.
ACI Container Group Identity
By default the ACI Container Group that is created to run the invocation image has no identity, in order to perform authenticated actions against resources credentials need to be presented to the invocation image. It is possible to have the ACI Container Group that executes the invocation image use Managed Service Identity(MSI) . This enables the invocation image to be able to access the token for this identity and use it for bundle actions. The driver supports both System Assigned and User Assigned MSI. To use system assigned MSI set the environment variable
system. If no other environment variables are set the MSI will be assigned the Contributor role at the scope of the Resource Group that the ACI Container Group is created in, to override this behaviour the environment variable
CNAB_AZURE_SYSTEM_MSI_ROLE can be set to the role required and
CNAB_AZURE_SYSTEM_MSI_SCOPE can be set to set the scope for the assignment. Note that when using System MSI in order to prevent a race condition between code in the bundle that relies on permissions being allocated to the MSI and the assignment of required permissions to the MSI the Container Group is first created using an alpine image. This allows for the system assigned MSI to be created and permissions assigned, once this is done the invocation image is launched. To use User Assigned MSI
CNAB_AZURE_MSI_TYPE should be set to
user and environment variable
CNAB_AZURE_USER_MSI_RESOURCE_ID should be set to the Resource Id of the User Assigned MSI. You can also set the variable
CNAB_AZURE_PROPAGATE_CREDENTIALS to propagate the Azure OAuth token from the local environment to the container in the environment variable
Resource Group and Location for the Container Group
The ACI Driver requires at least either
CNAB_AZURE_RESOURCE_GROUP to be set to the name of an existing resource group or
CNAB_AZURE_LOCATION to be set to the name of the region in which the ACI Container Group used to run the installation image will be created, however if running in CloudShell and neither of these values are set it will derive
CNAB_AZURE_LOCATION from the default location set in the users az cli defaults (you can set this using
az configure -d location=<location>) otherwise it will use the users CloudShell location. The driver will create a new resource group in the region specified by the environment variable
CNAB_AZURE_LOCATION if the environment variable
CNAB_AZURE_RESOURCE_GROUP is not set or if the resource group specified in
CNAB_AZURE_RESOURCE_GROUP does not exist. If
CNAB_AZURE_RESOURCE_GROUP is not set the name of the resource group will be auto-generated. If the resource group specified in
CNAB_AZURE_RESOURCE_GROUP already exists then that resource group will be used. If the
CNAB_AZURE_RESOURCE_GROUP exists and
CNAB_AZURE_LOCATION is unset then the location of
CNAB_AZURE_RESOURCE_GROUP will be used as for the location of the resources. The invocation image is also free to create resources in this resource group if it can acquire the correct permissions.
ACI Container Group and Container Instance Naming
The container group and the container instance use the value of the environment variable
CNAB_AZURE_NAME for their names, if this is not set then a name is generated automatically, prefixed with
cnab-, it is not possible to use different names for the group and the container, they will always use the same name.
By default the driver will delete the container group that it creates and also the resource group if it creates it (pre-existing resource groups are not deleted), this behaviour can be changed by setting the environment variable
CNAB_AZURE_DO_NOT_DELETE to true. This can be useful for debugging or if you know that the invocation image is going to create resources in the same resource group. The container group property
restartPolicy is set to
Debugging the Invocation Image
In order to debug issues with the execution of the invocation set the environment variable
CNAB_AZURE_DEBUG_CONTAINER to true, this will cause the command
tail -f \dev\nullto be run in the container, you can then connect to the instance by executing
az container exec -g <resource-group-name> -n <container-group-instance> --exec-command /bin/sh. You can find the resource group and container name in the log file.
Dealing with Bundle Outputs
Some bundles create outputs, the driver captures these in an Azure File Share, the details of the file share to be user should be provided in the environment variables
CNAB_AZURE_STATE_FILESHARE,CNAB_AZURE_STATE_STORAGE_ACCOUNT_NAME ,CNAB_AZURE_STATE_STORAGE_ACCOUNT_KEY, in CloudShell the users clouddrive is used for these data.
|CNAB_AZURE_VERBOSE||Verbose output - set to true to enable|
|CNAB_AZURE_CLIENT_ID||AAD Client ID for Azure account authentication - used to authenticate to Azure using Service Principal for ACI creation|
|CNAB_AZURE_CLIENT_SECRET||AAD Client Secret for Azure account authentication - used to authenticate to Azure using Service Principal for ACI creation|
|CNAB_AZURE_TENANT_ID||Azure AAD Tenant Id Azure account authentication - used to authenticate to Azure using Service Principal or Device Code for ACI creation|
|CNAB_AZURE_APP_ID||Azure Application Id - this is the application to be used when authenticating to Azure using device flow|
|CNAB_AZURE_SUBSCRIPTION_ID||Azure Subscription Id - this is the subscription to be used for ACI creation, if not specified the first (random) subscription is used|
|CNAB_AZURE_RESOURCE_GROUP||The name of the existing Resource Group to create the ACI instance in, if not specified a Resource Group will be created, if specified and it does not exist a new resource group with this name will be created|
|CNAB_AZURE_LOCATION||The location in which to create the ACI Container Group and Resource Group|
|CNAB_AZURE_NAME||The name of the ACI instance to create - if not specified a name will be generated|
|CNAB_AZURE_DELETE_RESOURCES||Set to false so as not to delete the RG and ACI container group created, default is true - useful for debugging - only deletes RG if it was created by the driver|
|CNAB_AZURE_MSI_TYPE||This can be set to either
|CNAB_AZURE_PROPAGATE_CREDENTIALS||Default false. If this is set to true and MSI is not being used then any credentials set\used to create the ACI instance are also propagated to the invocation image in an ENV variable as follows :
Tenant and subscription details used are presented to the invocation image container as follows
In addition if the driver uses CloudShell or az cli for authentication then the ADAL Token used by those tools will be propagated as a json object in the environment variable
|CNAB_AZURE_USE_CLIENT_CREDS_FOR_REGISTRY_AUTH||If this is set to true then
|CNAB_AZURE_REGISTRY_USERNAME||Username to authenticate to Registry for invocation image|
|CNAB_AZURE_REGISTRY_PASSWORD||Password to authenticate to Registry for invocation image|
|CNAB_AZURE_STATE_FILESHARE||The File Share for Azure State volume|
|CNAB_AZURE_STATE_STORAGE_ACCOUNT_NAME||The Storage Account for the Azure State File Share|
|CNAB_AZURE_STATE_STORAGE_ACCOUNT_KEY||The Storage Key for the Azure State File Share|
|CNAB_AZURE_STATE_PATH||The local path relative to the mount point where state can be stored - this is combined with the state mount point and set as environment variable
|CNAB_AZURE_DELETE_OUTPUTS_FROM_FILESHARE||Bundle outputs are written to an Azure file share, setting this variable to false will cause the driver not to clean these up after the action is finished.|
|CNAB_AZURE_DEBUG_CONTAINER||Setting this to true enables connection to the container instance to debug issues, it causes the command /cnab/app/run with tail -f /dev/null to be run in the invocation image.|