Passing simple strings to an ansible playbook as extra-vars is easy, but what if you want to pass lists or dictionary? Let's see...
Passing variables at runtime
As mentioned in the official docu one can pass variables at runtime using --extra-vars
or -e
. Values passed in using the key=value
syntax are interpreted as string
The above command will define two variables version
and other_variable
. Now if you want to pass dicts
or lists
you can define it in a external json or yaml file
This still may be cumbersome sometime, especially the extra vars you choose may change. For [bootstrapping my servers](({ ref “2021-04-what-are-tags-in-ansible-and-how-to-use-them” })) I have a playbook which expects to pass a parameter hcloud_server_labels
which should assign certain labels to the server. This expects a key-value pair i.e. a dictionary.
This can be done using JSON string format. The extra vars for a have to be wrapped in a single quote '
, whereas the dictionary itself is wrapped with curly brackets {
and }
. In case you want to pass a list, you use square brackets [
and ]
, instead the curly brackets
Let’s make a test
This seems simple, so let’s check with this playbooks:
That looks ok, but what if I want to assign the dictionary to a variable? Let’s modify the playbook:
I want the dictionary be accessible as sample_dict
so I do
$ ansible-playbook extra-vars-example.yml \
-e sample_dict='{"key1":"value1","key2":"value2"}'
...
TASK [Show dictionary assigned to a variable] ******************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
[
{
"key1": "value1",
"key2": "value2"
}
],
" is of type 'str'"
]
}
TASK [Show dictionary values] **********************************************************************************************************************************************************************************
ok: [localhost] => (item={'key': 'key1', 'value': 'value1'}) => {
"msg": [
"key1: value1"
]
}
ok: [localhost] => (item={'key': 'key2', 'value': 'value2'}) => {
"msg": [
"key2: value2"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Well the variable sample_dict
is considered a str
instead a dict
, however, the iteration seems to work. Still, there must be something wrong. Let’s try
this
$ ansible-playbook extra-vars-example.yml \
-e '{ "sample_dict": {"key1":"value1","key2":"value2"}}'
...
TASK [Show dictionary assigned to a variable] ******************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"key1": "value1",
"key2": "value2"
},
"is of type 'dict'"
]
}
TASK [Show dictionary values] **********************************************************************************************************************************************************************************
ok: [localhost] => (item={'key': 'key1', 'value': 'value1'}) => {
"msg": [
"key1: value1"
]
}
ok: [localhost] => (item={'key': 'key2', 'value': 'value2'}) => {
"msg": [
"key2: value2"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Cool, now the same for a list with the modified playbook
$ ansible-playbook extra-vars-example.yml \
-e '{ "sample_list": [ "list_value_1", "list_value_2", "list_value_3" ]}'
...
TASK [Show list assigned to a variable] ************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
[
"list_value_1",
"list_value_2",
"list_value_3"
],
"is of type 'list'"
]
}
TASK [Show list values] ****************************************************************************************************************************************************************************************
ok: [localhost] => (item=list_value_1) => {
"msg": [
"list_value_1"
]
}
ok: [localhost] => (item=list_value_2) => {
"msg": [
"list_value_2"
]
}
ok: [localhost] => (item=list_value_3) => {
"msg": [
"list_value_3"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Obviously I can combine these by either using multiple -e
parameter:
or with a single e
parameter
You can find the complete playbook extra-vars-example.yml
in my ansible-playground
And what about my use case?
Well, for my use case the command I call, would look like this: