How to set environment variables in a Container App using the Azure CLI

Posted by Jason on Sunday, March 20, 2022

Last month when I presented on Azure Container Apps, I was asked “How would you set an environment variable?”. Since it isn’t currently surfaced in the Azure Portal, I wasn’t sure.

Container Apps is still in preview and right now the best way to access the largest amount of features is by using ARM or Bicep … but since it is new a lot of people start with the Portal or the Azure CLI to explore.

In this short post, I want to capture how I should have answered the question during my demo.

How can I pass environment variables to a Container App?

If you look through the documentation, you can find an exmple of environment variables being set in the Manage Secrets Example page.

Screenshot of documentation example

In that example they are focusing on secrets, but since secrets get surfaced in the running container as environment variables the documentation is also relevant to just environment variables.

For this example I’ve put an ASP.NET .NET 6 application in the Docker.io repository that lists all the environment variables in running container - this is so you can follow along.

Assuming you don’t have a Container App Environment up and running, run these commands to get things setup:

az login --use-device-code

RESOURCE_GROUP="rg-envdemo"
LOCATION="eastus2"
LOG_ANALYTICS_WORKSPACE="law-envdemo"
CONTAINERAPPS_ENVIRONMENT="env-envdemo"
CONTAINERAPPS_NAME="envar"

az group create \
  --name $RESOURCE_GROUP \
  --location $LOCATION

az monitor log-analytics workspace create \
  --resource-group $RESOURCE_GROUP \
  --workspace-name $LOG_ANALYTICS_WORKSPACE

LOG_ANALYTICS_WORKSPACE_CLIENT_ID=`az monitor log-analytics workspace show --query customerId -g $RESOURCE_GROUP -n $LOG_ANALYTICS_WORKSPACE -o tsv | tr -d '[:space:]'`
LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET=`az monitor log-analytics workspace get-shared-keys --query primarySharedKey -g $RESOURCE_GROUP -n $LOG_ANALYTICS_WORKSPACE -o tsv | tr -d '[:space:]'`

az containerapp env create \
  --name $CONTAINERAPPS_ENVIRONMENT \
  --resource-group $RESOURCE_GROUP \
  --logs-workspace-id $LOG_ANALYTICS_WORKSPACE_CLIENT_ID \
  --logs-workspace-key $LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET \
  --location "$LOCATION"

Once you’ve run the above commands, the Container App Environment should be created and you should see output like the following (or the more detailed json output):

DefaultDomain                                       Kind                  KubeEnvironmentType    Location    Name         ProvisioningState    ResourceGroup    StaticIp  
--------------------------------------------------  --------------------  ---------------------  ----------  -----------  -------------------  ---------------  -------------
wittyisland-62d640a8.eastus2.azurecontainerapps.io  containerenvironment  Managed                eastus2     env-envdemo  Succeeded            rg-envdemo       20.80.208.216

Next set some variables for demo data and the registry image:

CONNECTIONSTRING='connection string goes here'
LOGLEVEL='Info'
IMAGE='jasonhaley/envarweb:latest'
REGISTRY='docker.io'

In order to show the secret is surfaced as an environment variable, I’ve also added a secret (and secret ref using it) to the following command that creates a container app:

az containerapp create \
  --name $CONTAINERAPPS_NAME \
  --resource-group $RESOURCE_GROUP \
  --environment $CONTAINERAPPS_ENVIRONMENT \
  --image $REGISTRY/$IMAGE \
  --target-port 80 \
  --ingress 'external' \
  --secrets "connection-string-secret=$CONNECTIONSTRING" \
  --environment-variables "LOG_LEVEL=$LOGLEVEL,CONNECTION_STRING=secretref:connection-string-secret"

Once the container app is created you can get a list of all revisons and the FQDN by running this command:

az containerapp revision list \
  --name $CONTAINERAPPS_NAME \
  --resource-group $RESOURCE_GROUP \
  --query "[].{Name:name,DateCreated:createdTime,ProvisionStatus:provisioningState,Traffic:trafficWeight,Active:active,FQDN:fqdn}"

If you put the FQDN in your browser you should see a listing of all the environment variables and their values. In the image below, I have highlighted the LOG_LEVEL and CONNECTION_STRING environment variables in that list.

Screenshot of environment variable listing

Ok, now you’ve created a Container App passing it a couple of evironment variables, now how to you modify it? For example: change the LOG_LEVEL to Verbose

This can be done using the az containerapp update command.

Run the following command to change the LOG_LEVEL environment variable value and create a new revision:

az containerapp update \
  --name $CONTAINERAPPS_NAME \
  --resource-group $RESOURCE_GROUP \
  --environment-variables "LOG_LEVEL=Verbose"

Once the command completes, run the command to get the revision list again:

az containerapp revision list \
  --name $CONTAINERAPPS_NAME \
  --resource-group $RESOURCE_GROUP \
  --query "[].{Name:name,DateCreated:createdTime,ProvisionStatus:provisioningState,Traffic:trafficWeight,Active:active,FQDN:fqdn}"

There should now be a couple of revisions:

Name            DateCreated                ProvisionStatus    Traffic    Active    FQDN
--------------  -------------------------  -----------------  ---------  --------  -----------------------------------------------------------------
envar--1al6ohi  2022-03-20T19:17:49+00:00  Provisioned        0          True      envar--1al6ohi.wittyisland-62d640a8.eastus2.azurecontainerapps.io
envar--2k02yao  2022-03-20T19:31:32+00:00  Provisioned        100        True      envar--2k02yao.wittyisland-62d640a8.eastus2.azurecontainerapps.io

Again, you can check the list of environment variables by copying the FQDN of the individual revision to see the differences. The original still has the old value of LOG_LEVEL=Info but the new one has the Verbose value

Screenshot of environment variable listing

Don’t forget to clean up your resources and delete the resource group when you are done exploring:

az group delete --name $RESOURCE_GROUP

BTW: Secrets have the option of being able to change the value and just restarting existing revision in order to get the new value. If I find a way to do that with environment variables, I’ll update this post.