# Ansible

## Summary


When software is delivered as a service, it's important that the server and the application running on it are initialized or configured correctly. Sometimes server modules or the application itself will need to be patched or upgraded. This task is more difficult when the service resides in the cloud and is running on multiple servers. What we need is a tool to automate these tasks. This is where Ansible is useful. 

Ansible is well known as a configuration tool that can help us put a remote machine into a desired state. But Ansible can do more: deploy applications, orchestrate multiple tasks across multiple machines, run ad-hoc commands. In short, Ansible is a tool that enables Infrastructure-as-Code (IaC).  

Ansible is open source and is sponsored by Red Hat.

## Discussion

### What are some typical use cases of Ansible?

The main uses of Ansible are the following: 

    + **Provisioning**: Provision bare-metal servers, VMs, cloud instances, and more.
    + **Configuration Management**: Centralize configuration and push the same to all machines. This means a consistent environment for your services regardless of the machine.
    + **App Deployment**: Manage your app's lifecycle easily, from development to production.
    + **Continuous Delivery**: Create CI/CD pipelines without additional complexity.
    + **Security & Compliance**: Scan and remediate site-wide security policies.
    + **Orchestration**: Orchestrate how multiple configurations interact; manage the environment as a whole and not in silos.Consider an example of orchestration. A three-tier web app will have app servers, database servers, content servers, load balancers and a monitoring system. Ansible can do a complex cluster-wide rolling update without any downtime. In fact, Ansible enables *immutable infrastructure*, meaning that we can replace servers without service disruption. 

It's interesting to note that Ansible configuration can be seen as a type of documentation and a solution for disaster recovery. 


### In Ansible, what do mean by "agentless" architecture?

To configure a number of host machines, one approach is to install custom programs, called **agents**, on each of these machines. The system will also have a server or control node that contains the current configuration. Each agent will periodically poll the server to obtain the configuration. The server and agent communicate using a common pre-defined protocol and port. This is otherwise called the *pull* approach. 

In Ansible, there are no agents. It uses the *push* approach, whereby the server pushes configuration or commands to the hosts. Hosts are often diverse. Installing agent programs on different OS/platform is a hassle. In Ansible, SSH is used by the server to talk to a host. OpenSSH is widely deployed. It's open source and lightweight. 

What if an agent crashes? What if server and agents have mismatching versions? Some agents have reportedly used 400MB of memory. Ansible's agentless architecture avoids all these issues. We can start managing the hosts with *zero bootstrapping*. 


### Could you describe some essentials Ansible terms?

From the complete Ansible Glossary, we describe a few essential terms:  

    + **Node**: Can either be a *Control Node* or a *Managed Node*. Ansible is installed on control nodes but not on managed nodes. Managed nodes are also called *hosts*.
    + **Inventory**: A list of managed nodes, specified by an inventory file or *hostfile*. Hosts can be organized into *groups* for easier scaling.
    + **Task**: A unit of execution in Ansible. Each task has an associated command and does a single operation unless it has a *loop*.
    + **Playbook**: An ordered list of tasks. These are designed to be easy to read, write, share and understand. Playbooks can use *variables*.
    + **Module**: Reusable code that Ansible executes and can be invoked by a task. Ansible comes with dozens of out-of-the-box and ready-to-use modules. Modules are typically organized by their purpose: crypto, database, identity, messaging, network, storage, etc.
    + **Role**: Makes playbooks modular and reusable. These are units of organization in Ansible. A role can apply variables, tasks or handlers to hosts or groups.

### What's the Ansible architecture?

Ansible executes on a control node and connects to hosts using SSH by default. Control node can be Linux, MacOS, or even any machine that has Python 2.7 or 3.5+ installed. Nodes need to have either SSH or PowerShell (Windows); and Python 2.6+ or 3.5+ installed. File transfer is done using `sftp` or `scp`. 

Hosts to be managed are listed in files called inventory. Modules offer reusable execution code. Playbooks contain step-by-step instructions. 

Configuration and playbooks are stored as YAML files in a well-defined directory layout. YAML is easier to learn than bash scripting. Ansible Tower, the enterprise version of Ansible, allows configuration to be stored in configuration management databases (CMDB), using PostgreSQL or MongoDB. 

It's been said that, 

> If Ansible modules are the tools in your workshop, playbooks are your instruction manuals, and your inventory of hosts are your raw material.


### Could you share some best practices when using Ansible?

Keep it simple. Think declaratively. Don't write code in playbooks. Since modules abstract away complexity, always check if there's a module to accomplish what you want. Avoid using run commands (`command`, `shell`, `raw`, `script`), since error and state handling are difficult. Instead, write your own modules. 

Don't ignore errors with `ignore_errors: yes` since you'll miss unexpected errors as well. Instead use `failed_when` and other alternatives. Along with roles, use `import*` and `include*` statements to logically chunk and reuse Ansible content. 

In the interest of readability, use descriptive names for both plays and tasks. Variable names can collide. Use prefixes to avoid collision and also improve readability, such as, `apache_port` and `tomcat_port` rather than just `port`. 

YAML's native syntax for name-value pairs is `name: value`. Use this for readability in preference of Ansible's shorthand `name=value`. The YAML syntax is easier to read and highlighted by editors and IDEs. 

When using the debug module, use the `verbosity` parameter to suppress debug messages in production. 

Organize your playbooks based on roles. Have separate inventory for staging and production. Define groups based on roles and geography. 

Ansible-Lint and Playbook Best Practices guides can help.


### Could you point to useful resources to get started with Ansible?

From Ansible's official site, read an overview of Ansible. Learn about setting up SSH keys and running your first commands in the Getting Start guide. There are also a number of useful whitepapers on Ansible.

To be part of or contribute, read the Ansible Community Guide.

Ansible Galaxy is a hub for downloading useful roles. Official documentation lists all Ansible modules.

## Milestones

2008

While at Red Hat, Michael DeHaan starts **Cobbler**, a tool to manage Linux server environments including provisioning, managing DNS and DHCP, updating packaging, and more. Since Cobbler is unable to run ad-hoc tasks on remote hosts, **Func** is invented. The roots of Ansible are in these early tools.  

Feb  
2012

Ansible begins as project with system administrators and developers being early adopters. An early adopter is Fedora Infrastructure where Puppet is replaced with Ansible. Ansible embraces the "batteries included" philosophy, with folks contributing modules. 

Feb  
2013

Ansible 1.0 is released. We can now use `when_failed` and `when_changed` in playbooks. With v1.2.1 (July 2013), default connection is OpenSSH if it supports ControlPersists; else, fall back to Paramiko. 

Aug  
2014

Ansible 1.7 is released. It's the first version to support Windows hosts using native PowerShell rather than SSH. On the control node, Python module `winrm` is used. Though control node can't be Windows, Windows Subsystem for Linux (WSL) bash shell can be used. 

Jan  
2016

Ansible 2.0 is released. 

Sep  
2017

Ansible 2.4 is released. For hosts, support for Python 2.4 and 2.5 are dropped. Old `include` directives are replaced with `import` (static) and `include` (dynamic). Keyword `order` can be used to specify the order in which hosts are processed. Inventory is revamped. The release is updated in July 2018 as v2.4.7. 

Mar  
2018

Ansible 2.5 is released. It's recommended to use `loop` keyword instead of `with_*` style loops. The new syntax is better with filters instead of using complex `query` or `lookup`. Two top-level persistent connection types are introduced, `network_cli` and `netconf`. Where possible, prefer these over `local` connections. 

2019

A survey of 786 IT professionals shows that Ansible is popular as a configuration tool for cloud infrastructure. Terraform has the largest growth in adoption.