Configure Environment
Ansible’s environment consists of a collection of files—including playbooks, plays, variables, and roles—all organized into a directory structure suitable for Ansible to work within.
Looking at Ansible’s documentation, two best practice layouts are recommended. Feel free to use what you prefer, but for this guide, we’ll be working with the first recommendation.
Here’s the structure we’ll be creating:
production # Inventory file for production environment.
development # Inventory file for staging environment.
group_vars/
group1.yml # For any variables we would like to assign to a group of hosts.
group2.yml
host_vars/
hostname1.yml # For any variables we would like to assign directly to a host.
hostname2.yml
library/ # For storing custom modules.
module_utils/ # For storing custom module_utils to support modules.
filter_plugins/ # For storing custom filters.
roles/ # For storing ansible roles.Directory Creation
Before setting up our environment, create a directory that will contain it. Since we want this directory to be managed by multiple users, we’ll use ACLs again to ensure read and write access for any member of the ansible group.
Create Directory
Create the /opt/ansible directory.
sudo mkdir /opt/ansibleGroup Membership
Create a new group called ansible.
sudo groupadd ansibleAdd all user’s who will be using Ansible on the host.
sudo usermod -a -G ansible usernameConfigure Permissions
Update the permissions so the ansible group will have read, write, and execute permissions on the /opt/ansible directory.
sudo setfacl -m g:ansible:rwx /opt/ansibleRerun the command, now with the -d flag (for default). This applies new default ACLs so all future sub-directories/files created within /opt/ansible have the same permissions as our top-level directory.
sudo setfacl -d -m g:ansible:rwx /opt/ansibleRestart Shell
Restart the shell to see these changes take effect.
exec bashCreate Environment
With our permissions configured, move under /opt/ansible and create our Ansible structure.
cd /opt/ansible
mkdir {group_vars,host_vars,library,module_utils,filter_plugins,roles}
touch production developmentStructure Overview
Congrats! We now have a basic Ansible environment that we can start filling out with hosts, variables, and roles. Before moving on to the next step, let’s quickly go over the purpose of each folder and how they work together to manage the environment.
Inventory File
The production and development files will serve as our inventory files. This is where we’ll tell Ansible about the hosts we’d like managed and assign those hosts to various groups.
For example, here’s an inventory file that lists three groups: linux_hosts, web, and db. Under these groups, we list our hosts, indicating that they are members of these corresponding group.
As seen, you’re welcome to have hosts be part of multiple groups.
|
|
The reason that we have both a production and development inventory file is to allow for testing before deployment. Typically both environments would match so testing could occur on our development environment and then, when confident, be deployed against our production environment.
Here’s an example where you can see identical setups but under different sub-domains to differentiate between the production and development environments.
|
|
|
|
Variable Files
Moving down a little we have two folders used for defining variables across our environment called group_vars and host_vars.
group_vars is for assigning variables against a collection or group of hosts. host_vars is its antithetical; when you want to assign a variable against a specific host.
Group Example
Continuing with the example above, say we want to apply a variable to all web servers. To do this, we would create file called web within group_vars (notice how the filename matches the group name). Inside we define a variable that applies to all members of this group, for example the apache version we want installed.
|
|
Host Example
Say instead we want to apply a hostname to each host using hostnamectl. To do this, we would create a file for each host under host_vars matching the hostname. Starting with web01.prod.twobyte.blog, we would run the following command:
touch host_vars/web01.prod.twobyte.blogNext within the host_vars/web01.prod.twobyte.blog file, we would specfy the host’s hostname as a variable.
|
|
All Hosts
What if we wanted to apply a setting to every host? Thats doable under a the special file group_vars/all.yaml. Any variable set within this file is applied to all hosts.
|
|
Modules & Plugins
For now ignore library,module_utils,filter_plugins as these relate to more advanced features of Ansible that are best learned later.
Roles
Lastly, we have our roles directory. roles is similar in idea to functions in programming. This is aruguble a larger topic best handled with a more indepth article.
Configuring Our Environment
Understanding the basics, lets start filling in all the details in our Ansible environment.
Inventory File
First lets add all of our Linux-based hosts so Ansible is aware of them. Open your production inventory file and create a group called linux_hosts. Underneath, list all of your Linux-based hosts.
|
|
Next, if applicable, do the same for Windows hosts.
|
|
In anticipation of needing to assign host-specific variables, lets create a file for each host under host_vars. We’ll fill in the details later.
# Linux Hosts
touch host_vars/web01.prod.twobyte.blog
touch host_vars/web02.prod.twobyte.blog
touch host_vars/db01.prod.twobyte.blog
# Windows Hosts
touch host_vars/dc01.ad.twobyte.blog
touch host_vars/fs01.ad.twobyte.blog
...Congraduations, you now have a basic folder/file structure for housing your Ansible plays, playbooks, roles, inventories etc.
Below is what your structure looks like after finishing this article.
production
development
group_vars/
linux_hosts.yml
windows_hosts.yml
host_vars/
web01.prod.twobyte.blog
web02.prod.twobyte.blog
db01.prod.twobyte.blog
library/
module_utils/
filter_plugins/
roles/