Elasticsearch Puppet module
This module sets up Elasticsearch instances with additional resource for plugins, templates, and more.
This module is actively tested against Elasticsearch 2.x, 5.x, and 6.x.
In order to simplify the management of Elasticsearch moving forward, and add support for both Elasticsearch 6.x and 7.x, support for running multiple instances of Elasticsearch has been removed.
This module also does not currently handle the migration from the instance based configuration to the new single deployment model.
Therefore in-place upgrades from version 6.x of this module to 7.x, or migrations from multi-instance to single deployment is not currently supported.
We hope to add support for this in a future release.
Therefore please ensure that you test this major release in your environment before using it in production!
Beginning with Elasticsearch 7.0.0, a Java JDK has been bundled as part of the elasticsearch package.
However there still needs to be a version of Java present on the system being managed in order for Puppet to be able to run various utilities.
We recommend managing your Java installation with the puppetlabs-java module.
When using the repository management, the following module dependencies are required:
Declare the top-level
elasticsearchclass (managing repositories) and set up an instance:
include ::javaclass { 'elasticsearch': }
Most top-level parameters in the
elasticsearchclass are set to reasonable defaults. The following are some parameters that may be useful to override:
class { 'elasticsearch': version => '7.9.3' }
Note: This will only work when using the repository.
By default, the module will not restart Elasticsearch when the configuration file, package, or plugins change. This can be overridden globally with the following option:
class { 'elasticsearch': restart_on_change => true }
Or controlled with the more granular options:
restart_config_change,
restart_package_change, and
restart_plugin_change.
class { 'elasticsearch': autoupgrade => true }
class { 'elasticsearch': ensure => 'absent' }
class { 'elasticsearch': status => 'disabled' }
Some resources, such as
elasticsearch::template, require communicating with the Elasticsearch REST API. By default, these API settings are set to:
class { 'elasticsearch': api_protocol => 'http', api_host => 'localhost', api_port => 9200, api_timeout => 10, api_basic_auth_username => undef, api_basic_auth_password => undef, api_ca_file => undef, api_ca_path => undef, validate_tls => true, }
Each of these can be set at the top-level
elasticsearchclass and inherited for each resource or overridden on a per-resource basis.
This module supports managing all of its defined types through top-level parameters to better support Hiera and Puppet Enterprise. For example, to manage an index template directly from the
elasticsearchclass:
class { 'elasticsearch': templates => { 'logstash' => { 'content' => { 'template' => 'logstash-*', 'settings' => { 'number_of_replicas' => 0 } } } } }
This module can help manage a variety of plugins. Note that
module_diris where the plugin will install itself to and must match that published by the plugin author; it is not where you would like to install it yourself.
elasticsearch::plugin { 'x-pack': }
elasticsearch::plugin { 'jetty': url => 'https://oss-es-plugins.s3.amazonaws.com/elasticsearch-jetty/elasticsearch-jetty-1.2.1.zip' }
You can also use a proxy if required by setting the
proxy_hostand
proxy_portoptions:
puppet elasticsearch::plugin { 'lmenezes/elasticsearch-kopf', proxy_host => 'proxy.host.com', proxy_port => 3128 }
Proxies that require usernames and passwords are similarly supported with the
proxy_usernameand
proxy_passwordparameters.
Plugin name formats that are supported include:
elasticsearch/plugin/version(for official elasticsearch plugins downloaded from download.elastic.co)
groupId/artifactId/version(for community plugins downloaded from maven central or OSS Sonatype)
username/repository(for site plugins downloaded from github master)
When you specify a certain plugin version, you can upgrade that plugin by specifying the new version.
elasticsearch::plugin { 'elasticsearch/elasticsearch-cloud-aws/2.1.1': }
And to upgrade, you would simply change it to
elasticsearch::plugin { 'elasticsearch/elasticsearch-cloud-aws/2.4.1': }
Please note that this does not work when you specify 'latest' as a version number.
For the Elasticsearch commercial plugins you can refer them to the simple name.
See Plugin installation for more details.
Installs scripts to be used by Elasticsearch. These scripts are shared across all defined instances on the same host.
elasticsearch::script { 'myscript': ensure => 'present', source => 'puppet:///path/to/my/script.groovy' }
Script directories can also be recursively managed for large collections of scripts:
elasticsearch::script { 'myscripts_dir': ensure => 'directory, source => 'puppet:///path/to/myscripts_dir' recurse => 'remote', }
By default templates use the top-level
elasticsearch::api_*settings to communicate with Elasticsearch. The following is an example of how to override these settings:
elasticsearch::template { 'templatename': api_protocol => 'https', api_host => $::ipaddress, api_port => 9201, api_timeout => 60, api_basic_auth_username => 'admin', api_basic_auth_password => 'adminpassword', api_ca_file => '/etc/ssl/certs', api_ca_path => '/etc/pki/certs', validate_tls => false, source => 'puppet:///path/to/template.json', }
This will install and/or replace the template in Elasticsearch:
elasticsearch::template { 'templatename': source => 'puppet:///path/to/template.json', }
This will install and/or replace the template in Elasticsearch:
elasticsearch::template { 'templatename': content => { 'template' => "*", 'settings' => { 'number_of_replicas' => 0 } } }
Plain JSON strings are also supported.
elasticsearch::template { 'templatename': content => '{"template":"*","settings":{"number_of_replicas":0}}' }
elasticsearch::template { 'templatename': ensure => 'absent' }
Pipelines behave similar to templates in that their contents can be controlled over the Elasticsearch REST API with a custom Puppet resource. API parameters follow the same rules as templates (those settings can either be controlled at the top-level in the
elasticsearchclass or set per-resource).
This will install and/or replace an ingestion pipeline in Elasticsearch (ingestion settings are compared against the present configuration):
elasticsearch::pipeline { 'addfoo': content => { 'description' => 'Add the foo field', 'processors' => [{ 'set' => { 'field' => 'foo', 'value' => 'bar' } }] } }
elasticsearch::pipeline { 'addfoo': ensure => 'absent' }
This module includes basic support for ensuring an index is present or absent with optional index settings. API access settings follow the pattern previously mentioned for templates.
At the time of this writing, only index settings are supported. Note that some settings (such as
number_of_shards) can only be set at index creation time.
elasticsearch::index { 'foo': settings => { 'index' => { 'number_of_replicas' => 0 } } }
elasticsearch::index { 'foo': ensure => 'absent' }
By default snapshotrepositories use the top-level `elasticsearch::api*` settings to communicate with Elasticsearch. The following is an example of how to override these settings:
elasticsearch::snapshot_repository { 'backups': api_protocol => 'https', api_host => $::ipaddress, api_port => 9201, api_timeout => 60, api_basic_auth_username => 'admin', api_basic_auth_password => 'adminpassword', api_ca_file => '/etc/ssl/certs', api_ca_path => '/etc/pki/certs', validate_tls => false, location => '/backups', }
elasticsearch::snapshot_repository { 'backups': ensure => 'absent', location => '/backup' }
This module offers a way to make sure an instance has been started and is up and running before doing a next action. This is done via the use of the
es_instance_conn_validatorresource.
puppet es_instance_conn_validator { 'myinstance' : server => 'es.example.com', port => '9200', }
A common use would be for example :
class { 'kibana4' : require => Es_Instance_Conn_Validator['myinstance'], }
There are two different ways of installing Elasticsearch:
This module uses the
elastic/elastic_stackmodule to manage package repositories. Because there is a separate repository for each major version of the Elastic stack, selecting which version to configure is necessary to change the default repository value, like this:
class { 'elastic_stack::repo': version => 6, }class { 'elasticsearch': version => '6.8.12', }
This module defaults to the upstream package repositories, which as of Elasticsearch 6.3, includes X-Pack. In order to use the purely OSS (open source) package and repository, the appropriate
ossflag must be set on the
elastic_stack::repoand
elasticsearchclasses:
class { 'elastic_stack::repo': oss => true, }class { 'elasticsearch': oss => true, }
You may want to manage repositories manually. You can disable automatic repository management like this:
class { 'elasticsearch': manage_repo => false, }
When a repository is not available or preferred you can install the packages from a remote source:
class { 'elasticsearch': package_url => 'https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.2.deb', proxy_url => 'http://proxy.example.com:8080/', }
Setting
proxy_urlto a location will enable download using the provided proxy server. This parameter is also used by
elasticsearch::plugin. Setting the port in the
proxy_urlis mandatory.
proxy_urldefaults to
undef(proxy disabled).
class { 'elasticsearch': package_url => 'puppet:///path/to/elasticsearch-1.4.2.deb' }
class { 'elasticsearch': package_url => 'file:/path/to/elasticsearch-1.4.2.deb' }
When configuring Elasticsearch's memory usage, you can modify it by setting
jvm_options:
class { 'elasticsearch': jvm_options => [ '-Xms4g', '-Xmx4g' ] }
Currently only the basic SysV-style init and Systemd service providers are supported, but other systems could be implemented as necessary (pull requests welcome).
The defaults file (
/etc/defaults/elasticsearchor
/etc/sysconfig/elasticsearch) for the Elasticsearch service can be populated as necessary. This can either be a static file resource or a simple key value-style hash object, the latter being particularly well-suited to pulling out of a data source such as Hiera.
class { 'elasticsearch': init_defaults_file => 'puppet:///path/to/defaults' }
$config_hash = { 'ES_HEAP_SIZE' => '30g', }class { 'elasticsearch': init_defaults => $config_hash }
Note:
init_defaultshash can be passed to the main class and to the instance.
File-based users, roles, and certificates can be managed by this module.
Note: If you are planning to use these features, it is highly recommended you read the following documentation to understand the caveats and extent of the resources available to you.
Roles in the file realm can be managed using the
elasticsearch::roletype. For example, to create a role called
myrole, you could use the following resource:
elasticsearch::role { 'myrole': privileges => { 'cluster' => [ 'monitor' ], 'indices' => [{ 'names' => [ '*' ], 'privileges' => [ 'read' ], }] } }
This role would grant users access to cluster monitoring and read access to all indices. See the Security documentation for your version to determine what
privilegesto use and how to format them (the Puppet hash representation will simply be translated into yaml.)
Note: The Puppet provider for
elasticsearch_userhas fine-grained control over the
roles.ymlfile and thus will leave the default roles in-place. If you would like to explicitly purge the default roles (leaving only roles managed by puppet), you can do so by including the following in your manifest:
resources { 'elasticsearch_role': purge => true, }
Associating mappings with a role for file-based management is done by passing an array of strings to the
mappingsparameter of the
elasticsearch::roletype. For example, to define a role with mappings:
elasticsearch::role { 'logstash': mappings => [ 'cn=group,ou=devteam', ], privileges => { 'cluster' => 'manage_index_templates', 'indices' => [{ 'names' => ['logstash-*'], 'privileges' => [ 'write', 'delete', 'create_index', ], }], }, }
If you'd like to keep the mappings file purged of entries not under Puppet's control, you should use the following
resourcesdeclaration because mappings are a separate low-level type:
resources { 'elasticsearch_role_mapping': purge => true, }
Users can be managed using the
elasticsearch::usertype. For example, to create a user
mysuserwith membership in
myrole:
elasticsearch::user { 'myuser': password => 'mypassword', roles => ['myrole'], }
The
passwordparameter will also accept password hashes generated from the
esusers/
usersutility and ensure the password is kept in-sync with the Shield
usersfile for all Elasticsearch instances.
elasticsearch::user { 'myuser': password => '$2a$10$IZMnq6DF4DtQ9c4sVovgDubCbdeH62XncmcyD1sZ4WClzFuAdqspy', roles => ['myrole'], }
Note: When using the
esusers/
usersprovider (the default for plaintext passwords), Puppet has no way to determine whether the given password is in-sync with the password hashed by Elasticsearch. In order to work around this, the
elasticsearch::userresource has been designed to accept refresh events in order to update password values. This is not ideal, but allows you to instruct the resource to change the password when needed. For example, to update the aforementioned user's password, you could include the following your manifest:
notify { 'update password': } ~> elasticsearch::user { 'myuser': password => 'mynewpassword', roles => ['myrole'], }
SSL/TLS can be enabled by providing the appropriate class params with paths to the certificate and private key files, and a password for the keystore.
class { 'elasticsearch' : ssl => true, ca_certificate => '/path/to/ca.pem', certificate => '/path/to/cert.pem', private_key => '/path/to/key.pem', keystore_password => 'keystorepassword', }
Note: Setting up a proper CA and certificate infrastructure is outside the scope of this documentation, see the aforementioned security guide for more information regarding the generation of these certificate files.
The module will set up a keystore file for the node to use and set the relevant options in
elasticsearch.ymlto enable TLS/SSL using the certificates and key provided.
System keys can be passed to the module, where they will be placed into individual instance configuration directories. This can be set at the
elasticsearchclass and inherited across all instances:
class { 'elasticsearch': system_key => 'puppet:///path/to/key', }
If you use the aforementioned security features, you may need to install a user license to leverage particular features outside of a trial license. This module can handle installation of licenses without the need to write custom
execor
curlcode to install license data.
You may instruct the module to install a license through the
elasticsearch::licenseparameter:
class { 'elasticsearch': license => $license, }
The
licenseparameter will accept either a Puppet hash representation of the license file json or a plain json string that will be parsed into a native Puppet hash. Although dependencies are automatically created to ensure that the Elasticsearch service is listening and ready before API calls are made, you may need to set the appropriate
api_*parameters to ensure that the module can interact with the Elasticsearch API over the appropriate port, protocol, and with sufficient user rights to install the license.
The native provider for licenses will not print license signatures as part of Puppet's changelog to ensure that sensitive values are not included in console output or Puppet reports. Any fields present in the
licenseparameter that differ from the license installed in a cluster will trigger a flush of the resource and new
POSTto the Elasticsearch API with the license content, though the sensitive
signaturefield is not compared as it is not returned from the Elasticsearch licensing APIs.
There are several different ways of setting data directories for Elasticsearch. In every case the required configuration options are placed in the
elasticsearch.ymlfile.
By default we use:
/var/lib/elasticsearch
Which mirrors the upstream defaults.
It is possible to override the default data directory by specifying the
datadirparam:
class { 'elasticsearch': datadir => '/var/lib/elasticsearch-data' }
It's also possible to specify multiple data directories using the
datadirparam:
class { 'elasticsearch': datadir => [ '/var/lib/es-data1', '/var/lib/es-data2'] }
See the Elasticsearch documentation for additional information regarding this configuration.
The
configoption can be used to provide additional configuration options to Elasticsearch.
The
confighash can be written in 2 different ways:
Instead of writing the full hash representation:
class { 'elasticsearch': config => { 'cluster' => { 'name' => 'ClusterName', 'routing' => { 'allocation' => { 'awareness' => { 'attributes' => 'rack' } } } } } }
class { 'elasticsearch': config => { 'cluster' => { 'name' => 'ClusterName', 'routing.allocation.awareness.attributes' => 'rack' } } }
Recent versions of Elasticsearch include the elasticsearch-keystore utility to create and manage the
elasticsearch.keystorefile which can store sensitive values for certain settings. The settings and values for this file can be controlled by this module. Settings follow the behavior of the
configparameter for the top-level Elasticsearch class and
elasticsearch::instancedefined types. That is, you may define keystore settings globally, and all values will be merged with instance-specific settings for final inclusion in the
elasticsearch.keystorefile. Note that each hash key is passed to the
elasticsearch-keystoreutility in a straightforward manner, so you should specify the hash passed to
secretsin flattened form (that is, without full nested hash representation).
For example, to define cloud plugin credentials for all instances:
class { 'elasticsearch': secrets => { 'cloud.aws.access_key' => 'AKIA....', 'cloud.aws.secret_key' => 'AKIA....', } }
By default, if a secret setting exists on-disk that is not present in the
secretshash, this module will leave it intact. If you prefer to keep only secrets in the keystore that are specified in the
secretshash, use the
purge_secretsboolean parameter either on the
elasticsearchclass to set it globally or per-instance.
Any changes to keystore secrets will notify running elasticsearch services by respecting the
restart_on_changeand
restart_config_changeparameters.
Class parameters are available in the auto-generated documentation pages. Autogenerated documentation for types, providers, and ruby helpers is also available on the same documentation site.
This module is built upon and tested against the versions of Puppet listed in the metadata.json file (i.e. the listed compatible versions on the Puppet Forge).
The module has been tested on:
Testing on other platforms has been light and cannot be guaranteed.
Please see the CONTRIBUTING.md file for instructions regarding development environments and testing.
Need help? Join us in #elasticsearch on Freenode IRC or on the discussion forum.