Skip to content

Commit

Permalink
Support for configuration per node and multiple nodes per server
Browse files Browse the repository at this point in the history
  • Loading branch information
Dale McDiarmid committed Oct 22, 2015
1 parent 0c6f326 commit d19297a
Show file tree
Hide file tree
Showing 30 changed files with 815 additions and 85 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
.vendor
.bundle
Converging
TODO
10 changes: 10 additions & 0 deletions .kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,14 @@ suites:
attributes:
provisioner:
playbook: test/integration/package.yml
- name: config
run_list:
attributes:
provisioner:
playbook: test/integration/config.yml
- name: multi
run_list:
attributes:
provisioner:
playbook: test/integration/multi.yml

94 changes: 69 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,88 @@ Then create your playbook yaml adding the role elasticsearch and overriding any
---
hosts: my_host
roles:
- elasticsearch
- { role: elasticsearch, es_multicast_enabled: true}
tasks:
- .... your tasks ...
```

or more complex..
By default es_multicast_enabled is false. If this is not to true, the user is required to specify the following additional parameters:

1. es_http_port - the http port for the node
2. es_transport_tcp_port - the transport port for the node
3. es_unicast_hosts - the unicast discovery list, in the comma separated format "<host>:<port>,<host>:<port>" (typically the clusters dedicated masters)


If set to true, the ports will be auto defined and node discovery will be performed using multicast.

A more complex example:

```
---
hosts: my_host
hosts: localhost
roles:
- { role: elasticsearch, es_unicast_hosts: "localhost:9301", es_http_port: "9201", es_transport_tcp_port: "9301", es_data_node: false, es_master_node: true, es_m_lock_enabled: true, es_multicast_enabled: false, es_node_name_prefix: "node1_", es_cluster_name: "custom-cluster" }
vars:
es_scripts: false
es_templates: false
es_version_lock: false
es_m_lock_enabled: true
es_start_service: false
es_plugins_reinstall: false
es_plugins:
- plugin: elasticsearch/elasticsearch-cloud-aws
version: 2.5.0
- plugin: elasticsearch/marvel
version: latest
- plugin: elasticsearch/license
version: latest
- plugin: elasticsearch/shield
version: latest
- plugin: elasticsearch/elasticsearch-support-diagnostics
version: latest
- plugin: lmenezes/elasticsearch-kopf
version: master
tasks:
- .... your tasks ...
```

The above example illustrates the ability to control the configuration.

The application of a role results in the installation of a node on a host. Multiple roles equates to multiple nodes for a single host. If specifying multiple roles for a host, and thus multiple nodes, the user must:

1. Provide a es_node_name_prefix. This is used to ensure seperation of data, log, config and init scripts.
2. Ensure those playbooks responsible for installing and starting master eligble roles are specified first. These are required for cluster initalization.

An example of a two server deployment, each with 1 node on one server and 2 nodes on another. The first server holds the master and is thus declared first.

```
---
hosts: masters
roles:
- { role: elasticsearch, es_node_name_prefix: "node1_", es_unicast_hosts: "localhost:9300", es_http_port: "9201", es_transport_tcp_port: "9301", es_data_node: true, es_master_node: false, es_m_lock_enabled: true, es_multicast_enabled: false }
vars:
es_scripts: false
es_templates: false
es_version_lock: false
es_cluster_name: example-cluster
m_lock_enabled: false
- hosts: data_nodes
roles:
- elasticsearch
- { role: elasticsearch, es_data_node: true, es_master_node: false, es_m_lock_enabled: true, es_multicast_enabled: false, es_node_name_prefix: "node1_" }
- { role: elasticsearch, es_data_node: true, es_master_node: false, es_m_lock_enabled: true, es_multicast_enabled: false, es_node_name_prefix: "node2_" }
vars:
java_packages:
- "oracle-java7-installer"
es_major_version: 1.4
es_version: 1.4.4
es_start_service: false
es_plugins_reinstall: false
es_scripts: false
es_templates: false
es_version_lock: false
es_cluster_name: example-cluster
m_lock_enabled: true
es_plugins:
- plugin: elasticsearch/elasticsearch-cloud-aws
version: 2.5.0
- plugin: elasticsearch/marvel
version: latest
- plugin: elasticsearch/license
version: latest
- plugin: elasticsearch/shield
version: latest
- plugin: elasticsearch/elasticsearch-support-diagnostics
version: latest
- plugin: lmenezes/elasticsearch-kopf
version: master
tasks:
- .... your tasks ...
```

Make sure your hosts are defined in your ```hosts``` file with the appropriate ```ansible_ssh_host```, ```ansible_ssh_user``` and ```ansible_ssh_private_key_file``` values.
Parameters can additionally be assigned to hosts using the inventory file if desired.

Make sure your hosts are defined in your ```inventory``` file with the appropriate ```ansible_ssh_host```, ```ansible_ssh_user``` and ```ansible_ssh_private_key_file``` values.

Then run it:

Expand Down
3 changes: 3 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ es_scripts: false
es_templates: false
es_user: elasticsearch
es_group: elasticsearch
es_cluster_name: elasticsearch
es_multicast_enabled: false
es_node_name_prefix: ""
9 changes: 9 additions & 0 deletions elasticsearch.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="RUBY_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
3 changes: 2 additions & 1 deletion meta/main.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
dependencies: []

allow_duplicates: yes

galaxy_info:
author: Robin Clarke
Expand Down
10 changes: 10 additions & 0 deletions tasks/checkParameters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Check for mandatory parameters

- fail: msg="Parameter 'es_http_port' must be defined when multicast is disabled"
when: es_multicast_enabled == false and es_http_port is not defined

- fail: msg="Parameter 'es_transport_tcp_port' must be defined when multicast is disabled"
when: es_multicast_enabled == false and es_transport_tcp_port is not defined

- fail: msg="Parameter 'es_unicast_hosts' must be defined when multicast is disabled"
when: es_multicast_enabled == false and es_unicast_hosts is not defined
22 changes: 1 addition & 21 deletions tasks/elasticsearch-Debian.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,4 @@
- name: Debian - Ensure elasticsearch is installed from downloaded package
apt: deb=/tmp/elasticsearch-{{ es_version }}.deb
when: not es_use_repository
register: elasticsearch_install

- name: Debian - configure memory
lineinfile: dest=/etc/default/elasticsearch regexp="^ES_HEAP_SIZE" insertafter="^#ES_HEAP_SIZE" line="ES_HEAP_SIZE={{ es_heap_size }}"
when: es_heap_size is defined
register: elasticsearch_configure
- name: Debian - configure data store
lineinfile: dest=/etc/default/elasticsearch regexp="^DATA_DIR" insertafter="^#DATA_DIR" line="DATA_DIR={{ es_data_dir }}"
when: es_data_dir is defined
register: elasticsearch_configure
- name: Debian - configure elasticsearch user
lineinfile: dest=/etc/default/elasticsearch regexp="^ES_USER" insertafter="^#ES_USER" line="ES_USER={{ es_user }}"
when: es_user is defined
register: elasticsearch_configure
- name: Debian - configure elasticsearch group
lineinfile: dest=/etc/default/elasticsearch regexp="^ES_GROUP" insertafter="^#ES_GROUP" line="ES_GROUP={{ es_group }}"
when: es_group is defined
register: elasticsearch_configure
- name: Debian - create data dir
file: state=directory path={{ es_data_dir }} owner={{ es_user }} group={{ es_group }}
when: es_data_dir is defined
register: elasticsearch_install
22 changes: 1 addition & 21 deletions tasks/elasticsearch-RedHat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,4 @@
- name: RedHat - Install Elasticsearch from url
yum: name={% if es_custom_package_url is defined %}{{ es_custom_package_url }}{% else %}{{ es_package_url }}-{{ es_version }}.noarch.rpm{% endif %} state=present
when: not es_use_repository
register: elasticsearch_install

- name: RedHat - configure memory
lineinfile: dest=/etc/sysconfig/elasticsearch regexp="^ES_HEAP_SIZE" insertafter="^#ES_HEAP_SIZE" line="ES_HEAP_SIZE={{ es_heap_size }}"
when: es_heap_size is defined
register: elasticsearch_configure
- name: RedHat - configure data store
lineinfile: dest=/etc/sysconfig/elasticsearch regexp="^DATA_DIR" insertafter="^#DATA_DIR" line="DATA_DIR={{ es_data_dir }}"
when: es_data_dir is defined
register: elasticsearch_configure
- name: RedHat - configure elasticsearch user
lineinfile: dest=/etc/sysconfig/elasticsearch regexp="^ES_USER" insertafter="^#ES_USER" line="ES_USER={{ es_user }}"
when: es_user is defined
register: elasticsearch_configure
- name: RedHat - configure elasticsearch group
lineinfile: dest=/etc/sysconfig/elasticsearch regexp="^ES_GROUP" insertafter="^#ES_GROUP" line="ES_GROUP={{ es_group }}"
when: es_group is defined
register: elasticsearch_configure
- name: RedHat - create data dir
file: state=directory path={{ es_data_dir }} owner={{ es_user }} group={{ es_group }}
when: es_data_dir is defined
register: elasticsearch_install
117 changes: 117 additions & 0 deletions tasks/elasticsearch-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---

# Configure Elasticsearch Node

# Create an instance specific default file
- name: Copy Default File for Instance
command: creates={{instance_default_file}} cp "{{default_file}}" "{{instance_default_file}}"
when: instance_default_file != default_file

- debug: msg="DEBUG {{ hostvars[inventory_hostname] }}"

# Create an instance specific init file
- name: Copy Init File for Instance
command: creates={{instance_init_script}} cp "{{init_script}}" "{{instance_init_script}}"
when: instance_init_script != init_script


#Create Config directory
- name: Create Config Directory
file: path={{ instance_config_directory }} state=directory owner={{ es_user }} group={{ es_group }}

#Copy the config template
- name: Copy configuration file
template: src=elasticsearch.yml.j2 dest={{instance_config_directory}}/elasticsearch.yml owner={{ es_user }} group={{ es_group }} mode=0644 force=yes

# Apply changes to the default file for this instance
- name: Configure config directory
lineinfile: dest={{instance_default_file}} regexp="^CONF_DIR" insertafter="^#CONF_DIR" line="CONF_DIR={{ instance_config_directory }}"
register: elasticsearch_configure

- name: Configure config file
lineinfile: dest={{instance_default_file}} regexp="^CONF_FILE" insertafter="^#CONF_FILE" line="CONF_FILE={{ instance_config_directory }}/elasticsearch.yml"
register: elasticsearch_configure

- name: Configure memory in defaults
lineinfile: dest={{instance_default_file}} regexp="^ES_HEAP_SIZE" insertafter="^#ES_HEAP_SIZE" line="ES_HEAP_SIZE={{ es_heap_size }}"
when: es_heap_size is defined
register: elasticsearch_configure

#We only have to set these if they are specified. The start scripts will by default use the NAME set later on constructing directory names to avoid collisions.

- name: Configure max open files
lineinfile: dest={{instance_default_file}} regexp="^MAX_OPEN_FILES" insertafter="^#MAX_OPEN_FILES" line="MAX_OPEN_FILES={{ es_max_open_files }}"
when: es_max_open_files is defined
register: elasticsearch_configure

#For directories we also use the {{ es_node_name_prefix }}{{inventory_hostname}} - this helps if we have a shared SAN. {{es_node_name_prefix}}{{default_file | basename} could potentially be used -
#init script effectively means this is the default.

#Create PID directory
- name: Create PID Directory
file: path={{pid_dir}}/{{ es_node_name_prefix }}{{inventory_hostname}} state=directory owner={{ es_user }} group={{ es_group }}

- name: Configure PID directory
lineinfile: dest={{instance_default_file}} regexp="^PID_DIR" insertafter="^#PID_DIR" line="PID_DIR={{pid_dir}}/{{ es_node_name_prefix }}{{inventory_hostname}}"
register: elasticsearch_configure

- set_fact: es_data_dir={{default_data_dir}}
when: es_data_dir is undefined

#include the host name as potentially shared SAN
- name: Create data dir
file: state=directory path={{ es_data_dir }}/{{ es_node_name_prefix }}{{inventory_hostname}} owner={{ es_user }} group={{ es_group }}

- name: Configure data store
lineinfile: dest={{instance_default_file}} regexp="^DATA_DIR" insertafter="^#DATA_DIR" line="DATA_DIR={{ es_data_dir }}/{{ es_node_name_prefix }}{{inventory_hostname}}"
register: elasticsearch_configure

- set_fact: es_work_dir={{default_work_dir}}
when: es_work_dir is undefined

- name: Create work dir
file: state=directory path={{ es_work_dir }}/{{ es_node_name_prefix }}{{inventory_hostname}} owner={{ es_user }} group={{ es_group }}

- name: Configure work directory
lineinfile: dest={{instance_default_file}} regexp="^WORK_DIR" insertafter="^#WORK_DIR" line="WORK_DIR={{ es_work_dir }}/{{ es_node_name_prefix }}{{inventory_hostname}}"
register: elasticsearch_configure

- set_fact: es_log_dir={{default_log_dir}}
when: es_log_dir is undefined

- name: Create log dir
file: state=directory path={{ es_log_dir }}/{{ es_node_name_prefix }}{{inventory_hostname}} owner={{ es_user }} group={{ es_group }}

- name: Configure log directory
lineinfile: dest={{instance_default_file}} regexp="^LOG_DIR" insertafter="^#LOG_DIR" line="LOG_DIR={{ es_log_dir }}/{{ es_node_name_prefix }}{{inventory_hostname}}"
register: elasticsearch_configure

#required so that the ES_HOME does not change between instances

- name: Configure elasticsearch home
lineinfile: dest={{instance_default_file}} regexp="^ES_HOME" insertafter="^#ES_HOME" line="ES_HOME={{es_home}}"
register: elasticsearch_configure

- name: Configure elasticsearch user
lineinfile: dest={{instance_default_file}} regexp="^ES_USER" insertafter="^#ES_USER" line="ES_USER={{ es_user }}"
when: es_user is defined
register: elasticsearch_configure

- name: Configure elasticsearch group
lineinfile: dest={{instance_default_file}} regexp="^ES_GROUP" insertafter="^#ES_GROUP" line="ES_GROUP={{ es_group }}"
when: es_group is defined
register: elasticsearch_configure

#Apply changes to init script - NAME can be changed in Debian start script
- name: Name Node in Init Script
lineinfile: dest={{instance_init_script}} regexp="^NAME" line="NAME={{es_node_name_prefix}}{{default_file | basename}}"
register: elasticsearch_configure
when: ansible_os_family == 'Debian'

- debug: msg="For {{ instance_init_script }} using default {{ instance_default_file }}"

- name: Environment in Init Script
lineinfile: dest={{instance_init_script}} regexp="^ES_ENV_FILE" line="ES_ENV_FILE={{instance_default_file}}"
register: elasticsearch_configure
when: ansible_os_family == 'RedHat'

22 changes: 16 additions & 6 deletions tasks/elasticsearch.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
---
# Trigger Debian section
- name: Include Debian specific Elasticsearch
- set_fact: instance_default_file={{default_file | dirname}}/{{es_node_name_prefix}}{{default_file | basename}}
- set_fact: instance_init_script={{init_script | dirname }}/{{es_node_name_prefix}}{{init_script | basename}}
- set_fact: instance_config_directory={{ es_conf_dir }}/{{es_node_name_prefix}}elasticsearch



# Install OS specific elasticsearch - this can be abbreviated in version 2.0.0
- name: Include specific Elasticsearch
include: elasticsearch-Debian.yml
when: ansible_os_family == 'Debian'

# Trigger Redhat section
- name: Include RedHat specific Elasticsearch
- name: Include specific Elasticsearch
include: elasticsearch-RedHat.yml
when: ansible_os_family == 'RedHat'

#Configuration file for elasticsearch
- name: Elasticsearch configuration
include: elasticsearch-config.yml

# Make sure the service is started, and restart if necessary
- name: Start elasticsearch service
service: name=elasticsearch state=started
service: name={{instance_init_script | basename}} state=started
when: es_start_service
register: elasticsearch_started

- name: Restart elasticsearch service if new version installed
service: name=elasticsearch state=restarted
service: name={{instance_init_script | basename}} state=restarted
when: es_start_service and
( elasticsearch_install.changed or elasticsearch_configure.changed )
and not elasticsearch_started.changed
4 changes: 2 additions & 2 deletions tasks/java.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
- name: RedHat - Ensure Java is installed
yum: name={{ java_rhel }} state=latest
yum: name={{ java }} state=latest
when: ansible_os_family == 'RedHat'

- name: Debian - Ensure Java is installed
apt: name={{ java_debian }} state=present update_cache=yes
apt: name={{ java }} state=present update_cache=yes force=yes
when: ansible_os_family == 'Debian'
Loading

0 comments on commit d19297a

Please sign in to comment.