Dynamic Data Store
Throughout this role, you may notice the use of the variable dynamic_data_store
.
This is a convention that I have implemented personally within my infrastructure, though it stems from a feature that I'm sure many people leverage in their own way - probably in a very similar manner.
The concept
The dynamic data store is a directory on the Ansible control node (where you're pushing all your Ansible code from).
This directory, in version control, is practically empty, with the exception of a .gitignore
with the following contents:
# Ignore everything in this directory
*
# Except this file
!.gitignore
Using this .gitignore
ensures that the directory (and the .gitignore
) are kept within version control, but anything that may be placed in it is not tracked. As you may have figured out from the name "dynamic", that's because the data here will be subject to change with your infrastructure.
The idea behind having this "empty" directory within your codebase is that, when deploying your Ansible codebase to your Ansible control node, it ensures the directory is there. This directory is then used in conjunction with some roles to store node specific data that you may wish to distribute amongst other nodes.
Use of the dynamic data store in this Sensu role
If you take a look at the tasks/ssl.yml
playbook, there's a use of the fetch
module.
This module works like
copy
, but in reverse. It is used for fetching files from remote machines and storing them locally in a file tree, organized by hostname.
Very handy!
I've coupled this with the generation of SSL certs on the Sensu "master". So, when applying this role to a node on which sensu_master
evaluates to true
, several SSL certs are generated, then stashed on the Ansible control node in the dynamic data store for distribution to client nodes at a later point in the playbook.
I've defined my dynamic_data_store
variable at the top level of my Ansible codebase, in the file group_vars/all.yml
:
dynamic_data_store: /path/to/ansible/config/data/dynamic
Let's take a look at this directory:
$ tree data/dynamic
data/dynamic/
`-- sensu.cmacr.ae
`-- opt
`-- local
`-- etc
`-- sensu
`-- ssl_generation
`-- ssl_certs
|-- client
| |-- cert.pem
| `-- key.pem
|-- sensu_ca
| `-- cacert.pem
`-- server
|-- cert.pem
`-- key.pem
As you can see, it resembles the file tree from the node it fetched the data from. This is configurable behavior, and can be set otherwise if you find this inconvenient/unsightly. See the fetch
documentation for more information.
Deployment of the data fetched to the dynamic data store
Next up is this little play (from the tasks/ssl.yml
playbook):
- name: Deploy the Sensu client SSL cert/key
copy:
src: "{{ item }}"
owner: "{{ sensu_user_name }}"
group: "{{ sensu_group_name }}"
dest: "{{ sensu_config_path }}/ssl"
loop:
- "{{ sensu_ssl_client_cert }}"
- "{{ sensu_ssl_client_key }}"
notify: restart sensu-client service
It takes care of distributing the SSL certificates to the client systems so they can interact with the Sensu API.
The same method is used for node communication with RabbitMQ:
tasks/rabbitmq.yml
- name: Ensure RabbitMQ SSL certs/keys are in place
copy:
src: "{{ item }}"
dest: "{{ sensu_rabbitmq_config_path }}/ssl"
loop:
- "{{ sensu_ssl_server_cacert }}"
- "{{ sensu_ssl_server_cert }}"
- "{{ sensu_ssl_server_key }}"
notify:
- restart rabbitmq service
- restart sensu-api service
- restart sensu-server service
So, what do I need to do?
Well, you simply need to decide where, on your Ansible control node's filesystem, you'd like your dynamic data store to reside.
Then simply set the dynamic_data_store
value to that path for all nodes that are going to be using this Sensu role, as described above.
This variable's value, like any other in Ansible, can include variable(s) itself also.
I have a role that deploys an Ansible control node, and use a variable for where I want my Ansible codebase to sit.
So my dynamic_data_store
(again) defined in group_vars/all.yml
is actually set to:
dynamic_data_store: {{ ansible_conf_path }}/data/dynamic