0

Currently I'm using azure devops to deploy an app container to azure.

I've created my release pipeline and added each ENVIRONMENT VARIABLE manually through the interface.

I wondering if is there any way to get it dynamically, I mean add the environment variables with a given prefix and add to the command.

Currently this is the command that I'm using:

az containerapp create --resource-group $(ResourceGroupName) --name $(ContainerAppName) --container-name $(ContainerAppName) --environment $(CONTAINERAPPS_ENVIRONMENT) --cpu $(ContainerCpu) --memory $(ContainerMemory) --min-replicas $(MinReplicas) --max-replicas $(MaxReplicas)  --ingress $(IngressType) --target-port $(IngressPort) --registry-server $(RegistryServer) --registry-username $(RegistryUsername) --registry-password $(RegistryPasswordSecretName)  --secrets $(PasswordSecretName)=$(RegistryPassword) --image  $(ContainerImage) --env-vars ENV_ENVIRONMENT_NAME_PREFIX=$(ENV_ENVIRONMENT_NAME_PREFIX) ENV_CLIENT_CONFIG_PATH=$(ENV_CLIENT_CONFIG_PATH)

To summarize it, get all VARIABLES with prefixed name ENV_ and pass it to --env-vars

Important addition: Not all variables are simple strings, some are json blobs and may contain spaces as well as unescaped quotes:

\"{\"type\":\"service_account\",\"project_id\":\"projectID\",\"private_key_id\":\"PRIVATEREGISTRYID\",\"private_key\":\"-----BEGIN PRIVATE KEY-----\nPRIVATEKEYHASH\n-----END PRIVATE KEY-----\n\",\"client_email\":\"publisher@email.iam.gserviceaccount.com\",\"client_id\":\"11132670678102951289\",\"auth_uri\":\"https:\/\/accounts.google.com\/o\/oauth2\/auth\",\"token_uri\":\"https:\/\/oauth2.googleapis.com\/token\",\"auth_provider_x509_cert_url\":\"https:\/\/www.googleapis.com\/oauth2\/v1\/certs\",\"client_x509_cert_url\":\"https:\/\/www.googleapis.com\/robot\/v1\/metadata\/x509\/az-fellipelli-publisher%40codescovery-default.iam.gserviceaccount.com\"}\"

UPDATE

I've done some tests and so far I've ended up with the following approach

formatted_env_vars=$(env | grep '^ENV_' | while read -r line; do
  KEY=$(echo "$line" | cut -d '=' -f 1)
  VALUE=$(echo "$line" | cut -d '=' -f 2-)
  echo "${KEY}=\"${VALUE}\""
done | tr '\n' ' ')
az containerapp create --resource-group $(ResourceGroupName) --name $(ContainerAppName) --container-name $(ContainerAppName) --environment $(CONTAINERAPPS_ENVIRONMENT) --cpu $(ContainerCpu) --memory $(ContainerMemory) --min-replicas $(MinReplicas) --max-replicas $(MaxReplicas)  --ingress $(IngressType) --target-port $(IngressPort) --registry-server $(RegistryServer) --registry-username $(RegistryUsername) --registry-password $(RegistryPasswordSecretName)  --secrets $(PasswordSecretName)=$(RegistryPassword) --image  $(ContainerImage) --env-vars ENVIRONMENT_NAME_PREFIX=$(ENVIRONMENT_NAME_PREFIX) CLIENT_CONFIG_PATH=$(CLIENT_CONFIG_PATH) "$formatted_env_vars"

This command results something like:

az containerapp create --resource-group my-resource-group --name my-app-name --container-name my-app-name --environment my-environment --cpu 0.25 --memory 0.5Gi --min-replicas 0 --max-replicas 1  --ingress external --target-port 80 --registry-server gcr.io --registry-username _json_key --registry-password secretref:registrypassword  --secrets registrypassword={"type":"service_account","project_id":"my-project-id","private_key_id":"ecd532a427a221bb5e95e6433a27723b25413392","private_key":"-----BEGIN PRIVATE KEY-----nMIIEvgIDCBENBhqkgkiG9w0BAQFEABSCBKgwggSkAgEAAoIBAQC0FPeHr6LlOibbnNUUsNzJfKNED7eZ6PT71UesZ8blWn2C2FWP7wI7OrfE19FtF8Jt6RP8J2x2jSafmnuR0FmNH1tkWuq+BenZjaefW/a9LAYzdKspq9Ob4caNYXbBNvJ6xrn+x6+m3TGg6nJXDlAmV+FRYAePdHJ+uanfZUx1e2HfGSswCczMSevTXSNU+6VKnmtL2hg1uam3ywnp2VoMleY2dkrAV2xqAJDnAV21oC57MAi5kEryRYNtzaP40m87Csl0g31VNjn9Acfn4cMsHhoM/LBL5AQwklQstJMVk4dJGfLBOi46G8BES0zuGVrLBY72dUjz3EHiIc3Kn54Fn1eedAgMBAAECggEACiDbwy/oD6kXnri8ST5ZgOykxNnOirWDIv0WggEZCrwwnDpWLmSrSL06gI1wYFVCuyMu/ZHQ7L3fE4lkt3DGeJ943m4WodVnT6sd8GKVwBIHzn0ESl2dooW3TYwRGT5uti6Y9s8y7XmE2d1xdgACFgX/UDpccn8UKXh7y2rBICJuXzn1wG4zIrb9bukysxbC1f55MdqWAHhmGY2EiCRMQ1iABh8cueZffRb25MqN/quqdNPnEJ3eZ5AXo1kgb+JE85f6T8UxGBbV8NhYn4EBHoO3QDS8EPk+QnyBcTN6TWqB+Za3nfTBW878dbljFEtg8cvUJel1xR2QiiVoOYORntlCJaQKBgQD3/Vs0kHfxmElCHpEmn6ResBMDNgQNvtP86825QYjnVobqpujsoT3Oq7HZrFdnrtncE5BwDonLfMzIpNwWnnb3Z0AoZKNL7UK1tWk7uoLLMqcgK6cJ1uPhzZ9jDQLl/kQzF1UMcZ7qKzKMDORGX7nxrW2drV+Hl6sR2vJ+5eNvs7SbwKBgQC55hOb1IQES4QHQakIMh9RumnKG3vILdqXnjux0Vn7BM+2PDHtzXaGIYMyUdyYR2lijf3RTqWOaw6+16AbUmGdGpKZormT7uujfnyQPAvlpIpfNpuQOv8OC3Wd8ORBJ7JqQ2mtO/JAT8D02x8fqJ/oN83SrpeUyOar96npU8TjuV8swKBgQDbJ+a7PFUTh+5t5U+HoITP+19b/YDI7p6EPW8m0LelqQiqSC9Rnf22MBu7b0fLFEXp7Mw/i0mRMBhV1QO/ZOXLoMPb2i0h9fld42pQDmoU3pIvuseken7BsWG+5xfBo4Qn1p3None7IDHKevYdieuXgK6TuZWkN2YqPKW3JizNZANwKBgAvCnpGbtUNS8ukODQeBE23peIqcoifImBHgmEItjlW0/jb3I+l5YBAoOpaKWzw++EnF1ndLR+ONDnpEwLu7LjWVU8wVJKBhVuw6C0pMoiwK9r4DRGAhe1U2IGC3hpkgm8bhMOnRGsJKk+P4EhrmH/2W/cgPsC6bb9svWRS5OfF2HrFAoGBANG612EferWkG7jLrVpzniYabgP73yjRAjt+J3JLV3QW42JyXEh+fgJwU4A6mty9GxcNPogTsdz16PdFOG1YtndKHCZUP29i1hIG4BxgxxXjWDrfzH+mEdNg+80v2R5YTM0L2vHUMMU63VR603fl5En4OfBG5cnJ9A3RDeg6mRIGEMnn-----END PRIVATE KEY-----n","client_email":"publisher@registry.iam.gserviceaccount.com","client_id":"2222035690768105943154","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/publisher%registry.iam.gserviceaccount.com"} --image  gcr.io/registry/codescovery/my-site-vue3:0.1.245274 --env-vars ENVIRONMENT_NAME_PREFIX=ENV_ CLIENT_CONFIG_PATH=/app/client/configurations/settings.json ENV_SITE_CREATOR_NAME="Example Creator" ENV_SITE_NAME="Site Name" ENV_SITE_TITLE="My Site Title"

But apparently it's writing the dynamically variables into ENV_SITE_CREATOR_NAME only:

Azure Devops Log

Here are the environment variables in azure

Azure Devops Container Environment Variables

What I'm missing?

Update 2

According to @siddheshdesai Answer I got the following result

Aazure devops log

Container Instance

Vinicius Andrade
  • 151
  • 1
  • 4
  • 22
  • powershell? bash? – jessehouwing Mar 18 '23 at 20:03
  • Actually is an azure devops Release Task, it can be used wich can be used as `Type of script: PowerShell/PowerShell Core/Bat/Shell script. Select Shell/PowerShell Core script when running on Linux agent or Batch/PowerShell/PowerShell Core script when running on Windows agent. PowerShell Core script can run on cross-platform agents (Linux, macOS, or Windows).` – Vinicius Andrade Mar 18 '23 at 20:06
  • I know that, but do you have any preference? Is the current call in a PowerShell task? Are you on windows or on Linux? The reason I'm asking is because it's not really a azure-pipelines or azure-cli question, but a shell scripting question. – jessehouwing Mar 19 '23 at 07:47
  • Adding tags for bash and powershell core, since it seems you have no preference. Removing `azure` as the Q isn't related to a true azure problem. Replacing azure-devops with azure-pipelines, since it's more precise. – jessehouwing Mar 19 '23 at 08:33
  • 1
    Actually I don't have any preference, it's a Brand new release pipelines could be any one of them. I'll take a look at the answer you Just posted – Vinicius Andrade Mar 19 '23 at 19:03

3 Answers3

1

You can add the Environment variables in the Variables tab of Azure Release pipeline and then use it as an ENV_VAR in your pipeline, Refer below:-

enter image description here

And I used the same code as an environment variable in the inline script :-

az config set extension.use_dynamic_install=yes_without_prompt
az containerapp create --name $(ENV_ContainerAppName)  --resource-group $(ENV_ResourceGroupName) --cpu $(ENV_ContainerCpu) --memory $(ENV_ContainerMemory) --environment $(ENV_CONTAINERAPPS_ENVIRONMENT)

And the container app got deployed successfully like below:-

enter image description here

enter image description here

You can also add the same variables in the Variable group and use those variable group across multiple pipeline within your Azure DevOps project, Refer below:-

enter image description here

And reference it in any pipeline like below:-

enter image description here

enter image description here

In order to call the Environment variables dynamically, you can make use of below CLI commands in your Azure CLI task:-

Code 1:-

#!/bin/bash

# set the prefix for your environment variables
envPrefix="ENV_"

# get the list of environment variables that have the specified prefix
envVars=$(env | grep "^$envPrefix" | sed "s/^$envPrefix//")

# create a string of environment variables in the format "KEY=VALUE"
envVarsStr=""
for envVar in $envVars; do
  envVarVal=$(eval "echo \$$envVar")
  envVarsStr+="$envVar=$envVarVal "
done

# create a string with the environment variables argument for the az command
envVarsArg="--env-vars $envVarsStr"

# set the extension configuration
az config set extension.use_dynamic_install=yes_without_prompt

# create the container app with the specified environment variables
az containerapp create --name $ContainerAppName --resource-group $ResourceGroupName --cpu $ContainerCpu --memory $ContainerMemory --environment $CONTAINERAPPS_ENVIRONMENT $envVarsArg

Code 2:-

#!/bin/bash

# Set the prefix for your environment variables
envPrefix="ENV_"

# Retrieve environment variables dynamically
containerAppName=${!envPrefix"CONTAINERAPP_NAME"}
resourceGroupName=${!envPrefix"RESOURCE_GROUP_NAME"}
containerCpu=${!envPrefix"CONTAINER_CPU"}
containerMemory=${!envPrefix"CONTAINER_MEMORY"}
containerAppsEnvironment=${!envPrefix"CONTAINERAPPS_ENVIRONMENT"}

# Retrieve environment variables that start with the prefix
envVars=()
while IFS='=' read -r key value; do
  envVars+=("$key=$value")
done < <(env | grep "^$envPrefix")

# Join the environment variables with a space
envVarsArg="--env-vars ${envVars[*]}"

# Set the Azure CLI extension configuration
az config set extension.use_dynamic_install=yes_without_prompt

# Create the Azure Container App
az containerapp create \
  --name "$containerAppName" \
  --resource-group "$resourceGroupName" \
  --cpu "$containerCpu" \
  --memory "$containerMemory" \
  --environment "$containerAppsEnvironment" \
  $envVarsArg

Above codes gets the required environment variables dynamically and sets them to the desired variables. Then it retrieves the variable that start with "ENV_" and joins them with space and creates envVarsArg variable. Then it uses Azure CLI extension config to create Azure container app with retrieved variable.

Output:-

enter image description here

enter image description here

Updated code:-

# set the prefix for your environment variables
envPrefix="ENV_"

# get the list of environment variables that have the specified prefix
envVars=$(env | grep "^$envPrefix" | sed "s/^$envPrefix//")

# create a string of environment variables in the format "KEY=VALUE"
envVarsStr=""
for envVar in $envVars; do
  envVarVal=$(eval "echo \$$envVar")
  
  # if the value of the environment variable contains spaces, enclose it in quotes
  if [[ "$envVarVal" == *" "* ]]; then
    envVarVal="\"$envVarVal\""
  fi
  
  envVarsStr+="$envVar=$envVarVal "
done

# create a string with the environment variables argument for the az command
envVarsArg="--env-vars $envVarsStr"

# set the extension configuration
az config set extension.use_dynamic_install=yes_without_prompt

# create the container app with the specified environment variables
az containerapp create --name $ContainerAppName --resource-group $ResourceGroupName --cpu $ContainerCpu --memory $ContainerMemory --environment $CONTAINERAPPS_ENVIRONMENT $envVarsArg

Updated code 2:-

# set the prefix for your environment variables
envPrefix="ENV_"

# get the list of environment variables that have the specified prefix
envVars=$(env | grep "^$envPrefix" | sed "s/^$envPrefix//")

# create an array of environment variables and their values
declare -a envVarsArr
for envVar in $envVars; do
  envVarVal=$(eval "echo \$$envVar")
  
  # if the value of the environment variable contains spaces, enclose it in quotes
  if [[ "$envVarVal" == *" "* ]]; then
    envVarVal="\"$envVarVal\""
  fi
  
  envVarsArr+=("$envVar=$envVarVal")
done

# join the elements of the array with spaces to create the envVarsStr variable
envVarsStr="${envVarsArr[@]}"

# create a string with the environment variables argument for the az command
envVarsArg="--env-vars $envVarsStr"

# set the extension configuration
az config set extension.use_dynamic_install=yes_without_prompt

# create the container app with the specified environment variables
az containerapp create --name $ContainerAppName --resource-group $ResourceGroupName --cpu $ContainerCpu --memory $ContainerMemory --environment $CONTAINERAPPS_ENVIRONMENT $envVarsArg
SiddheshDesai
  • 3,668
  • 1
  • 2
  • 11
  • You didn't get the point of the question. – Vinicius Andrade Mar 11 '23 at 16:18
  • Manually I know How to do It. I need to get It dynamically, because I've too many variables(too many release pipelines) and I can't take the risk of missing one variable – Vinicius Andrade Mar 11 '23 at 16:20
  • @ViniciusAndrade Check the updated answer? I've added some additional commands that you can pass in your CLI to retrieve the value of Environment variables dynamically. – SiddheshDesai Mar 11 '23 at 19:22
  • Sorry taking to long to answer, I wasn't in my development PC. Currently I'm getting the following error: `ERROR: Environment variables must be in the format "= =secretref: ..."` – Vinicius Andrade Mar 13 '23 at 18:42
  • Here is the --env-vars parameter `--env-vars ENVIRONMENT_NAME_PREFIX=ENV_ CLIENT_CONFIG_PATH=/app/client/configurations/settings.json ENV_SITE_CREATOR_NAME="TESTE CREATOR" ENV_SITE_NAME=Test ENV_SITE_DESCRIPTION=test` – Vinicius Andrade Mar 13 '23 at 19:02
  • Do you have any ideas? – Vinicius Andrade Mar 14 '23 at 20:56
  • @ViniciusAndrade Are the env variables in this format ? az container create -g MyResourceGroup --name myapp --image myimage:latest --environment-variables key1=value1 key2=value2' – SiddheshDesai Mar 15 '23 at 11:42
  • Here is the --env-vars parameter part of the command `--env-vars ENVIRONMENT_NAME_PREFIX=ENV_ CLIENT_CONFIG_PATH=/app/client/configurations/settings.json ENV_SITE_CREATOR_NAME="TESTE CREATOR" ENV_SITE_NAME=Test ENV_SITE_DESCRIPTION=test` – Vinicius Andrade Mar 15 '23 at 16:35
  • I think the main problem is the variable ENV_SITE_CREATOR_NAME. But in docs the say we can pass a variable with KEY="VALUE" – Vinicius Andrade Mar 15 '23 at 16:50
  • Looking at your assignment to `formatted_env_vars` you find your vars with `grep`, then split them on `=` and then immediately recombine them with `echo` ? As far as I can tell, the only thing that actually does something is the `tr '\n' ' '` – Christian Bongiorno Mar 23 '23 at 15:52
  • The tr '\n' ' ' command removes any new line characters from the final envVarsStr – SiddheshDesai Mar 23 '23 at 16:15
  • Can you try this command- envVarsStr="" for envVar in $envVars; do envVarVal=$(eval "echo \$$envVar") # if the value of the environment variable contains spaces, enclose it in quotes if [[ "$envVarVal" == *" "* ]]; then envVarVal="\"$envVarVal\"" fi envVarsStr+="$envVar=$envVarVal " done # create a string with the environment variables argument for the az command envVarsArg="--env-vars $envVarsStr" – SiddheshDesai Mar 23 '23 at 16:17
  • and then this - # set the extension configuration az config set extension.use_dynamic_install=yes_without_prompt # create the container app with the specified environment variables az containerapp create --name $ContainerAppName --resource-group $ResourceGroupName --cpu $ContainerCpu --memory $ContainerMemory --environment $CONTAINERAPPS_ENVIRONMENT $envVarsArg – SiddheshDesai Mar 23 '23 at 16:17
  • @ViniciusAndrade Added the updated code in my answer – SiddheshDesai Mar 23 '23 at 16:20
  • I've tested your answer, It's very close to what i need. but when the variable value contains spaces it is getting loss. – Vinicius Andrade Mar 23 '23 at 18:32
  • I'm updating the question so yo can see the results – Vinicius Andrade Mar 23 '23 at 18:33
  • @ViniciusAndrade Check the Updated code 2 in my answer? – SiddheshDesai Mar 24 '23 at 07:20
  • Yes, I've updated my question with some information regarding your answer – Vinicius Andrade Mar 24 '23 at 09:06
  • @ViniciusAndrade I have updated a new code in my answer at last refer Updated code 2? Did you try that to avoid the space loss? – SiddheshDesai Mar 24 '23 at 10:09
  • Yes, as I posted in the updated question: it's creating the variables the wrong way. Please take a look in ** Update 2 ** in my question – Vinicius Andrade Mar 24 '23 at 17:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/252755/discussion-between-vinicius-andrade-and-siddheshdesai). – Vinicius Andrade Mar 24 '23 at 17:47
1

Try this

#!/bin/bash

# Get all environment variables with prefix "ENV_"
# Initialize variable
ENV_VARS=""

# Loop through all environment variables
while IFS= read -r var
do
  # Check if the variable starts with ENV_
  if [[ "$var" == ENV_* ]]; then
    # Extract the variable name and value
    name=$(echo "$var" | cut -d '=' -f 1 | sed 's/^//')
    value=$(echo "$var" | cut -d '=' -f 2-)

    # Escape any single quotes in the value
    value="${value//\'/\'\\\'\'}"

    # Append the variable and its value to the result
    ENV_VARS+=" $name='$value'"
  fi
done <<< "$(env)"

# Create the container app in Azure
echo "Creating container app $CONTAINERAPP_NAME in Azure..."
az containerapp create \
  --name $CONTAINERAPP_NAME \
  --resource-group my_resource_group \
  --image $IMAGE_NAME \
  --env-vars $ENV_VARS
scorpio
  • 1,587
  • 2
  • 15
  • 27
  • Didn't work, but I think this is something like this. I couldn't use the `<(echo "$ENV_VARS")` command, I used just `"$ENV_VARS"` . And this is the output of the command writing the envirionment variables to the container: `"value": "creator\nENV_SITE_NAME=Test\nENV_SITE_TITLE=\"testeeeer a\""` – Vinicius Andrade Mar 18 '23 at 17:08
  • probably need a bit of fine tuning the command.. will have a look – scorpio Mar 18 '23 at 17:11
  • try the updated command - that may work – scorpio Mar 18 '23 at 17:17
  • Just triggered the pipeline, It will take about 5 minutes to finish. Can we move this to a chat? I think would be better to sharing logs and images – Vinicius Andrade Mar 18 '23 at 17:20
  • Now I've got the following error: ` ERROR: Environment variables must be in the format "= =secretref: ..."` – Vinicius Andrade Mar 18 '23 at 17:23
  • This problem apparently happens when I try to set a multi string value to a variable, like: **ENV_SITE_TITLE="testeeeer a"** but according to this command: `az containerapp create -n MyContainerapp -g MyResourceGroup \ --image my-app:v1.0 --environment MyContainerappEnv \ --secrets mysecret=secretvalue1 anothersecret="secret value 2" \ --env-vars GREETING="Hello, world" SECRETENV=secretref:anothersecret` From [Microsfot Docs](https://learn.microsoft.com/en-us/cli/azure/containerapp?view=azure-cli-latest#az-containerapp-create) this is possible – Vinicius Andrade Mar 18 '23 at 17:30
  • updated answer to take care of space in the environment variable value – scorpio Mar 18 '23 at 19:50
  • Still having the same problem. Did you try running it with a multi word string? I've just printed the command used, here is the final results `az containerapp create --resource-group non-production --name site --container-name site3 --environment non-production --cpu 0.25 --memory 0.5Gi --min-replicas 0 --max-replicas 1 --ingress external --target-port 80 --image imageName --env-vars ENVIRONMENT_NAME_PREFIX=ENV_ CLIENT_CONFIG_PATH=/app/client/configurations/settings.json ENV_SITE_CREATOR_NAME=creator ENV_SITE_NAME=Test ENV_SITE_TITLE="testeeeer a"` – Vinicius Andrade Mar 18 '23 at 20:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/252597/discussion-between-vinicius-andrade-and-scorpio). – Vinicius Andrade Mar 18 '23 at 20:25
1

In powershell, you can grab all the environment variables and then buid the string with which you call the azure cli:

gci env:*

Filtering that down to all variables starting with ENV_:

gci env:* | ?{ $_.name -like "ENV_*" }

That leaves us with building the string to pass to azure-cli:

((gci env:* | ?{ $_.name -like "ENV_*" }) | %{ "$($_.name)=$($_.value)" }) -join " "

And then we're left with the quoting issue. I'm not 100% sure how azure-cli wants its quotes, "abc=def ghi" or abc="def ghi", but that's easy to add in:

# either: "abc=def ghi"
((gci env:* | ?{ $_.name -like "ENV_*" }) | %{ "`"$($_.name)=$($_.value)`"" }) 

# Or abc="def ghi"
((gci env:* | ?{ $_.name -like "ENV_*" }) | %{ "$($_.name)=`"$($_.value)`"" })

Then call azure-cli:

& az containerapp create `
   --resource-group $(ResourceGroupName) `
   --name $(ContainerAppName) `
   --container-name $(ContainerAppName) `
   --environment $(CONTAINERAPPS_ENVIRONMENT) `
   --cpu $(ContainerCpu) --memory $(ContainerMemory) `
   --min-replicas $(MinReplicas) --max-replicas $(MaxReplicas)  `
   --ingress $(IngressType) `
   --target-port $(IngressPort) `
   --registry-server $(RegistryServer) --registry-username $(RegistryUsername) --registry-password $(RegistryPasswordSecretName) `
   --secrets "$(PasswordSecretName)=$(RegistryPassword)" `
   --image  $(ContainerImage) `
   --env-vars ((gci env:* | ?{ $_.name -like "ENV_*" }) | %{ "`"$($_.name)=$($_.value)`"" })

Or build the whole string and then calling it through invoke-expression:

$envVars = ((gci env:* | ?{ $_.name -like "ENV_*" }) | %{ "`"$($_.name)=$($_.value)`"" }) -join " "
$command = "& az containerapp create `
   --resource-group $(ResourceGroupName) `
   --name $(ContainerAppName) `
   --container-name $(ContainerAppName) `
   --environment $(CONTAINERAPPS_ENVIRONMENT) `
   --cpu $(ContainerCpu) --memory $(ContainerMemory) `
   --min-replicas $(MinReplicas) --max-replicas $(MaxReplicas)  `
   --ingress $(IngressType) `
   --target-port $(IngressPort) `
   --registry-server $(RegistryServer) --registry-username $(RegistryUsername) --registry-password $(RegistryPasswordSecretName) `
   --secrets `"$(PasswordSecretName)=$(RegistryPassword)`" `
   --image $(ContainerImage) `
   --env-vars $envVars"

iex $command # invoke expression

To pass variables to Powershell in a safer manner, you can use:

- powershell: |
      & az .... $env:RegistryUsername
    env:
      RegistryUsername: $(RegistryUsername)

Or in UI based pipelines and releases:

Pass variables through the environment section

This usually simplifies many of the quoting issues since PowerShell will know how to pass the contents of the variable safely to the invocation of az, where as when you inline the azure pipelines variable reference, the contents will be added to the script without context. I'm not aware of any clear docs on the dangers, but here's a doc from the GitHub Actions team that explains the potential issue. This applies to Azure Pipelines as well.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
  • by the way, do all of these things have to be an Azure Pipelines variable? I wonder whether some of these values could simply be hard-coded in the script just to make things easier. – jessehouwing Mar 19 '23 at 08:45
  • I prefer to be in pipeline, so I don't have to mantain a separated script file and commit the code everytime I need to change it. – Vinicius Andrade Mar 19 '23 at 19:25
  • I've just ran the script using `--env-vars ((gci env:* | ?{ $_.name -like "ENV_*" }) | %{ "\`"$($_.name)=$($_.value)\`"" }) -join " " and I got the following Error: `ERROR: unrecognized arguments: -join ` – Vinicius Andrade Mar 19 '23 at 19:26
  • Then I added a () to wrap the command and got the following message: `ERROR: Secrets must be in format "= = ...` – Vinicius Andrade Mar 19 '23 at 19:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/252605/discussion-between-vinicius-andrade-and-jessehouwing). – Vinicius Andrade Mar 19 '23 at 19:41