Ansible: how to set serial numbers for hosts
I am trying to provide hosts on EC2, so I am working with Ansible Dynamic Inventory.
I want to do this; to set the serial number for each node.
For example: "myid" Zookeeper config
Zookeeper requires a serial number named "myid" for each node; 1 for hostA, 2 for hostB, 3 for hostC, etc.
Here is a piece of my play that copies the "myid" file to the hosts.
- name: Set myid
sudo: yes
template: src=var/lib/zookeeper/myid.j2 dest=/var/lib/zookeeper/myid
And there myid.j2
should be something like this below.
{{ serial_number }}
Question: what should the variable "{{serial_number}} look like?
source to share
I solved this by assigning a number to each EC2 instance as a tag when they were created. Then I refer to this tag when I create the file myid
. Below are the tasks I used to create EC2 instances with all important fields omitted for brevity.
- name: Launch EC2 instance(s)
with_sequence: count="{{ instance_count }}"
ec2:
instance_tags:
number: "{{ item }}"
Then when installing ZooKeeper on those servers, I use dynamic inventory to get all the servers with tags zookeeper
and use the tag number
in the file myid
.
- name: Render and copy myid file
copy: >
content={{ ec2_tag_number }}
dest=/etc/zookeeper/conf/myid
Note. When instantiating EC2, I needed to use with_sequence
, not a field count
in a module ec2
. Otherwise, I wouldn't have a capture index for the tag.
If you want the playbook to handle the ability to add nodes to the current cluster, you can query for the number of tagged EC2 instances zookeeper
and add that to the iteration index. This is ok because it current_instance_count
will be 0 if there are none.
- name: Determine how many instances currently exist
shell: echo "{{ groups['tag_zookeeper'] | length }}"
register: current_instance_count
- name: Launch EC2 instance(s)
with_sequence: count="{{ instance_count }}"
ec2:
instance_tags:
number: "{{ item|int + current_instance_count.stdout|int }}"
source to share
I found a nice clean way to do this using the Ansible with_index_items syntax:
tasks:
- name: Set Zookeeper Id
set_fact: zk_id={{item.0 + 1}}
with_indexed_items: "{{groups['tag_Name_MESOS_MASTER']}}"
when: item.1 == "{{inventory_hostname}}"
/ etc / zookeeper / conf / myid template can be set to
{{zk_id}}
This assumes you are using AWS dynamic resources.
source to share
There is no need to use a template, you can directly assign the contents of the myid file to the playbook. Suppose you have collected the entire ec2 instance into the "ec2hosts" group.
- hosts: ec2hosts
user: ubuntu
sudo:Trues
tasks:
- name: Set Zookeeper Id
copy: >
content={{ item.0 + 1 }}
dest=/var/lib/zookeeper/myid
with_indexed_items: "{{groups['ec2hosts']}}"
when: item.1 == "{{inventory_hostname}}"
source to share