I have an Ansible playbook which requires --extra-vars
to be passed and would like to know if there is any way that validate the hostnames from the --extra-vars
values is within the variables.
Sample playbook test.yml
- hosts: localhost
gather_facts: false
vars:
prg:
prod_mgmt_network: "{{ ['prodsrv00']|product(range(prod_start,prod_end))|map('join')|list }}"
test_mgmt_network: "{{ ['testsrv00']|product(range(test_start,test_end))|map('join')|list }}"
prod_start: 4281
prod_end: 4283
test_start: 8281
test_end: 8283
tasks:
- debug:
var: prg.prod_mgmt_network, prg.test_mgmt_network
Sample command
ansible-playbook --extra-vars hostname=['prodsrv004281', 'prodsrv004282', 'testsrv008281', 'testsrv008282', 'testsrv008283', 'testsrv008284'] test.yml
I would like to fail the task if a hostname is not within the variable. for example, testsrv008283
and testsrv008284
should fail the task.
The first problem is the format of the extra variables. See Defining variables at runtime. The key=value (INI) syntax are always interpreted as strings. You might want to test it. For example, the below play
shell> cat pb.yml
- hosts: localhost
tasks:
- debug:
var: hostname
- debug:
var: hostname|type_debug
gives (abridged)
shell> ansible-playbook pb.yml -e hostname=['host1','host2']
hostname: '[host1,host2]'
hostname|type_debug: str
There are more options for how to get a list:
hostname_list: "{{ hostname|from_yaml }}"
Then, you'll get
hostname_list:
- host1
- host2
hostname_list|type_debug: list
shell> ansible-playbook pb.yml -e '{"hostname": ["host1", "host2"]}'
hostname:
- host1
- host2
hostname_list|type_debug: list
shell> cat hostname.yml
hostname:
- host1
- host2
Then, the below play gives the same result
shell> ansible-playbook pb.yml -e @hostname.yml
For testing your case, the simplest option is to put the list into a file
shell> cat hostname.yml
hostname:
- prodsrv004281
- prodsrv004282
- testsrv008281
- testsrv008282
- testsrv008283
- testsrv008284
Q: "Fail if hostname is not within the variable. For example, testsrv008283 and testsrv008284 should fail."
A: Select the lists of hosts and compare the differences. For example,
prod_hosts: "{{ hostname|select('match', 'prodsrv') }}"
test_hosts: "{{ hostname|select('match', 'testsrv') }}"
gives
prod_hosts:
- prodsrv004281
- prodsrv004282
test_hosts:
- testsrv008281
- testsrv008282
- testsrv008283
- testsrv008284
Evaluation of the networks gives
prg:
prod_mgmt_network:
- prodsrv004281
- prodsrv004282
test_mgmt_network:
- testsrv008281
- testsrv008282
The below assert will pass
- assert:
that: prod_out|length == 0
fail_msg: "Hosts: {{ prod_out }} out of range."
vars:
prod_out: "{{ prod_hosts|difference(prg.prod_mgmt_network) }}"
ok: [localhost] => changed=false
msg: All assertions passed
but, this one will fail
- assert:
that: test_out|length == 0
fail_msg: "Hosts: {{ test_out }} out of range."
vars:
test_out: "{{ test_hosts|difference(prg.test_mgmt_network) }}"
fatal: [localhost]: FAILED! => changed=false
assertion: test_out|length == 0
evaluated_to: false
msg: 'Hosts: [''testsrv008283'', ''testsrv008284''] out of range.'
Example of a complete playbook for testing
- hosts: localhost
vars:
prg:
prod_mgmt_network: "{{ ['prodsrv00']|
product(range(prod_start,prod_end))|map('join') }}"
test_mgmt_network: "{{ ['testsrv00']|
product(range(test_start,test_end))|map('join') }}"
prod_start: 4281
prod_end: 4283
test_start: 8281
test_end: 8283
prod_hosts: "{{ hostname|select('match', 'prodsrv') }}"
test_hosts: "{{ hostname|select('match', 'testsrv') }}"
tasks:
- debug:
var: prg.prod_mgmt_network
- debug:
var: prg.test_mgmt_network
- debug:
var: hostname
- debug:
var: prod_hosts
- debug:
var: test_hosts
- assert:
that: prod_out|length == 0
fail_msg: "Hosts: {{ prod_out }} out of range."
vars:
prod_out: "{{ prod_hosts|difference(prg.prod_mgmt_network) }}"
- assert:
that: test_out|length == 0
fail_msg: "Hosts: {{ test_out }} out of range."
vars:
test_out: "{{ test_hosts|difference(prg.test_mgmt_network) }}"