Search code examples
jinja2ansibleapache-zookeeperansible-inventory

Ansible: How can I set serial numbers for hosts


I am trying to provision hosts on EC2, so I am working with Ansible Dynamic Inventory.

What I want to do is; to set serial number for each node.

For example: "myid" configuration of Zookeeper

Zookeeper requires serial number named "myid" for each node; 1 for hostA, 2 for hostB, 3 for hostC and so on.

Here is the part of my playbook that copies "myid" file to hosts.

- name: Set myid
  sudo: yes
  template: src=var/lib/zookeeper/myid.j2 dest=/var/lib/zookeeper/myid

And myid.j2 should be something like this below.

{{ serial_number }}

The question is: What should the variable "{{ serial_number }}" be like?


Solution

  • I solved this by assigning a number to each EC2 instance as a tag when creating them. I then refer to that tag when creating the myid file. Below are the tasks I used to create my EC2 instances with all non-important fields left out for brevity.

    - name: Launch EC2 instance(s)
      with_sequence: count="{{ instance_count }}"
      ec2:
        instance_tags:
          number: "{{ item }}"
    

    Then when installing ZooKeeper on these servers, I use the dynamic inventory to obtain all the servers tagged with zookeeper and use the number tag in the myid file.

    - name: Render and copy myid file
      copy: >
        content={{ ec2_tag_number }}
        dest=/etc/zookeeper/conf/myid
    

    Note: when creating the EC2 instances, I needed to use with_sequence rather than the count field in the ec2 module. Otherwise I wouldn't have an index to capture for the tag.


    If you want the playbook to handle being able to add nodes to the current cluster, you can query for the number of EC2 instances tagged with zookeeper and add that to the iteration index. This is fine to have normally because current_instance_count will be 0 if there aren't any.

    - 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 }}"