Need instructions on how to pass in --tags as a single argument to az cli
# Command line
Please note the "c=a dog"
The following works from the command line
az group create --name "rg-terraform-lionking" --tags "a=b" "c=a dog" --location "eastus2"
{
"id": "/subscriptions/**REDACTED**/resourceGroups/rg-terraform-lionking",
"location": "eastus2",
"managedBy": null,
"name": "rg-terraform-lionking",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"a": "b",
"c": "a dog"
},
"type": "Microsoft.Resources/resourceGroups"
}
The following does not work;
tags='"a=b" "c=a dog"'
echo $tags
"a=b" "c=a dog"
az group create --name "rg-terraform-lionking" --tags $tags --location "eastus2"
{
"id": "/subscriptions/39ac48fb-fea0-486a-ba84-e0ae9b06c663/resourceGroups/rg-terraform-lionking",
"location": "eastus2",
"managedBy": null,
"name": "rg-terraform-lionking",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"\"a": "b\"",
"\"c": "a",
"dog\"": ""
},
"type": "Microsoft.Resources/resourceGroups"
}
az group create --name "rg-terraform-lionking" --tags "${tags}" --location "eastus2"
{
"id": "/subscriptions/39ac48fb-fea0-486a-ba84-e0ae9b06c663/resourceGroups/rg-terraform-lionking",
"location": "eastus2",
"managedBy": null,
"name": "rg-terraform-lionking",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"\"a": "b\" \"c=a dog\""
},
"type": "Microsoft.Resources/resourceGroups"
}
Oddly enough, the following works if there is no spaces, but chokes on quotes:
tags='a=b c=dog'
echo $tags
a=b c=dog
az group create --name "rg-terraform-lionking" --tags $tags --location "eastus2"
{
"id": "/subscriptions/39ac48fb-fea0-486a-ba84-e0ae9b06c663/resourceGroups/rg-terraform-lionking",
"location": "eastus2",
"managedBy": null,
"name": "rg-terraform-lionking",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"a": "b",
"c": "dog"
},
"type": "Microsoft.Resources/resourceGroups"
}
# FAILS - adds quotes
tags='"a=b" "c=dog"'
echo $tags
"a=b" "c=dog"
{
"id": "/subscriptions/39ac48fb-fea0-486a-ba84-e0ae9b06c663/resourceGroups/rg-terraform-lionking",
"location": "eastus2",
"managedBy": null,
"name": "rg-terraform-lionking",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"\"a": "b\"",
"\"c": "dog\""
},
"type": "Microsoft.Resources/resourceGroups"
}
Pass in tags to a bash script.
tags='"a=b" "c=a dog"'
bash ./az-create-group.sh rg-terraform-lionking eastus2 "${tags}"
My Script
#!/bin/sh -l
die () {
echo >&2 "$@"
echo "die"
exit 1
}
# This works
# az group create --name "rg-terraform-lionking" --location "eastus2" --tags "a=b" "c=a dog"
REQUIRED_ARGS=3
[ "$#" -eq $REQUIRED_ARGS ] || die "$REQUIRED_ARGS argument required, $# provided"
bash --version
resource_group_name=$1
location=$2
tags=$3
echo "resource_group_name:" $resource_group_name
echo "location:" $location
echo "tags" $tags
az group create --name "$resource_group_name" --location "$location" --tags "${tags}"
Output
{
"id": "/subscriptions/**REDACTED**/resourceGroups/rg-terraform-lionking",
"location": "eastus2",
"managedBy": null,
"name": "rg-terraform-lionking",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"\"a": "b\" \"c=a dog\""
},
"type": "Microsoft.Resources/resourceGroups"
}
So I don't know if this is a defect or documentation request on how to get this working.
Linux-4.4.0-18362-Microsoft-x86_64-with-debian-buster-sid
Python 3.6.5
Installer: DEB
azure-cli 2.4.0
Extensions:
azure-devops 0.16.0
add to S170
@ghstahl Hi, my suggestion is to change the parameter variable of the tags to an array, and modify IFS distinguish between the spaces in the array and the spaces in each tag. Can this method solve your problem?
Example:
resource_group_name='ResourceGroupName'
location='westus'
tags=("key=val" "key2=val2 val3 val4")
IFS='*'
az group create --name "$resource_group_name" --location "$location" --tags ${tags[*]}
IFS=' '
@zhoxing-ms
Getting closer.
The tags need to be passed in as a single string via a github action
action-docker-azure-terraform-setup
- name: Terraform Setup Step
id: tfsetup
uses: ./
with:
shortName: 'lunchMeat'
location: 'eastus2'
creds: ${{ secrets.AZURE_CREDENTIALS }}
tags: 'owner=Firstname_Lastname application=cool-name'
NOTE: The way github actions passes in arguments to my entrypoint.sh is probably the constraint here which I can't change.
Its a github docker actions and here is my Entry Point
I have a simple test script that takes three arguments az-create-group
#!/bin/sh -l
die () {
echo >&2 "$@"
echo "die"
exit 1
}
# This works
# az group create --name "rg-terraform-lionking" --location "eastus2" --tags "a=b" "c=a dog"
REQUIRED_ARGS=3
[ "$#" -eq $REQUIRED_ARGS ] || die "$REQUIRED_ARGS argument required, $# provided"
bash --version
resource_group_name=$1
location=$2
tags=$3
echo "resource_group_name :" $resource_group_name
echo "location: " $location
echo "tags: " $tags
az group create --name "$resource_group_name" --location "$location" --tags $tags
```bash
resource_group_name='rg-lionking'
location='eastus2'
tags='owner=Firstname_Lastname application=cool-name'
./az-create-group.sh $resource_group_name $location $tags
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
resource_group_name : rg-lionking
location: eastus2
tags: owner=Firstname_Lastname application=cool-name
{
"id": "/subscriptions/39ac48fb-fea0-486a-ba84-e0ae9b06c663/resourceGroups/rg-lionking",
"location": "eastus2",
"managedBy": null,
"name": "rg-lionking",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"application": "cool-name",
"owner": "Firstname_Lastname"
},
"type": "Microsoft.Resources/resourceGroups"
}
````
At the moment I have banned all tags that have spaces in their values 馃憥
I don't know yet if the problem is on the github actions side to provide different ways to pass in an array with spaces in its values, or I haven't found a simple and easily understandable way to pass space valued array so that az cli likes it.
@ghstahl I suggest that you can pass the array data as a string, and modify IFS to define the separator of array elements to avoid confusion between the separator of array elements and the spaces contained in tag.
For example:
# mock the input data from yaml file
tags='a=b#c=a dog#sad=a dsa'
bash test.sh "$tags"
resource_group_name='zhoxing-test'
location='westus'
IFS='#'
tags=($1)
az group create --name "$resource_group_name" --location "$location" --tags ${tags[@]}
IFS=' '
What do you think of this solution?
Found a very useful tutorial: http://mywiki.wooledge.org/BashFAQ/050
This doesn't work:
tags='"a=b" "c=a dog"'
az group create --name "rg-terraform-lionking" --tags $tags --location "eastus2"
Because space is used for field splitting (see this stackoverflow answer) and
Quotes inside the variable are literal, not syntactical.
In general, passing multiple arguments ("a=b" and "c=a dog") within a single variable (tags) can be very nasty when it becomes complicated:
"a=b" "c=a dog"
^^ ^ ^
13 2 3
'"c=a' 'dog"')eval to parse double quotes$ tags='"a=b" "c=a dog"'
# This command is purely for showing what is going on inside Bash.
# $ help set
# -v Print shell input lines as they are read.
# -x Print commands and their arguments as they are executed.
$ set -vx
$ eval az $tags --debug
# This is the output from `-v`, which is the original command we typed
eval az $tags --debug
# This is the output from `-x`, showing spaces are used to separate arguments
# and double quotes are treated literally
+ eval az '"a=b"' '"c=a' 'dog"' --debug
----- ---- ----
# This is the output from `-v`, which is the command being executed by `eval`
# The arguments are concatenated by `eval` and double quotes will be parsed by Bash
az "a=b" "c=a dog" --debug
# This is the output from `-x`, showing arguments are correctly sent to `az`
++ az a=b 'c=a dog' --debug
# This is the output from `--debug`, showing arguments are correctly received by `az`
Command arguments: ['a=b', 'c=a dog', '--debug']
Or
$ eval az "$tags" --debug # Quote `$tags` this time
eval az "$tags" --debug
+ eval az '"a=b" "c=a dog"' --debug # `"a=b" "c=a dog"` is received as a whole argument
---------------
az "a=b" "c=a dog" --debug
++ az a=b 'c=a dog' --debug
Command arguments: ['a=b', 'c=a dog', '--debug']
I am actually thinking we can change the behavior of --tags to make it more user-friendly.
@zhoxing-ms, how about we expand the syntax of --tags to support JSON to save our customers from this mess?
$ set -vx
$ tags='{"a": "b", "c": "a dog"}'
tags='{"a": "b", "c": "a dog"}'
+ tags='{"a": "b", "c": "a dog"}'
$ echo "$tags"
echo "$tags"
+ echo '{"a": "b", "c": "a dog"}'
{"a": "b", "c": "a dog"}
$ az "$tags" --debug
az "$tags" --debug
+ az '{"a": "b", "c": "a dog"}' --debug
Command arguments: ['{"a": "b", "c": "a dog"}', '--debug']
I think this will be extremely helpful.
Another possible solution is to use this form and parse spaces and double quotes " by az itself.
$ az "$tags" --debug
az "$tags" --debug
+ az '"a=b" "c=a dog"' --debug
Command arguments: ['"a=b" "c=a dog"', '--debug']
---------------
But I think this is a bad solution as az is doing jobs belonging to Bash.
FYI, a good post for explaining the difference between "${myarray[@]}" and "${myarray[*]}": https://stackoverflow.com/a/3355375/2199657
@ghstahl Do you have any other questions?
@zhoxing-ms
As long as you give me something that can bridge the gap between github actions string parameters, and the az cli command than I am good. I would hope that an earlier suggestion of sending in an json string for this would be the best approach. As I said earlier, I have mandated "no space" tags just so I can move on.
@ghstahl Yes, we will support JSON format input for tags in the future~ I have created another issue #13659 to follow it up
Most helpful comment
Found a very useful tutorial: http://mywiki.wooledge.org/BashFAQ/050
This doesn't work:
Because space is used for field splitting (see this stackoverflow answer) and
In general, passing multiple arguments (
"a=b"and"c=a dog") within a single variable (tags) can be very nasty when it becomes complicated:"a=b" "c=a dog" ^^ ^ ^ 13 2 3'"c=a''dog"')evalto parse double quotesOr