elastic / ansible-elasticsearch Goto Github PK
View Code? Open in Web Editor NEWAnsible playbook for Elasticsearch
License: Other
Ansible playbook for Elasticsearch
License: Other
Somehow this showed up after running the playbook in the /etc/system/multi-user.target.wants/node1_elasticsearch.service
file
Environment=DATA_DIR=[,',/,v,a,r,/,l,i,b,/,e,l,a,s,t,i,c,s,e,a,r,c,h,/,e,s,-,0,1,-,n,o,d,e,1,',]
Also shows in /etc/elasticsearch/node1/elasticsearch.yml
path.data: [,',/,v,a,r,/,l,i,b,/,e,l,a,s,t,i,c,s,e,a,r,c,h,/,e,s,-,0,1,-,n,o,d,e,1,',]
Expect :
Template
[Service]
Environment=ES_HOME={{es_home}}
Environment=CONF_DIR={{conf_dir}}
Environment=DATA_DIR={{ data_dirs | array_to_str }}
Environment=LOG_DIR={{log_dir}}
Environment=PID_DIR={{pid_dir}}
EnvironmentFile=-{{instance_default_file}}
Every time I use the es_config parameter elasticsearch fails to start:
$ cat playbooks/elasticsearch.yml
---
- name: One Node Elasticsearch
hosts: search
become: True
roles:
- { role: ansiblebit.oracle-java, oracle_java_set_as_default: yes }
- { role: elasticsearch, es_instance_name: "node1" , es_config: { network.host: "_global_" } }
vars:
If I do NOT use es_config everything works fine.
With 2.2 out and the default to install latest maybe you should update the defaults and docs to reflect that
Currently installs can be only installed from the official Elastic repos. We commonly encounter users who have systems with no external internet access, instead hosting their own yum/apt-get repos. This feature would allow users to specify the repo as a parameter - if specified this would be used for the install.
Currently we are forcing people to be only able to install Elasticsearch plugins with --install elasticsearch/{{ item.plugin }}/{{ item.version }}
Could we please make this more open?
the item.plugin could be something like elasticsearch/marvel
or an other author/pluginname
combo.
Ansible role currently only adds plugins and does not support plugin removal.
First improvement will:
More tricky, and separate ticket:
Avoid automatic upgrades by checking directory before trying to install a plugin: if directory exists, then don't try to install again unless the reinstall variable is set.
Remember - the directory name is not necessarily the same as the plugin name
Defining multiple data directories:
es_data_dir: "/mnt/xvdb,/mnt/xvdc"
Results in
DATA_DIR=/mnt/xvdb,/mnt/xvdc/ec2_marvel-rclarke_marvel
The node name is pasted after the last directory.
I don't think it is necessary to have a separate directory for each node running on a single machine, same as it is not necessary to have a separate directory for logs or work I think...
Test run levels are correctly applied per OS. Given the challenge with testing (using Kitchen) that ES is restarted on machine reboot, this gives us a confidence this is behaving correctly.
Between ES 1.x and 2.x plugins management verbs changed.
bin/plugin --install [plugin_name]
bin/plugin install [plugin_name]
We should catch this change during the plugin installation and removal. At least, as long we support ES 1.x
Currently Systemd results in an error and fails to work when tested in Docker. Further investigation required. Error to be added here.
Allow the specification of a different username under which elasticsearch should be run. Currently we only support "elasticsearch".
I propose we do not create this user if it doesn't exist i.e. we assume its existence.
When using the role to manage plugins, it fails in consecutive runs due to deleted /etc/default/elasticsearch
The elasticsearch plugin command used in elasticsearch-plugins.yml
to detect already installed plugins fails with
# ./plugin list
./plugin: 49: .: Can't open //etc/default/elasticsearch
The playbook fails with
"ERROR: plugin directory /usr/share/elasticsearch/plugins/sams/kopf already exists. To update the plugin, uninstall it first using 'remove kopf' command"
You delete /etc/default/elasticsearch
in elasticsearch-config.yml
.
Running Debian Jessie and elasticsearch 2.2.0
All current tests install to a clean docker image. The image is destroyed on completion of the test run. No tests currently confirm the behaviour if a role is applied multiple times to an image.
Whilst this is difficult to achieve with Kitchen tests, we could test the behaviour is correct when the role is applied to a docker image which already has nodes installed. This could be used to confirm:
@electrical I propose choosing one platform on which to test this - in Kitchen it will require another platform/docker image preloaded with Elasticsearch. To avoid test explosion we might just limit to one platform therefore.
Like this
I would like to add shield support, and I was wondering how we can structure things like variables and templates.
Here are my proposals:
Dicts structure:
es_license: my_vaulted_private_and_secret_license
es_users:
- user: bob
password: my_vaulted_secret_password
role: user
es_role_mapping:
- admin:
- "cn=admins,dc=example,dc=com"
- user:
- "cn=users,dc=example,dc=com"
- "cn=other-users,dc=example,dc=com"
or this structure (I personally prefer this one):
es_license: my_vaulted_private_and_secret_license
es_shield:
- users:
- user: bob
password: my_vaulted_secret_password
role: user
- role_mapping:
- admin:
- "cn=admins,dc=example,dc=com"
- user:
- "cn=users,dc=example,dc=com"
- "cn=other-users,dc=example,dc=com"
Templates structure:
Add these following templates to configure shield's roles and role mappings. For the main configuration, we'll use the es_config
object.
+-- templates
| +-- ...
| +-- shield
| | +-- role_mapping.yml.j2
| | +-- roles.yml.j2
Do you have any suggestion or preference on how we should add this feature?
The copy commands in the tasks/elasticsearch-scripts.yml and tasks/elasticsearch-templates.yml are pretty clear in their intent.
So, is the expectation that I should clone this repo, and add any custom scripts/templates to the appropriate directory in files/
?
Is there a way to configure a playbook to reference a different directory to load scripts/templates from?
On Ubuntu 14.04 you cannot restart (or stop) the elastic service with this command:
service <es_instance_name_elasticsearch> restart
Currently you have to restart the service, you have to kill the process and then use:
service <es_instance_name_elasticsearch> start
At the moment the code uses a download link.
Would be nice if we can use our official repositories instead.
Hello
Could it be possible to check whether Java is already present before to install it through package manager?
In my case, Oracle JDK is installed through an ansible role that download the tgz directly from Oracle.
I would like to avoid openjdk installation if not required.
For example, changing java.yml to:
---
- name: Check Java
shell: command -v java
register: check_java
ignore_errors: True
changed_when: False
- name: RedHat - Ensure Java is installed
yum: name={{ java }} state=latest
when: ansible_os_family == 'RedHat' and check_java.rc > 0
- name: Debian - Ensure Java is installed
apt: name={{ java }} state=present update_cache=yes force=yes
when: ansible_os_family == 'Debian' and check_java.rc > 0
Best regards.
Geoff.
Before making public we need acceptance testing to pass on multiple distro's.
There is an article http://www.slideshare.net/MartinEtmajer/testing-ansible-roles-with-test-kitchen-serverspec-and-rspec-48185017 that describes testing for ansible.
Using a map for configuring elasticsearch.yml is super flexible and nice, but it makes it very easy to miscreate configurations that will not start. It would be very nice if there was some sort of validation that checks syntax.
Currently a config change will cause the node to be restarted. Have this controlled by a variable whose default is false.
I am using Ubuntu 14.04.
I am configuring Elasticsearch in a role like so:-
- { role: elasticsearch,
es_instance_name: "es01",
es_heap_size: "3g",
es_data_dirs: "/opt/app/elasticsearch/data",
es_log_dir: "/opt/app/elasticsearch/logs",
es_work_dir: "/opt/app/elasticsearch/temp",
es_config: { network.host: '[ "_local_", "_docker0_" ]',
transport.host: '_eth0_',
http.port: 9200,
transport.tcp.port: 9300,
max-open-files: true,
bootstrap.mlockall: true,
script.inline: true,
script.indexed: true,
index.translog.durability: async,
index.queries.cache.everything: true } }
This leaves me with a defaults file at /etc/default/es01_elasticsearch
.
This happens when I try to run the plugin
command:-
root@my-es-host:/usr/share/elasticsearch# bin/plugin โ~
bin/plugin: 49: .: Can't open //etc/default/elasticsearch
I can fix it up manually by editing bin/plugin
like so:-
ES_ENV_FILE="/etc/default/es01_elasticsearch"
Am I missing some configuration or is this a bug? Thanks for your help.
This is currently left to which ever takes precedence as to what the user configures post install i.e. both scripts are installed.
The proposal is we clearly delimitate which is used, why and when.
@electrical maybe we should replicate the puppet modules behaviour here?
How do I add additional properties to:
es_plugins:
- plugin: elasticsearch-cloud-aws
version: 2.5.0
to match:
cloud:
aws:
access_key: *********
secret_key: **********
discovery:
type: ec2
Thanks,
Per
I just did an initial test install with this role. I configured three nodes and ran the play. When I tried checking the health of the cluster, it became apparent that elasticsearch was not started.
So I tried starting it manually, and I got this:
root@node1:~# /usr/share/elasticsearch/bin/elasticsearch
Failed to configure logging...
ElasticsearchException[Failed to load logging configuration]; nested: NoSuchFileException[/usr/share/elasticsearch/config];
at org.elasticsearch.common.logging.log4j.LogConfigurator.resolveConfig(LogConfigurator.java:158)
at org.elasticsearch.common.logging.log4j.LogConfigurator.configure(LogConfigurator.java:103)
at org.elasticsearch.bootstrap.Bootstrap.setupLogging(Bootstrap.java:204)
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:258)
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35)
Caused by: java.nio.file.NoSuchFileException: /usr/share/elasticsearch/config
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
at sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:144)
at sun.nio.fs.LinuxFileSystemProvider.readAttributes(LinuxFileSystemProvider.java:97)
at java.nio.file.Files.readAttributes(Files.java:1686)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:109)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:69)
at java.nio.file.Files.walkFileTree(Files.java:2602)
at org.elasticsearch.common.logging.log4j.LogConfigurator.resolveConfig(LogConfigurator.java:142)
... 4 more
log4j:WARN No appenders could be found for logger (bootstrap).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" java.lang.RuntimeException: don't run elasticsearch as root.
at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:93)
at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:144)
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:285)
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35)
Refer to the log for complete error details.
root@node1:~# ls /etc/elasticsearch/
elasticsearch.yml node1 logging.yml scripts
Here are the ansible vars, just replace node1 with node2 or node3 to get the other nodes config:
es_version: 2.1.1
es_log_dir: "/opt/elasticsearch/logs"
es_work_dir: "/opt/elasticsearch/temp"
es_heap_size: "3072m"
es_config:
cluster.name: "asdfqwerty"
discovery.zen.ping.unicast.hosts: "http://node1:9301"
http.port: 9200
transport.tcp.port: 9301
bootstrap.mlockall: True
discovery.zen.ping.multicast.enabled: False
path.repo: "/path/to/repo/path"
discovery.zen.minimum_master_nodes: 2
action.destructive_requires_name: True
es_instance_name: "node1"
es_config:
node.name: "node1"
node.data: True
node.master: True
es_data_dir: "/mounts/node1"
Did I miss some required var?
I did try /etc/init.d/node1_elasticsearch start
and it did not work, nor did it output any errors. Just Starting ... [OK]
. /var/logs/elasticsearch
is empty so I can't figure anything out from there.
So, what obvious step am I missing?
Should this kind of question be posted on discuss.elastic.co somewhere instead of here? If so, what forum?
Currently if the user does the following:
The plugins are not changed to those in step (2) - they are required to specify es_plugins_reinstall:true. My current proposal is to remove all plugins and re-install them in the event of ANY delta.
@jakommo thoughts?
Ability to define a proxy port like this
TASK: [elasticsearch | Debian - Add java repos] *******************************
failed: [localhost] => (item=ppa:webupd8team/java) => {"failed": true, "item": "ppa:webupd8team/java"}
msg: Invalid repository string: ppa:webupd8team/java
Should not be necessary to define the version.
i.e. if you specify major version 1.5 then the latest 1.5 full version should be installed (currently 1.5.2)
Ability to go around package management and install .deb/.rpm package directly like here
https://github.com/elastic/ansible-elasticsearch/blob/master/tasks/elasticsearch-RedHat.yml
Should be /etc/sysconfig/elasticsearch instead of /etc/default/elasticsearch
When a specific version of Elasticsearch is defined, this will be pinned in the package manager so that an inadvertent apt-get upgrade
will not upgrade to the latest elasticsearch.
I just started using the ES Ansible playbook, and noticed that there aren't any logrotate entries.
Would be nice to see a logrotate file added for ES automatically as part of the playbook as I can't seem to find any reference to one.
The rpm and deb packages install an elasticsearch.yml, env default file (e.g. /etc/sysconfig/elasticsearch) init script and systemd file. These are not used as the role creates its own copy for each node instance - delimiting them with the mandatory instance name.
This ticket proposes cleaning these files up on completion of install.
Issue: The plugin management is not idempotent (using current master, commit e14ebe0).
A plugin gets installed on first ansible-playbook run and causes "ERROR: plugin directory already exists" on the second run.
To be able to run a playbook multiple time, one has to workaround it by setting es_plugins_reinstall to true (default is false), but then the playbook reports changes on each run (not idempotent either).
Expected behaviour: second run finishes without error, with zero changes.
Environment: Fresh Ubuntu 14.04 64bit in Vagrant
Playbook (idemp.yml):
---
- name: Provision the ES node or cluster
hosts: es
remote_user: vagrant
become: yes
become_user: root
gather_facts: true
vars:
es_plugins:
- plugin: cloud-aws
roles:
- { role: elasticsearch, es_instance_name: "node1" }
First run:
marji@anna:~/projects/ansible-project-logstash$ ansible-playbook -i hosts idemp.yml
--- cut ---
PLAY RECAP *********************************************************************
10.8.8.2 : ok=47 changed=18 unreachable=0 failed=0
Second run:
marji@anna:~/projects/ansible-project-logstash$ ansible-playbook -i hosts idemp.yml
--- cut ---
TASK [elasticsearch : Remove elasticsearch plugins] ****************************
skipping: [10.8.8.2] => (item= cloud-aws)
TASK [elasticsearch : Install elasticsearch plugins] ***************************
failed: [10.8.8.2] => (item={u'plugin': u'cloud-aws'}) => {"changed": false, "cmd": ["/usr/share/elasticsearch/bin/plugin", "install", "cloud-aws", "--silent"], "delta": "0:00:10.256230", "end": "2016-06-05 03:27:35.476620", "failed": true, "failed_when_result": true, "item": {"plugin": "cloud-aws"}, "rc": 74, "start": "2016-06-05 03:27:25.220390", "stderr": "", "stdout": "ERROR: plugin directory /usr/share/elasticsearch/plugins/node1/cloud-aws already exists. To update the plugin, uninstall it first using 'remove cloud-aws' command", "stdout_lines": ["ERROR: plugin directory /usr/share/elasticsearch/plugins/node1/cloud-aws already exists. To update the plugin, uninstall it first using 'remove cloud-aws' command"], "warnings": []}
PLAY RECAP *********************************************************************
10.8.8.2 : ok=43 changed=0 unreachable=0 failed=1
The error above is: "ERROR: plugin directory /usr/share/elasticsearch/plugins/node1/cloud-aws already exists. To update the plugin, uninstall it first using 'remove cloud-aws' command"
Insert templates to elasticsearch like here
Given the situation with default java versions on Centos and Debian based systems, users are likely to want to specify an external repo to supply Java e.g. for Oracle. Currently the role limits them to IcedTea distribution and the latest version available through the default repos.
Are there any plans to deploy this role to Ansible Galaxy?
This isn't correctly detected and the task succeeds. Shouldn't actually occur but has done during network issues.
Currently the default user "elasticsearch" is used - this is installed by the package manager.
If installed through a manual URL this might not be the case. User may also wish to use another user.
Proposal is to create the user if it doesn't exist.
/usr/sbin/update-rc.d
fails on Ubuntu (15.04):
fatal: [hostname]: FAILED! => {"changed": false, "failed": true, "msg": "Error when trying to enable node2_elasticsearch: rc=1 Synchronizing state for node2_elasticsearch.service with sysvinit using update-rc.d...\nExecuting /usr/sbin/update-rc.d node2_elasticsearch defaults\ninsserv: script node2_elasticsearch: service elasticsearch already provided!\ninsserv: exiting now!\nupdate-rc.d: error: insserv rejected the script header\n"}
node2
is the es_instance_name
.
I believe the issue is related to the following line in the debian init script:
# Provides: elasticsearch
Should that be something like this?
# Provides: {{es_instance_name}}_{{default_file | basename}}
My playbook looks like this:
- hosts: elasticsearch
vars:
es_major_version: "2.x"
es_version: "2.2.0"
es_heap_size: "31g"
es_max_open_files: 262140
es_data_dir: "/elasticsearch/data"
es_log_dir: "/elasticsearch/log"
roles:
- { role: elasticsearch, es_instance_name: "node1", es_config: { node.name: "node1", http.port: 9200, transport.tcp.port: 9300, cluster.name: "cluster", bootstrap.mlockall: true, discovery.zen.ping.multicast.enabled: false } }
- { role: elasticsearch, es_instance_name: "node2", es_config: { node.name: "node2", http.port: 9201, transport.tcp.port: 9301, discovery.zen.ping.unicast.hosts: "localhost:9300", cluster.name: "cluster", bootstrap.mlockall: true, discovery.zen.ping.multicast.enabled: false } }
- { role: elasticsearch, es_instance_name: "node3", es_config: { node.name: "node3", http.port: 9202, transport.tcp.port: 9302, discovery.zen.ping.unicast.hosts: "localhost:9300", cluster.name: "cluster", bootstrap.mlockall: true, discovery.zen.ping.multicast.enabled: false } }
(I assume this is also an issue on redhat, but dont have a system to test.)
I've been testing the role with a few plugins that require java 8 (openjdk-8-jre-headless). Attempting to set the java:
variable directly in the playbook, or in a separate vars file does not override the default. As a workaround, I can set it using the --extra-vars flag on runtime.
The use of include_vars:
in tasks/main.yml
is the culprit. According to https://github.com/ansible/ansible/issues/11807 , this is 'expected behaviour'.
Provide a path from which to install a plugin.
Add a uri parameter to each plugin definition like this
Not sure where the fault lays but should be found out :-)
TASK: [elasticsearch | Start elasticsearch service] ***************************
failed: [localhost] => {"failed": true}
msg: failed determining service state, possible typo of service name?
FATAL: all hosts have already failed -- aborting
Proposal to support:
Some of the above could already be achieved. It may not be appropriate to include this functionality in the default role - we may wish to create a separate management role.
To be discussed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.