Elastic.elasticsearch role and Ansible Tower Dynamic Inventory


I am trying to configure Elasticsearch cluster over Ansible using official Elastic Ansible role elastic.elasticsearch. I set up Ansible tower and Dynamic Inventory for my AWS instances. I tagged my instances and have them all grouped in tag_Group_Elasticsearch. Here is the Ansible code:

  hosts: tag_Group_Elasticsearch
    - role: elastic.elasticsearch
    es_heap_size: "2g"
      cluster.name: "prod-cluster"
      cluster.initial_master_nodes: "tag_Group_Elasticsearch"
      discovery.seed_hosts: "tag_Group_Elasticsearch"
      http.port: 9200
      node.master: true
      bootstrap.memory_lock: false
     - plugin: ingest-attachment

So when I want to use the group in the role it works well when it come to hosts part of the play. It resolves well and apply to all hosts in the group. But when I want to use it in es_config variable it doesn't resolve to hosts names it just pass it as a string and therefore, elasticsearch cluster fails.

This is what I get in elasticsearch.yml on the cluster members:

cluster.initial_master_nodes: tag_Group_Elasticsearch
discovery.seed_hosts: tag_Group_Elasticsearch

What I need to have here is:

cluster.initial_master_nodes: "192.168.x.x, 192.168.x.x, 192.168.x.x "
discovery.seed_hosts: "192.168.x.x, 192.168.x.x, 192.168.x.x"

I can't add hostnames in cluster.initial_master_nodes and discovery.seed_hosts manually as my Elasticsearch cluster is built over AWS autoscaling group and my hosts are dynamic...


Here is the way I fixed this. It might help someone.

First I created new variable using set_fact:

- name: Determine nodes to join
  hosts: tag_Group_Elasticsearch
  become: true
  - name: Setting nodes IPs
      join_list: "{{ groups['tag_Group_Elasticsearch'] | map('extract', hostvars, ['ansible_host']) | list }}" # instead 'ansible_host' you can use the folloving variables as well: ansible_fqdn, ec2_private_ip_address or ansible_nodename

Then I configured cluster.initial_master_nodes and discovery.seed_hosts in elastic.elasticsearch role as follows:

cluster.initial_master_nodes: "{{ join_list | join(',') }}"
discovery.seed_hosts: "{{ join_list | join(',') }}"

As a result elasticsearch.yaml picked up the IP addresses of the nodes:

cluster.initial_master_nodes: 10.174.x.x,10.174.x.x,10.174.x.x
discovery.seed_hosts: 10.174.x.x,10.174.x.x,10.174.x.x

Now whenever new node is added into the group, in this case tag_Group_Elasticsearch, that node will be added to cluster.initial_master_nodes and discovery.seed_hosts automatically.

This configuration is very useful when you have cluster nodes in AWS (EC2) and when you use AWS auto scaling and Ansible elastic.elasticsearch role for setting up cluster.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.