Ansible Architecture

Ansible Architecture | Ansible Automation

As a best practice, you don’t want your Ansible architecture that consists of playbooks and Inventory to be too specific. But, on the other hand, you need to have a certain level of abstraction and keep out very specific information. Therefore, to develop flexible code, you must separate site-specific information from the code, and this is done with variables in Ansible. Keep in mind that when you develop dynamic code along with your static information, you can use this on any site with minor modifications to the variables themselves. However, there are different places you can have variables, and where you place variables, such as a play header or Inventory, will take different precedence. So, to provide site-specific code, variables can be used. However, keeping variables in the Inventory itself may not be a flexible solution for your automation efforts.

Ansible Architecture

Diagram: Ansible Architecture and Variables.

 

Ansible Architecture: The Drive for Automation

To move to an Ansible architecture has been driven by several megatrends. Firstly, the rise of distributed computing made the manual approach to almost anything in the I.T environment obsolete. Not only because this causes many errors and mistakes, but the configuration drift from desired to actual state was considerable. Not only is this an operational burden but also a considerable security risk. Today it’s common to deploy applications by combining multiple services that run on a distributed set of resources. As a result, there is a lot more complexity to configuration and maintenance than what we had in the past.

You have two options to implement all of this. First, you can connect up these services by, for example, manually: spinning up the servers, installing the necessary packages, SSHing to each one, or you can go down the path of automation, in particular, automation with Ansible. So with Ansible, we have both the Automation Engine, the CLI, and Ansible Tower, which is more of an automation platform for enterprise-grade automation. This post focuses on Ansible Engine. 

 

Ansible Automation Requirements

Diagram: Ansible Automation Requirements

 

As a quick note, if you have environments with more than a few teams automating, I recommend Ansible Tower or the open-source version of AWX. This is because Ansible Tower has a 60-day trial license, while AWX is fully open-sourced and does not require a license.

 

  • A Key Point: Risky: The Manual Way.

Let me put it this way. If you are configuring manually, you will likely maintain all the settings manually. Or, more importantly, what about mitigating vulnerabilities and determining what patches or packages are installed in a large environment? With the manual approach, how can you be sure that all your servers are patched and secured?. Manipulating configuration files by hand is a tedious and error-prone task. Not to mention time-consuming. Equally, performing pattern matching to make changes to existing files is risky. 

  • A Key Point: The issue of Configuration Drift

The manual approach will result in configuration drift, where some servers will drift from the desired state. Configuration drift is caused by inconsistent configuration items across devices, usually due to manual changes and updates and not following the path of automation. Ansible is all about maintaining the desired state and eliminating configuration drift.

 

Components of Ansible Architecture

    • Configuration Management

Ansible is a configuration management tool that can help alleviate these challenges. Ansible replaces the need for an operator to manually tune configuration files and does a good job in application deployment and orchestrating multi-deployment scenarios. It can also be integrated into CI/CD pipelines. In reality, Ansible is relatively easy to install and operate. However, it is not a single entity. Instead, it comprises tools, modules, and software-defined infrastructure that form the ansible toolset configured from a single host that can manage multiple hosts. We will discuss the value of idempotency with Ansible modules later in mind. Even with the idempotency nature of modules, you can still have users of Ansible automate over each other. Ansible Tower or AWS is the recommended solution for multi-team automation efforts.

 

    • Pre-deployed infrastructure: Terraform

Ansible does not deploy the infrastructure; you could use other solutions like Terraform that are best suited for this. Terraform is infrastructure as a code tool. Ansible Engine is more of a configuration as code. The physical or virtual infrastructure needs to be there for Ansible to automate, compared to Terraform, which does all of this for you. Ansible is an easy-to-use DevOps tool that manages configuration as code has in the same configuration through any sized environment. Therefore, the size of the environment is irrelevant to Ansible. As Ansible connectivity uses SSH that runs over TCP, there are multiple optimizations you can use to increase performance and optimize connectivity which we will discuss shortly. Ansible is often described as a configuration management tool and is typically mentioned in the same lines as Puppet, Chef, and Salt. However, there is a considerable difference in how they operate. Most notably, the installation of agents.

 

    • Ansible Architecture: Agentless

Ansible is agentless and requires nothing to be installed on the managed systems. In addition, its architecture is serverless and agentless, so it has a minimal footprint. Some configuration management systems such as Chef and Puppet are “pull-based” by default. Where agents are installed, periodically check in with the central service and pull-down configuration. Ansible is agentless and does not require the installation of an agent on the target for Ansible to communicate to the target host. However, it requires connectivity from the control host to the target inventory ( which contains a list of hosts that Ansible manages) with a trusted relationship. For convenience, we can have passwordless sudo connectivity between our hosts. This allows you to log in without a password and can be a security risk if someone gets to your machines; they could have escalated privileges on all the Ansible-managed hosts.

 

Key Ansible Features

  • Easy-to-Read Syntax: Ansible uses the YAML file format and Jinja2 templating. Jinja2 is the template engine for the Python programming language. Ansible uses Jinja2 templating to access variables and facts and extends the defaults of Ansible for more advanced use cases.

 

  • Not a full programming language: Remember that Ansible is not a full-fledged programming language, but it has several good features. One of the most important of these is variable substitution or using the values of variables in strings or other variables. In addition, the variables in Ansible make the Ansible playbooks, which are like executable documents, very flexible. Variables are a powerful construct within Ansible and can be used in various ways. Nearly every single thing done in Ansible can include a variable reference. We also have dynamic variables known as facts.

 

  • Jinja2 templating language: The defaults of Ansible are extended by the use of Jinja2 templating language. In addition, Ansible’s use of Jinja2 templating adds more advanced use cases to Ansible. And one great benefit is that it is self-documenting, so when someone looks at your playbook, it’s easy to understand, unlike a Python code or a Bash script. So not only is Ansible easy to understand, but with just a few lines of YAML, which is the language used for Ansible, you can install, let’s say, web servers on as many hosts as you like.

 

  • Ansible Architecture: Scalability: Ansible can scale. For example, Ansible uses advanced features such as SSH multiplexing to optimize SSH performance. Some use cases manage thousands of nodes with Ansible from a single machine.

 

  • SSH Connection: Parallel connections: We have three managed hosts, web1, web2, and web3. Ansible will make SSH connections parallel to web1, web2, and web3. It will then execute the first task on the list on all three hosts simultaneously. In this example, the first task is installing the Nginx package, so the task in the playbook would look like this. Except for Windows hosts, Ansible uses the SSH protocol to communicate with hosts. This SSH service is normally integrated with the operating system authentication stack, enabling you to take advantage of things such as Kerberos to improve authentication security. Ansible uses the same authentication methods that you will already be familiar with. SSH keys are normally the easiest way to proceed as they remove the need for users to input the authentication password every time a playbook is run.

 

Ansible Connectivity

Diagram: Ansible Connectivity

 

A Key Point: Optimizing SSH 

Ansible uses SSH to manage hosts, and establishing an ssh connection takes time. However, you can optimize SSH with several features. Because the SSH protocol runs on top of the TCP protocol, when you make a connection to a remote host with SSH, you need to make a new TCP connection. You don’t want to open a new SSH connection for every activity. Here you can use Control Master, which allows multiple simultaneous SSH connections with a remote host using one network connection. Control Persists, also known as multiplexing, keeps a connection option for xx seconds. The pipeline allows more commands to use simultaneous SSH connections. If you recall how Ansible executes a task?

    1. It generates a Python script based on the module being invoked
    2. It then copies the python script to the host
    3. Finally, it executes the python script

The pipelining optimization will execute the Python scripts by piping it to the SSH sessions instead of copying git. Here we are using one SSH session instead of two. These options can be configured in Ansible.cfg, and we use the SSH_connecton section. Then you can specify how these connections are used.  

 

  • A Note on Scalability: Ansible and Modularity

Ansible scales down well because simple tasks are easy to implement and understand in playbooks. Ansible scales well because it provides mechanisms for decomposing complex jobs into smaller pieces. So we can bring the concept of modularity into playbooks as the playbook becomes more complex. I like using Tags for playbook developments that can save time and effect to test different parts of the playbook when you know certain parts are 100% working.

 

  • A Security Win! No Daemons and No Listening Agent.

Once Ansible is installed, it will not add a database, and there will be no daemons to start or keep running. You only need to install it on one machine (which could easily be a laptop), and it can manage an entire fleet of remote machines from that central point. No Ansible agent is listening on a port. Therefore, when you use Ansible, there is no extra attack surface for a bad actor to play with. This is a big win for security following one of the main security principles of reducing the attack surface. As soon as you run the ansible-playbook command, Ansible connects to the remote servers and carries out what you want it to do. By its defaults, Ansible is pretty streamlined out of the box, but you can enhance it by configuring the Ansible.cfg file, to be even more automated.

 

Ansible Inventory

Diagram: Ansible Inventory: Link to YouTube video.

 

Main Ansible Components

    • Ansible Inventory: Telling Ansible About Your Servers

The Ansible inventory is all about telling Ansible about your servers. Ansible can manage only the servers it explicitly knows about. Ansible comes with one default server of the local host, which is the control host. You provide Ansible with information about servers by specifying them in an inventory. We usually create a directory called “inventory” to hold this information. For example, a very simple inventory file might contain a list of hostnames. The Ansible Inventory is the system that a playbook runs against. It is a list of systems in your infrastructure that the automaton is executed against. 

    • Inventory Highlights

These are a collection of hosts that commonly have hosts but can comprise other components such as network devices, storage arrays, and other physical and virtual appliances. It also has useful information that can be used alongside our target using the execution. The Inventory can be simple as a text file or more dynamically where the Inventory is an executable where the data is sourced dynamically. This way, we can store data externally and be used during runtime. So we can have a dynamic inventory via Amazon Web Service or create our dynamic.

 

Example: AWS EC2 External Inventory Script  

If you use Amazon Web Services EC2, maintaining an inventory file might not be the best approach because hosts may come and go over time, be managed by external applications, or be affected by AWS autoscaling. For this reason, you can use the EC2 external inventory script. In addition, if your hosts run on Amazon EC2, then EC2 tracks information about your hosts for you. Ansible inventory is a flexible object; you can use multiple inventory sources simultaneously. When doing so, it is possible to mix dynamic and statically managed inventory sources in the same ansible run. Many are referring to this as an instant hybrid cloud.

 

Highlighting Ansible Modules

Then we have the Ansible modules, considered to be the main workhorse of Ansible. You use modules to perform various tasks such as installing a package, restarting a service, or copying a configuration file. Ansible modules cater to a wide range of system administration tasks. This list has the categories of the kinds of modules that you can use. There are over 3000 modules. So you may be thinking, who is looking after all of these modules? That’s where collections in the more recent versions of Ansible are doing.

Ansible Playbook

    • Extending Ansible Modules

The modules are the scripts ( that are written in Python) that come packages with Ansible and Perform some action on the managed host. Ansible has an extensive list of modules covering many areas such as networking, cloud computing, server config, containerized, and virtualization. In addition, there are many modules to support the automation requirements you have. If no modules exist, you can create a custom module with the extensive framework of Ansible. So each task is a one-to-one correlation with the module. So, for example, a template task will use the template module.

 

    • A Key point: Idempotency

Modules strive to be idempotent, allowing the module to be run repeatedly without having a negative impact. In Ansible, the input is in the form of command-line arguments to the module, and the output is delivered as JSON to STDOUT. Input is generally provided in the space-separated key=value syntax, and it’s up to the module to deconstruct these into usable data. Most of the Ansible modules are also idempotent. Idempotent means running an Ansible playbook multiple times against a server is safe. For example, if the deploy user does not exist, Ansible will create it. If it does exist, Ansible will not do anything. This is a big improvement over the shell script approach, where running the shell script a second time might have different and potentially unintended effects.

 

    • The Use of Ansible Ad Hoc Commands

For instance, if you wanted to power off all of your labs for the weekend, you could execute a quick one-liner in Ansible without writing a playbook. With an Ad Hoc command, we can be good for running one command on a host, and it uses the modules. They are used for checking configuring on the host and are also good for learning Ansible. Note that Ansible is the executable for ad hoc one-task executions, and ansible-playbook is the executable that will process playbooks to orchestrate multiple tasks. The opposable side of the puzzle is the playbook commands are used for more complex tasks and are better for use cases where the dependencies have to be managed. The playbook can take care of the entire application deployments and dependencies.

 

Ansible Plays 

  • Ansible playbooks

An Ansible Playbook can have multiple plays that can exist within an Ansible playbook that can execute on different managed assets. So an Ansible Play is all about “what am I automating.” And then, it connects to the hosts to perform the actions. Each playbook comprises one or more ‘plays’ in a list. The goal of a play is to map a group of hosts to some well-defined roles, represented by things Ansible calls tasks. At a basic level, a task is nothing more than a call to an Ansible module. By composing a playbook of multiple ‘plays’, it is possible to orchestrate multi-machine deployments, running certain steps on all machines in the web servers group. For example, certain steps on the database server group, then more commands back on the web servers group, etc.

 

  • Ansible Tasks

Once a playbook is parsed and the hosts are determined, Ansible is ready to execute a task. Tasks include a name, a module reference, module arguments, and task control directives. Task execution By default, Ansible executes each task in order, one at a time, against all machines matched by the host pattern. Each task executes a module with specific arguments. You can also use the “–start-at-task <task name> flag to tell Ansible playbook to start a playbook in the middle of a task.

 

  • Task Execution

Each play contains a list of tasks. Tasks are executed in order, one at a time, against all machines matched by the host pattern before moving on to the next task. It is important to understand that, within a play, all hosts will get the same task directives. This is because the purpose of a play is to map a selection of hosts to tasks.  

Comments are closed.