Ansible: The Automator's Delight
Because Manual Configuration is for Losers
Developers were loving the awesomeness of tools like GitHub, while sys admins were stuck in a nightmare of manual tasks. Hosting applications on different servers is a huge job, but maintaining them is even tougher. In today's fast-paced world, applications need to be hosted on numerous servers for reliability.
The sys admins are responsible for managing these apps and the underlying environments. They have to do tasks like updating app versions, installing programming languages, and updating Docker versions. On top of that, they have to deal with repetitive tasks like OS updates, backups, and system reboots. It's like a never-ending cycle of logging into each server and carrying out these tasks one by one, which is both time-consuming and prone to errors.
๐ ฐ for... Ansible
We were desperately in need of a magic tool that could swoop in and make all our worries disappear. Thankfully, Michael DeHaan, a systems administrator at a small company in the Netherlands, came up with a brilliant solution called Ansible.
Ansible is a tool that automates all those tedious IT tasks. But guess what? Ansible got so popular that Red Hat snatched it up and made it open source. So now, it's not just any tool, it's an open-source infrastructure automation tool!
Believe it or not, Ansible is like the superhero of both provisioning and configuration management. It's a total game-changer!
Agentless and Declarative ๐ต๏ธโโ๏ธ
Ansible is agentless compared to other CM tools like Chef and Puppet because it doesn't require any agents to be installed, making it super easy to set up. You don't have to worry about managing agents on different servers, which saves a ton of time and deployment or upgrade effort. With Ansible, you only need to set it up on the control machine.
The magic behind Ansible is the use of modules, these little programs that do the actual tasks. All you have to do is push these modules from the control machine to the target machines, they do their thing, and then they're gone.
Ansible Playbooks ๐
Just like Shakespeare, sys admins have the fun task of writing playbooks to gracefully carry out all those repetitive IT tasks in a clever and automated manner. We use a single YAML file called Playbook to handle the installation, configuration, and deployment process.
The Playbook is fantastic because it can be version controlled and reused. Ansible playbooks are so versatile that they can configure any operating system, whether it's a physical server or a cloud-based one. Inside the Playbook, you'll find plays, which are like the acts in a play. Each play specifies how, in what order, and what should happen on the target machines.
But how does Ansible figure out which machines to work its magic on?
Well, all the machine information is stored in the inventory
file. This file holds the IP addresses or DNS hostnames of the servers we want to target. It's like a secret list of all the machines waiting for their turn to be configured.
Reduce, Reuse, and Recycle ๐
Ansible playbooks have the added benefit of reusability. Ansible playbooks allow reproducing applications across any environment like Docker containers, vagrant containers, cloud instances, and bare metal servers
Idempotent nature of Ansible
When you run this playbook, Ansible will save the state of what tasks it has already done on the machines. So, the next time you run the same playbook, it won't waste time redoing those tasks. But here's the fun part - even if you make a tiny tweak to the playbook, Ansible will only focus on executing that specific change instead of doing the whole playbook all over again.
Hands-on, please... ๐ป
We will try a simple scenario to understand the Ansible workflow and realize its true power.
In our mini setup, we will have four virtual servers - three for deploying web applications and one for database deployment. We will use another virtual server called the "control" machine that will handle the configuration management for all these target servers.
Note*: We will not deploy an actual website or database, but rather have dummy virtual machines to understand the workflow.*
Prerequisites
AWS account and knowledge of EC2 instances
One Ubuntu instance with Ansible installed
Two CentOS and one Ubuntu instance used for web deployment
One CentOS instance for database deployment
The EC2 instances would be set up like this...
Steps for the workflow
The aim is to manage and execute simple tasks on all the target servers using the control machine that has Ansible installed.
Step 1:
Create a directory that will store the inventory and playbook files. This directory will also store the .pem
file from AWS. Ansible will use this key file for logging into the target machines.
Add another directory into it that stores the index.html file that will be deployed on the web servers.
Step 2:
Let's understand the inventory
file...
all:
hosts:
web01:
ansible_host: 172.31.81.92
web02:
ansible_host: 172.31.94.211
db01:
ansible_host: 172.31.81.236
children:
webservers:
hosts:
web01:
web02:
dbservers:
hosts:
db01:
vars:
ansible_user: ec2-user
ansible_ssh_private_key_file: client-key.pem
The
all
section defines the top-level hosts, which areweb01
,web02
,web03
, anddb01
.The
children
section defines two groups of hosts:webservers
anddbservers
. Thewebservers
group includesweb01
,web02
, andweb03
, while thedbservers
group only includesdb01
.The
vars
section defines two variables:ansible_user
andansible_ssh_private_key_file
. Theansible_user
variable specifies the user that Ansible will use when connecting to hosts in thedbservers
group. Theansible_ssh_private_key_file
variable specifies the path to the SSH private key that Ansible will use when connecting to hosts in thedbservers
group.
Step 3:
Let's understand the web-db.yaml
playbook
---
- name: Webserver Setup
hosts: webservers
become: yes
tasks:
- name: Install httpd
ansible.builtin.yum:
name: httpd
state: present
- name: Start service
ansible.builtin.service:
name: httpd
state: started
enabled: yes
- name: Copy index file
copy:
src: files/index.html
dest: /var/www/html/index.html
backup: yes
- name: DBserver setup
hosts: dbservers
become: yes
tasks:
- name: Install mariadb-server
ansible.builtin.yum:
name: mariadb-server
state: present
- name: Install pymysql
ansible.builtin.yum:
name: python3-PyMySQL
state: present
- name: Start mariadb service
ansible.builtin.service:
name: mariadb
state: started
enabled: yes
The playbook defines two tasks:
Webserver Setup
Install the httpd package.
Start the httpd service.
Copy the index.html file to the /var/www/html directory.
DBserver setup
Install the mariadb-server package.
Install the python3-PyMySQL package.
Start the mariadb service.
The playbook targets two groups of hosts:
webservers
dbservers
The become
keyword tells Ansible to run the playbook with root privileges on the target hosts.
The backup: yes
option tells Ansible to create a backup of the index.html file before copying it to the /var/www/html directory.
Step 4:
Let's execute this command and check the output
ansible-playbook web-db.yaml -i inventory
For the webservers, we deployed a dummy index.html
file to the var/www/html
directory so that we could check it from the browser
The content of the text file is...
Now, let's check the public IP of the web-01
or web-02
webservers target machine on the browser
For the dbservers, the playbook installed the maria-db
server and started the maria-db
service.
Check this repository to understand how these tasks were carried out before Ansible by using Linux shell scripts.
Conclusion
So there you have it, folks! We've taken a wild ride through the world of Ansible and hopefully, you're feeling as jazzed up about it as I am. From its ridiculously cool automation powers to its ability to turn you into a virtual superhero, Ansible is the tool you never knew you needed (but totally do). Trust me, once you get a taste of its awesomeness, you'll wonder how you ever managed without it.
So go forth, my friends, and conquer the world of automation with Ansible by your side. Happy coding, and may the playbooks be ever in your favor!