Learning Ansible
This assignment takes just about all the knowledge you have gained so far and combines it into a single assignment.
We need to create some infrastructure first. In the explanation below we’ll use Docker and docker-compose, but you can use any infrastructure you like. Eventually you’ll need 4 hosts, 2 webservers and 2 databaseservers:
(The hostnames can vary a bit, the hostnames you will be using should end up in the Ansible inventory.)
| Hostname | Group |
|---|---|
| node-1 | webservers |
| node-2 | webservers |
| node-3 | databaseservers |
| node-4 | databaseservers |
Feel free to use the infrastructure directory as a starting point.
All the assignments and examples will be based on this Docker setup.
Let’s first setup Ansible without too much Ansible code, just the inventory and it’s variable.
advanced_assignment.ansible.cfg file in this directory.ansible.cfg to use the inventory directory as inventory.inventory directory.hosts in the inventory directory.webservers in the inventory file.webservers group: node-1 and node-2, both using ansible_connection=docker.databaseservers in the inventory file.databaseservers group: node-3 and node-4, both using ansible_connection=local.production in the inventory file, add node-1 and node-3 to it.development in the inventory file, add node-2 and node-4 to it.group_vars.group_vars/all/ntp.yml in the group_vars directory.ntp_server variable to 0.pool.ntp.org for all hosts.Once the above steps are completed, run these commands to verify if all is working as expected:
ansible -m ping all
The value all used in the above command can be changed for:
webserversdatabaseserversproductiondevelopment| Group | Expected output |
|---|---|
all |
4 nodes: node-1, node-2, node-3 and node-4. |
webservers |
2 nodes: node-1 and node-2. |
databaseservers |
2 nodes: node-3 and node-4. |
production |
2 nodes: node-1 and node-3. |
development |
2 nodes: node-2 and node-4. |
Running this command:
ansible -m ansible.builtin.debug -a "msg=" all
Should return 0.pool.ntp.org for all nodes.
You should have assignment 1 ready before starting this assignment.
playbook.yml in the advanced_assignment directory.sudo, tcpdump, vim, wget.webservers group.webservers group.databaseservers group.databaseservers group.To prevent a high load, set the serial parameter to 50% in the playbook.
Once the above steps are completed, run these commands to verify if all is working as expected:
ansible-playbook playbook.yml
You should see:
As a bonus; try to keep your playbooks or roles idempotent.
We’re going to create a play for the NTP setup.
Note: The name
ntpis being used, but the package name, configuration file and service name change over different distributions.
| Distribution | Package name | Configuration file | Service name |
|---|---|---|---|
| Ubuntu | ntp |
/etc/ntp.conf |
ntp |
| CentOS | chrony |
/etc/chrony.conf |
chronyd |
playbook.yml for all nodes to install the package for NTP.webservers group to 0.ch.pool.ntp.org. Make sure to restart NTP on changes made to the configuration file.Some hints on the configuration file: You can login to the nodes and cat a default NTP configuration, and place a modified version in the templates directory of your role.
Run this Ansible command and check that nothing has changed.
Note, please remember that different names of the package, configuration file and service.
ansible -m lineinfile -a "path=/etc/chrony.conf line='pool 0.pool.ntp.org iburst'" all --check
Modify the playbook to:
index.html on the webservers.index.html read something like this: “Hello from MY_HOST_NAME.” (Where MY_HOST_NAME is the variable hostname of the node.)Run this command: curl http://localhost:80 and make sure “Hello from node-1.” is returned.
Run this command: curl http://localhost:81 and make sure “Hello from node-2.” is returned.
We’re going to play with error handling.
Append to the playbook, a task that:
random filter.When running the playbook a few times, you should see the play summary, where rescued is 1:
node-1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
node-2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node-3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node-4 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0