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 the directory which will hold it. As we want this directory to be managed by multiple users, we’ll use ACLs again to ensure read/write access to any member of the ansible
group.
Create Directory
Create the /opt/ansible
directory.
sudo mkdir /opt/ansible
Group Membership
Create a new group called ansible
.
sudo groupadd ansible
Add all user’s who will be using Ansible on the host.
sudo usermod -a -G ansible username
Configure 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/ansible
Rerun the command, now with the -d
flag (for default). This applies new default ACLs so all future sub-directories/files created within /opt/ansible
ahve the same permissions as our top-level directory.
sudo setfacl -d -m g:ansible:rwx /opt/ansible
Restart Shell
Restart the shell to see these changes take effect.
exec bash
Create 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 development
Structure Overview
Congrads, we now have a basic Ansible environment we can start filling out with hosts, variables and roles. Before moving on to the next step, let’s quickly go through and outline the purpose of each folder and how they work together in managing an environment.
Inventory File
The production
and development
files will be our inventory files. This is where we tell Ansible about the hosts we’d like managed and assign those hosts to various groups.
For example, here is an inventory file which lists three groups: linux_hosts
, web
and db
. Under these groups, we list our hosts, indicating that these hosts are members of said group.
As shown, you’re welcome to have hosts be apart 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 variaible 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 wouold 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 host’s name. Starting with web01.prod.twobyte.blog
, we would run the following command:
touch host_vars/web01.prod.twobyte.blog
Next 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 are for more advanced features of Ansible that are best learned later.
Roles
Lastly, we have our roles
directory. roles
are 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 should look 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/