In any IT infrastructure, servers will built for different purposes. They often have some things in common, yet their purpose will differ from other hosts in the environment. So far, everything we’ve done treats all hosts identically. That is, whatever we install, remove or change on one host, we do on all hosts. For an effective automation solution, we need to be able to target certain changes to hosts that require those changes, but not to other hosts.
Consider the following environment (the model of our infrastructure for this tutorial):
- We have one web server that will run Nginx on Rocky Linux.
- We have one database server that will run MariaDB also on Rocky Linux.
- We have one file server that will provide access to Windows machines via Samba running on Ubuntu.
To accomplish this, we’ll update our inventory file splitting the hosts into different groups:
192.168.5.250
[db_servers]
192.168.5.251
[file_servers]
192.168.6.30
With that out of the way, we can make updates to our playbook that will use the group names in square brackets above to tell Ansible to only commit the actions to servers under the respective group name. We’ll discuss different plays individually.
become: true
pre_tasks:
- name: Install Updates - Rocky
dnf:
update_only: true
update_cache: true
when: ansible_distribution == "Rocky"
Here, we see continued use of 'hosts: all.' It is common to standardize on a single operating system, then deploy different services to different hosts, which use that same operating system. In that respect, we are introducing 'levels' or 'hierarchies' of configuration. At one level (the operating system) we can do the same thing to all servers whether they are Rocky or Ubuntu. In the case above, we are updating the repository cache (update_cache: true) and updating all packages where the operating system is Rocky. We do the same for Ubuntu, using its specific commands:
apt:
upgrade: dist
update_cache: true
when: ansible_distribution == "Ubuntu"
Now we want to perform actions that are specific to the role of the servers (web, database, or file servers). We do that by changing the "all" above to the group name we used in the inventory file. Here’s the first play that will target only servers in the web_servers group:
- hosts: web_servers
become: true
tasks:
- name: Install Nginx Web Service - Rocky
dnf:
name:
- nginx
- pcp-pmda-nginx
state: latest
We began a new hosts section and provided the group name, web_servers. The remainder is unchanged from prior tutorials. When this cookbook is run, it will update all servers’ OS packages, but will install Nginx only on the server in the web_servers group. Now, since we know the only web server in our environment is a Rocky Linux host, we no longer require the 'when' directive, so that has been removed.
Here are the updates that target database and file servers, with nothing notably different from the prior example:
become: true
tasks:
- name: Install MariaDB - Database Servers
dnf:
name: mariadb
state: latest
- hosts: file_servers
become: true
tasks:
- name: Install Samba - File Servers
package:
name: samba
state: latest
That wraps up this section, but a few final notes:
You can add additional groups, as well as additional servers underneath each group. The key to remember is that the plays that are constrained by the group name following the hosts directive and will only be applied to the hosts in that group.
You’ll notice that in the first code example above, we swapped the 'tasks' directive with “pre_tasks.” This will be used later.
No comments:
Post a Comment