Infrastructure Automation with Ansible
Automating infrastructure increases efficiency, reliability, repeatability, and more. Managing servers through GUIs can be laborious, and it's difficult to keep track of all the appropriate buttons to click for a correct deployment and configuration.
Moving from a GUI (graphical user interface) to a CLI (command line interface) is a start, though you still find yourself repeating or copy and pasting slight variants of the same commands to do similar things. Next, you might upgrade to writing bash scripts that repeat the CLI commands for you. And by using environmental variables along with bash scripts, you could achieve many of the benefits of infrastructure as code.
However, bash is not as powerful and flexible as a full-fledged programming language such as Python or Go. In your pursuit of more powerful, efficient, and elegant automation, you could take one more step up and move from using the CLI to the API (application programming interface) with a client library written in your language of choice. For example pyVmomi, a Python library for interacting with the vSphere API, or the AWS SDK for Java.
Tools like Ansible, Terraform, Cloud Formation, and vRealize have created an even more efficient layer on top of programming with APIs and client libraries. Though these tools have many differences, they all provide templating in a markup language like YAML, to make even scripting easier, faster, and more flexible. Before we dive into Ansible specifically, let's look at the different types of tools to see how Ansible fits in.
Configuration Management vs Orchestration
Configuration management is mainly concerned with configuring servers once they have already been provisioned; conversely, orchestration is mainly concerned with provisioning the servers. Provisioning is done by interacting with APIs like vSphere and AWS to bring up virtual machines, networks, and storage. Configuration management is often done by editing configuration files for silent deployments and sending SSH commands to customize Linux and the software running on it.
Ansible is primarily designed as a configuration management tool, though like most of the tools, it is capable of both. On the other end of the spectrum is Terraform, which is designed to excel at orchestration. It is typical to use Terraform to provision a resource, then have it trigger Ansible to configure the resource. In less complex use cases, it can be more efficient to just use one tool for the entire process.
The platform-specific tools like AWS's Cloud Formation, Google's Deployment Manager, and VMware's vRealize Automation are primarily orchestration tools. Though they are capable of some configuration management, they tend to leave it to cross-platform tools like Ansible, Puppet, Chef, and Salt.
Declarative vs Imperative
Another dimension to infrastructure automation tools is which programming paradigm they chose. Ansible is imperative (designed for commands), which means you tell it what to do step by step. Terraform is declarative (designed for descriptions), which means you describe the desired state of your infrastructure, and Terraform figures out how to make that happen.
As a simple example, let's say you need to create three VMs that are identical copies, then later you decide to scale down and delete one. Ansible is not primarily for provisioning VMs, but you could use it that way. You'd write a Playbook (what Ansible calls the YAML files you write to describe your workflows) to delete VMs, then later you'd write one to delete a VM. In both cases, you just tell Ansible what to do (give it imperative commands).
With Terraform you'd write a .tf configuration file that described an environment with three copies and run "terraform apply." Later you'd simple edit that description, change the number of copies from three to two, then run "terraform apply" again. Notice that you describe the desired state of your infrastructure, rather than tell Terraform what to do specifically (delete a VM).
Orchestration tools tend to be declarative, as that is a convenient way to evolve infrastructure over time. Imperative can make more sense for configuration management, as it tends to be more of a sequential set of tasks. However, some configuration management tools, most notably Puppet, are declarative. For more on Declarative vs Imperative check out our blog post on that topic.
|Tool||Paradigm||Primary Purpose||Cross Platform|
|AWS Cloud Formation||Declarative||Orchestration||No|
Now that we see where Ansible fits, as an imperative configuration management tool, let's dive into its usage and terminology. As an imperative tool, Ansible is a system for wrapping your scripts in YAML templates called Playbooks. Ansible Playbooks are primarily made up of Tasks, which are the ordered list of commands Ansible will execute on your behalf. These can be simple SSH commands, or complex code that interact with several APIs.
Each task references an Ansible Module, which contains the code that makes your task happen. For example, let's say you are configurating a web server and you want to create the /var/www/html/ folder - you could write a Task that uses the official Ansible File Module. With the File Module, you can create and delete files and folders, change their permissions, etc.
Here's a simple Ansible Playbook file, config-web-server.yaml, to create the folder described above:
- hosts: webservers
This file starts with a standard three dashes, then has some number of Plays. Each Play has the hosts to connect to, then the commands to run on them (Tasks). In this case, we just have one Play with one Task, but you can have many Plays, each with many Tasks. The Task references the Ansible File Module, and gives the details for the file/folder manipulation that is to occur. Underneath the hood, the File Module is just a Python file that Ansible runs for you according to your YAML configuration. Since Ansible is open source, you can look at file.py (File Module) in the Ansible Github and see exactly what it does.
This is a very simple module that only interacts with Linux. But there are a wide variety of Modules built into Ansible, such as hundreds of Modules for interacting with various cloud platforms such as GCP, AWS, and vSphere. In the case of vSphere, there are great built in Modules, but if you wanted to configure NSX you would need to add additional modules (nsxansible) built by VMware, but not included in stock Ansible. If those still didn't do what you needed, you might need to find modules developed by the community, or even write them yourself.
While writing your own modules is not at all necessary for most common functions, it is a convenient way to integrate entirely custom logic into Ansible. By writing your scripts as Ansible Modules, you gain access to the templating system, Ansible Vault for storing encrypted information. Additionally, you can easily weave your scripts with all the Modules of Ansible and its community.