Deploying InfluxDB with Ansible
By
Todd Persen /
Product
Nov 17, 2015
Navigate to:
Today we will cover how to deploy and configure an instance of the time series database InfluxDB using Ansible.
Why Ansible?
Out of all of the configuration management tools out there, why use Ansible? The answer, at least for me, has always been simplicity. Ansible is an ‘agentless’ configuration management tool, which is to say that it requires zero dependencies to be installed on the target machines prior to getting started. Ansible uses a widely-used, secure communication protocol called SSH (Secure Shell) to execute commands remotely in parallel. This makes Ansible unique in that the only thing stopping you from deploying an Ansible “task” (or “playbook”) to any server is simply an SSH connection and Ansible itself (installation instructions here). Ansible playbooks are also written in a data-serialization format called YAML (a superset of JSON), so you don’t have to learn any new languages to get started.
Why InfluxDB?
InfluxDB is a zero-dependency time series database that strikes the near-perfect balance between ease-of-use and power. With language support for Erlang, Go, Haskell, Python, Java, PHP, and more, it is hard to not find a reason to use InfluxDB for your time series data.
Getting Started
The building block of any Ansible deployment is the ‘task’ file. This file enumerates all of the steps that you will want Ansible to perform in order to configure your server. Ansible also has the concept of a “playbook” (similar to a project), but that is a bit outside the scope of this article.
In order to install and configure InfluxDB, we will need to perform the following steps:
- Setup the InfluxDB repository
- Install InfluxDB
- Configure InfluxDB
- [optional] Any post-configuration steps required - This can include creating databases, loading sample data, or any other steps required before using the database.
- For the remainder of this article, we will assume that we are using an Ubuntu 14.04 server with an Ansible version >= 1.6. The task/playbook we will be creating is available for download here.
Setting up the InfluxDB Repository
To start off, we will need to setup the InfluxDB repository, which is currently hosted at repos.influxdata.com. The first step when adding a repository to the APT package manager is to add the GPG signing key from the package maintainers. This ensures that the packages are verified to be secure. This task will look like:
- name: Import InfluxDB GPG signing key
apt_key: url=https://repos.influxdata.com/influxdb.key state=present
Where the -name
attribute is simply a human-readable declaration of what this task is supposed to accomplish. The apt_key
on the line below is the invocation of Ansible’s built-in apt_key
module, which adds GPG keys to the Ubuntu package manager configuration. The module takes two parameters: a url
field (the URL to the key we want to add) and a state
field (what the status of the key should be once the task is completed, in this case present
since we are adding it to our current configuration).
Once the GPG signing key is added, we will then need to add the repository to our configuration:
- name: Add InfluxDB repository
apt_repository: repo='deb https://repos.influxdata.com/ubuntu trusty stable' state=present
Here we are stating that we would like to use the https://repos.influxdata.com/ubuntu repository (leveraging the apt_repository
module). The trusty
towards the end of the line is referring to the codename of the current Ubuntu release (Trusty Tahr), and the stable
is referring to the package channel we would like to use. The InfluxDB repository currently supports a stable and unstable package channel.
Installing InfluxDB
Now that our repository is added to the system package manager, it is time to install InfluxDB:
- name: Install InfluxDB packages
apt: name=influxdb state=present
This time we are using the apt
module, where the name
refers to the package name we want to install, and state
refers to the status of the package (present
meaning don’t upgrade if it’s already installed). Once the above task has completed, we now know that InfluxDB was successfully installed.
Configuring and Starting InfluxDB
Now that we’ve installed InfluxDB, let’s modify the configuration a bit. By default, the InfluxDB hostname points to localhost
. Let’s change that:
- name: Modify InfluxDB hostname
replace:
dest=/etc/opt/influxdb/influxdb.conf
regexp='hostname = "localhost"'
replace='hostname = "{{ ansible_hostname }}"'
backup=yes
Here we are using the replace
module to replace all instances of the hostname = "localhost"
string with the new and improved hostname = "{{ ansible_hostname }}"
string in the InfluxDB configuration, where, at runtime, the {{ ansible_hostname }}
string will be converted to your server’s real hostname (leveraging the power of Jinja2). The dest
signifies the file we would like to modify, and by using thebackup=yes
flag we are also ensuring backup of the current configuration is made, just in case anything goes awry.
Wait, we just modified the configuration without restarting the service! The new changes won’t take effect until the service is restarted, so let’s do that now:
- name: Start the InfluxDB service
service: name=influxdb state=restarted
Here we are using the service
module to restart the InfluxDB service.
Note: restarting the service on every run is typically not something we want to do (especially if the configuration didn’t even change). We are just using basic tasks for this post, but, as a best-practice, it is recommended to utilize a Handler to make sure a service restart is only executed when the configuration changes.
Loading Some Test Data
By combining the above building blocks, we now have a fully-functioning instance of InfluxDB ready and waiting. One thing that we left out was the post-configuration step described in our list above. While not absolutely mandatory, having a shiny new InfluxDB instance isn’t as exciting if there isn’t some test data ready for us to play with. Let’s create a test database and add some random points:
- name: Create sample database
command: /opt/influxdb/influx -execute 'CREATE DATABASE sample_database'
- name: Load some test data into sample database
uri:
url: https://localhost:8086/write?db=sample_database
method: POST
body: "random_ints,host=server_{{ 10 | random }} value={{ 100 | random }}"
status_code: 204
with_sequence: start=1 end=10
The above is left as an exercise for the reader to decipher. Here are a few links to get you started:
- command module
- Using the Influx Shell
- uri module
- with_sequence looping
- random filter
There is one last step before we can run our new playbook: we have to tell Ansible which server to install InfluxDB on. To do this, we’ll need to create an ‘inventory’ file. This file will simply be a listing of each server we want to run our playbook on. This will vary by your environment, but will resemble the following:
[email protected]
Where ubuntu
is the username you would like to use to authenticate, and influxdb.mydomain.com
is the DNS-resolvable hostname to your server (assuming you already have SSH access). Write this to a file (hosts
, for example), and we’re all set!
Now that we have the pieces necessary to get everything installed, all we need to do is write them to a file (install-influxdb.yml, for example) and have Ansible do the heavy-lifting for us. The exact shell command will vary by your setup, but it is usually of the form:
$ ansible-playbook -i hosts install-influxdb.yml
If everything worked as expected, you should have seen something similar to the following output:
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [influx1]
TASK: [Import InfluxDB GPG signing key] ***************************************
changed: [influx1]
TASK: [Add InfluxDB repository] ***********************************************
changed: [influx1]
TASK: [Install InfluxDB packages] *********************************************
changed: [influx1]
TASK: [Modify InfluxDB hostname] **********************************************
changed: [influx1]
TASK: [Start the InfluxDB service] ********************************************
changed: [influx1]
TASK: [Pause for InfluxDB service] ********************************************
(^C-c = continue early, ^C-a = abort)
[influx1]
Pausing for 3 seconds
ok: [influx1]
TASK: [Create sample database] ************************************************
changed: [influx1]
TASK: [Load some test data into sample database] ******************************
ok: [influx1] => (item=1)
ok: [influx1] => (item=2)
ok: [influx1] => (item=3)
ok: [influx1] => (item=4)
ok: [influx1] => (item=5)
ok: [influx1] => (item=6)
ok: [influx1] => (item=7)
ok: [influx1] => (item=8)
ok: [influx1] => (item=9)
ok: [influx1] => (item=10)
PLAY RECAP ********************************************************************
influx1 : ok=9 changed=6 unreachable=0 failed=0
Note: influx1
is the hostname of my local VM, so you should expect to see something different
You now have a fully functioning (and, more importantly, easily reproducible) InfluxDB instance with some test data to play around with. The full task file used to run this Ansible playbook is available here.