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
$ ansible-playbook release.yml \
--extra-vars "version=1.23.45 other_variable=foo"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
ansible-playbook release.yml --extra-vars "@some_file.json"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
This seems simple, so let’s check with this playbooks:
- name: Test passing different types of extra vars
hosts: localhost
tasks:
- name: Show dictionary values
debug:
msg:
- "Key1: {{ key1 }}"
- "Key2: {{ key2 }}"
when: key1 is defined$ ansible-playbook extra-vars-example.yml \
-e '{"key1":"value1","key2":"value2"}'
...
TASK [Show dictionary values] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
"Key1: value1",
"Key2: value2"
]
}
...That looks ok, but what if I want to assign the dictionary to a variable? Let’s modify the playbook:
- name: Test passing different types of extra vars
hosts: localhost
tasks:
- name: Show dictionary values
debug:
msg:
- "Key1: {{ key1 }}"
- "Key2: {{ key2 }}"
when: key1 is defined
- block:
- name: Show dictionary assigned to a variable
debug:
msg:
- "{{ sample_dict | from_yaml_all }}"
- " is of type '{{ sample_dict | type_debug }}'"
- name: Show dictionary values
debug:
msg:
- "{{ item.key }}: {{ item.value }}"
with_dict: "{{ sample_dict }}
when: sample_dict is definedI 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=0Well 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=0Cool, now the same for a list with the modified playbook
- name: Test passing different types of extra-vars
hosts: localhost
tasks:
- block:
- name: Show list assigned to a variable
debug:
msg:
- "{{ sample_list | from_yaml_all }}"
- "is of type '{{ sample_list | type_debug }}'"
- name: Show list values
debug:
msg:
- "{{ item }}"
with_items: "{{ sample_list }}"
when: sample_list is defined$ 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=0Obviously I can combine these by either using multiple -e parameter:
ansible-playbook extra-vars-example.yml \
-e '{ "sample_dict": {"key1":"value1","key2":"value2"}}' \
-e '{ "sample_list": [ "list_value_1", "list_value_2", "list_value_3" ]}' \
-e 'simple_string_1=test simple_string_2="another test"'or with a single e parameter
ansible-playbook extra-vars-example.yml \
-e '{ "sample_dict": {"key1":"value1","key2":"value2"}, "sample_list": [ "list_value_1", "list_value_2", "list_value_3" ], "simple_string_1": "test", "simple_string_2": "another test" }'You can find the complete playbook
extra-vars-example.yml in
my ansible-playground
Well, for my use case the command I call, would look like this:
ansible-playbook bootstrap-hcloud_servers.yml \
--tags hcloud-server \
-e server_names="dev0001" \
-e '{ "hcloud_server_labels": {"dev":"","k8s":"master" }}'