Reputation: 683
I have a group with a large list of systems and need to grab the first 3 systems from the group. Is there a way to take a group such as this:
[webservers]
web01
web02
web03
web04
web05
And produce a quoted list similar to the following?:
- name: Pick the initial masters
lineinfile:
dest: "/bits/etc/web.conf"
state: present
regexp: 'node.masters'
line: 'node.masters: [ "web01", "web02", "web03" ]'
I may need to change the number of masters in the future so I'm hoping to use a slice if at all possible. Thanks for any insight.
Upvotes: 2
Views: 1000
Reputation: 1266
You can use the python array slice syntax and pipe it to the json filter. This will avoid looping in Jinja2 and produce nice quoted output.
- name: Pick the initial masters
lineinfile:
dest: /bits/etc/web.conf
state: present
regexp: 'node.masters'
line: 'node.masters: {{groups['webservers'][:3] | to_json}}'
Be careful with slices of groups, as the order is not necessarily consistent if the inventory is dynamically generated, as stated in the Ansible FAQ. To avoid this, I would advice on creating a second group, "masters" in the inventory, specifying which nodes to use rather than relying on order. This has other benefits, such as being able to target the masters or non-masters instead of having to know and change the number of masters in every playbook.
[webservers]
web[01:05]
[masters]
web[01:03]
Upvotes: 2
Reputation: 1579
You can reference the built-in groups
variable.
- name: Pick the initial masters
lineinfile:
dest: "/bits/etc/web.conf"
state: present
regexp: 'node.masters'
line: "node.masters: [ \"{{ groups['webservers'][0] }}\", \"{{ groups['webservers'][1] }}\", \"{{ groups['webservers'][2] }}\" ]"
Updated answer from comments:
You could also use jinja in your variable declarations to loop over an arbitrary number of hosts in webservers.
vars:
master_nodes: 3
master_nodes_line: "{% for item in groups['webservers'][:master_nodes] %}\"{{ item }}\"{% if not loop.last %},{% endif %}{% endfor %}"
tasks:
- name: Print list
lineinfile:
dest: foo
regexp: "node.masters"
line: "node.masters: [ {{ master_nodes_line }} ]"
Upvotes: 2