Stepping outside of my configuration management comfort zone and will be using Ansible in my lab!
Ansible is a python based configuration management tool similar to Salt, Puppet, and Chef. It utilizes SSH to interact with the hosts it controls. With that said, controlled hosts or targets will need to have SSH enabled and a specific user for Ansible to utilize.
For this tutorial, I will be using a CentOS 8 virtual machine as the Ansible server and Debian 10 as the target.
The ansible server will also be referred to as the control node.
---------------------------------
| Ansible server | 192.168.1.18 |
---------------------------------
| Target | 192.168.1.19 |
---------------------------------
Setting up
I'll be creating the ansible user and will give it sudo rights on both the ansible server and target.
- Creating the ansible user
adduser ansibleadmin
2. Give ansible user sudo rights
usermod -aG sudo ansibleadmin
3. Create SSH keys
Ansible uses SSH to connect to the controlled instances, but it's not feasible to supply the password to each hosts when executing a playbook. To handle authentication, I'll create SSH key pair (private and public).
ssh-keygen -t rsa -b 4096
Do not put a password on the key.
4. Copy the public key to the target hosts
ssh-copy-id ansibleadmin@192.168.1.19
5. Verify access
If you added the key correctly, you should be automatically connected to the target.
ssh ansibleadmin@192.168.1.18
Installing Ansible
- Install Python3
dnf install python3 -y
2. Install ansible
dnf install ansible -y
3. Verify if ansible installed properly
Execute the command below:
ansible --version
Configuring the Ansible Control Node
- Edit the ansible hosts file and add your hosts. I'll be managing the control node and target using ansible.
vim /etc/ansible/hosts
[control]
192.168.1.18
[targets]
192.168.1.19
2. Verify ansible can access the hosts
After you're done adding the IP addresses of the control node and target, I'll verify ansible can reach them.
ansible -m ping all
You should get an output like this:
192.168.1.18 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.19 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Creating a Playbook
- Create a directory specifically for the playbooks
mkdir /etc/ansible/playbooks
2. Create an empty file for a playbook
This empty file will be the playbook that will install mysql on the target
touch /etc/ansible/playbooks/mysql.yml
3. Writing the mysql playbook
vim /etc/ansible/playbooks/mysql.yml
After opening mysql.yml
, write the following:
---
- hosts: target
become: true
tasks:
- name: Installing MySQL
dnf:
name: mysql-server
state: latest
update_cache: yes
- name: Starting MySQL server
service:
name: mysqld
state: started
enabled: yes
hosts
= Which hosts ansible should target, in this case hosts under the target
section in the ansible hosts file will be used.
become
= Allows ansible to use the sudo command.
tasks
= The actions ansible should take on the targets hosts.
- name
= The name of the task.
dnf
= Is the built it module ansible will use. In the example ansible will use dnf to download packages.
state
= The version of the package, in this case it will be the latest version.
update_cache
= Will execute dnf update
.
service
= Is another module within ansible that can interact with services on the target system. This will start a service on the target host.
enabled
= Enables the service to always start after a reboot.
Executing the Playbook
- Execute syntax check
Before executing the playbook for real, I'm going to do two checks. The first one will be the syntax check.
ansible-playbook --syntax-check mysql.yml
If there are no syntax errors, it will return the playbook's name, like below.
playbook: mysql.yml
If there is an error, it will tell you on which line and column your mistake is on.
2. Check what will be changed on the target
ansible-playbook --check mysql.yml
This command will go and connect to the host and look at the gathered facts and will generate a preview of what will be changed on the target.
3. Execute the playbook
Now that the checks have shown me what is going to happen, I'm satisfied to execute the playbook.
ansible-playbook mysql.yml
You will get an output similar to this:
PLAY [database] ***************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************
ok: [192.168.1.19]
TASK [Installing MySQL server] **************************************************************************************************************************************************************************
changed: [192.168.1.19]
TASK [Starting MySQL server] **************************************************************************************************************************************************************************
changed: [192.168.1.19]
PLAY RECAP ********************************************************************************************************************************************************************************************
192.168.1.18 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Conclusion
See ansible is quite simple isn't it? Well it's just the tip of the iceberg, now I can incorporate ansible into my CI/CD pipeline or use it to manage my infrastructure. Ansible makes it easy to control my fleet of virtual machines. As my infrastructure scales management becomes easier.