anchor.diff:  :published_at: 2017-07-15
   
   Ansible is a nice tool to deploy distributed systems like Elasticsearch, Kafka, Cassandra and the like.
  -These systems are built to avoid downtime and allow partial failures.
  -But upgrading these software, or updating their configuration, requires restarting each member of the cluster.
  +These systems are built with high availability in mind,
  +they can tolerate partial failures.
  +Upgrading these software, or updating their configuration, requires restarting each member of the cluster.
   
   The aim of this article is to describe a pattern I discovered
   trying to improve deployment speed of Ansible playbooks
  
positive.code:     - role: elasticsearch
  ----
  
  But deploying every host one after the other (in serial) takes a very long time and makes deployment endless.
  
  == Refactoring the role
  
  The main idea to improve speed is to split the role into multiple steps, and do as much as possible in parallel:
  
  1. *In Parallel*: Deploy system settings, software settings, software binaries.
    But don't stop anything and don't remove anything.
  2. *In Serial*:
    * Stop the node
    * Install or upgrade the node as quickly as possible
    * Start the node
  3. *In Parallel*: finish applying settings on running cluster and remove old files and binaries.
  
  Then describe each step in its own YAML file: `before.yml`, `stop_start.yml` and `after.yml`.
  Finally, the role entry point `main.yml` will include the appropriate step using a variable named `elasticsearch_step`:
  
negative.code:     - role: elasticsearch
  ----
  
  At some point, the `elasticsearch` role will probably contain something to stop Elasticsearch in order for changes to be reloaded:
  
  .roles/elasticsearch/tasks/main.yml
  [source,yaml]
  