11 November 2019

Only Once Ansible Task Execution

Ansible is a great tool to setup multiple servers in a consistent reproducible way. It is easy to setup a complete cluster or a complex software architecture running on multiple machines. But some tasks only need to be executed once. For example you can setup a complete cluster of DB servers, but the table definitions/content only needs to be done once, after the cluster is running. Since the goal of Ansible is to always end with a consistent state it should be OK to run the same task multiple times, without breaking your setup (idempotent), but if you setup a bigger cluster with Hundertes of nodes, you would definitely want to avoid running the same task over and over again, if this can be avoided.

There a basically two options that you can use to ensure a task is executed only once.

run_once: True

Code sample take from the official documentation:
---
# ...
  tasks:

  - name: Send summary mail
    local_action:
      module: mail
      subject: "Summary Mail"
      to: "{{ mail_recipient }}"
      body: "{{ mail_body }}"
    run_once: True
Not working if you use serial playbook execution!

However this approach only works if you run your setup on all nodes simultaneously. If you run your playbook in a sequential order (using serial: 1) your run_once task will be executed each time.
If you plan to extend or upgrade your existing cluster you will have to set serial: 1 to ensure that each node gets updated one after the other. If you would upgrade all nodes at once, you would have a complete cluster outage. Please read the next section for an alternative approach.

localhost execution

When you setup a complete cluster with ansible, you can usually reach this cluster from your localhost. Of course ssh port needs to be available anyway to run ansible, but in most cases you will also have access to the application port (e.g. from your DB) as well. By setting the hosts in your playbook to localhost you can also ensure that each role/task in your playbook is also executed only once.
---
- name: Setup elasticsearch configuration
  hosts: localhost
  roles:
    - role: elasticsearch-config
Not working if you want to setup your application cluster within the same playbook

If you want to setup your application cluster in a sequential way as well as setting up some configuration only once for your cluster, you need to define two different playbooks and then have another one importing both playbooks.
---
# Setup complete ELK stack for the cluster
- import_playbook: prepare_server.yml
- import_playbook: elasticsearch.yml
- import_playbook: elasticsearch-config.yml
- import_playbook: kibana.yml
- import_playbook: zookeeper.yml
- import_playbook: kafka.yml
- import_playbook: logstash.yml
- import_playbook: metricbeat.yml
- import_playbook: filebeat.yml
The playbook elasticsearch.yml will run with serial: 1 setting up each node one after the other, while the elasticsearch-config.yml playbook will be executed on your localhost only (once) the cluster is running. This way you can combine both approaches together.

1 comment:

  1. I use to read blogs on daily basis for new informations, your this blog is one of the best information i come to read today. Hope you are doing same work for new updates.

    Digital Marketing Services in delhi

    ReplyDelete