Software applications, once developed locally, need to be made available for public use. In order for this to happen, they need to be deployed to a server. This server, which maybe physical or a cloud server, needs to be provisioned for your application. Ansible is used to configures a server for your use. If you are running a python web application for example, the server needs to have python installed, similar to how you would install python on your local computer (read server). Of course, for a web application to run successfully in production, it needs far more than just Python. You need to deploy your code and supporting libraries, configure the server to listen securely for incoming requests to your application and balance these calls and more. What is worse, often more than one application is deployed on one server and one application is deployed to multiple server. Provisioning these servers for your applications manually is as painful as it sounds. This is where Ansible comes in.
Ansible, is a python based, open source, IT automation framework. Ansible enables you to provision your server via reusable and maintainable playbooks as well as providing a rich ecosystem to minimize the effort required for developing said playbooks . An Ansible playbook is a recipe of steps to be executed on a server. I will delve deeper into these playbooks in the next section. These playbook are at the core of the Ansible framework. Just as a web framework enables you to focus on your domain logic, Ansible enables you to focus on your specific server configurartions
The Ansible Framework
Ansible works with a control node and managed nodes. There is only one control node. This node is responsible for provisioning all your other nodes. The control node is your command center, managing all other nodes. These other nodes, you guessed it, are the managed nodes. You may have only one or multiple managed nodes. For our purposes, you can think of each node as a server. To keep track of these managed nodes, Ansible uses a host file, known as the Inventory. The control node, provisions your managed nods as found in the inventory based on your playbooks.
An Ansible playbook is a set of tasks Tasks. These playbooks come together to create a Role. Multiple roles typically come together to provision a managed node.
tasks, playbooks and roles
A task, is a command to executed on a node. An Ansible task can install a software, pull your code from git or any other command you would typically run on your server. A task is compromised of a name as well as the relevant command.
- name: Copy file copy: src: /src/myfiles/foo.conf dest: /etc/foo.conf
The task above, named Copy file, copies foo.conf from your control node’s src directory into the managed node’s etc directory.
An Ansible task then, is the atom your Ansible project. Put together, a number of tasks compromise a playbook. A playbook should hold all similar tasks. All the files you need to move into a server for example, should be handled in an appropriately named playbook as a set of tasks.
Finally, a set of playbooks form a role. A role is a set of playbooks you want to group together for whatever reason. All the playbooks required to provision a node for your python app for example, could come together to form a role named after your app.
roles/ Myapp/ # this hierarchy represents a "role" playbooks/ filestuff.yml # this hierarchy represents a “playbook”, “tasks” are found inside this playbook. pythonstuff.yml secuitystuff.yml ...
Templates and Variables
As more and more responsibilities are given to your control node, in form of more applications or bigger application, you may need to parametrize your tasks. Ansible has a concept of templates and variables. Templates are used at a role level, helping avoid duplicity in the playbooks for the role. Once this variable is set in the appropriate template, your playbook can refer to it by its given name. As with any variable, the template avoids duplicity as well as provide ease of change.
roles/ Myapp/ # this hierarchy represents a "role" playbooks/ filestuff.yml # this hierarchy represents a “playbook”, “tasks” are found inside this playbook. pythonstuff.yml secuitystuff.yml ... templates/ # <-- files for use with the template resource pythonstuff.conf.j2 # <------- templates end in .j2
Certain variables are relevant for all your managed nodes. For example, the name of your organization or an external partner’s API stay consistent on all your servers. These variables are commonly called group_vars. This name is due to the fact that you can speficy a group for an Ansible task which would then correspond to a group variable. These groupings go beyond a specific role and are scoped across all your nods.
group_vars/ group1.yml # here we assign variables to particular groups roles/ Myapp/ # this hierarchy represents a "role" playbooks/ filestuff.yml # this hierarchy represents a “playbook”, “tasks” are found inside this playbook. pythonstuff.yml secuitystuff.yml ... templates/ # <-- files for use with the template resource pythonstuff.conf.j2 # <------- templates end in .j2
The Ansible Modules
Ansible playbooks and templates provide reusability and maintainability for your configurations. The modules provide the functionality. At the core of an Ansible playbook is a task, each task is compromised of a command. Above we saw an example of these commands in “COPY”. As you have may have already noticed, nothing in your tasks defines what a COPY is or what it does. COPY, as well as hundreds of other commands, are part of Ansible modules. Ansible modules are classified into more than a dozen categories, amongst which are cloud, system, database and storage to name a few. These module for example includes commands such as :
- ec2_snapshot (for AWS) - digitalocean (for digital ocean) - docker-compose (for composing containers) - timezone (setting system timezone) and many more.
Listed in each of these modules are dozens of commands, where each is used like a function taking in different parameters and performing different functions. If there’s something you need to do, chances are, there is already an Ansible task for it. Taking
COPY again as an example, the parameters include.
- src -> a path string - dest -> a path string Which are required as well as other parameters such as - owner -> a string - group -> a string - mode -> a string of permissions either in numbers or letters as typically done with chmod.
All together, there are thousands of these module commands, No matter what it is that you’re doing, chances are, Ansible already has a task for your use. To become proficient with Ansible, you need to become familiar and comfortable with using these tasks. Ansible does allow users to create their own modules and expand on the existing list of commands, However, if you find yourself relying on custom modules and commands, chances are you are not using Ansible correctly.