Table of Contents
In this article we will create ansible role from scratch using ansible galaxy init. In our earlier article I gave you an overview on ansible role directory structure. Now we will use that directory structure to deploy a playbook with some ansible roles example.
Let us go step by step in this ansible roles tutorial to create ansible playbook roles from scratch. I will share two ansible role examples in this article
- Update
/etc/motd
using ansible playbook roles - Configure virtual hosting for apache server using ansible playbook roles
Ansible will by default look for roles in the following directories
- Current project directory
~/.ansible/roles
/etc/ansible/roles
/usr/share/ansible/roles
Install Ansible and set up the environment
Since I have already installed and configured Ansible on my CentOS 8 environment, I will not repeat the same here.
Create project
Once we have our Ansible environment ready, next create a project. I will create a new project base
to demonstrate ansible roles example:
[ansible@controller ~]$ mkdir base
Example 1: Ansible roles example to update /etc/motd
Step 1: Create ansible role - motd
- To create ansible role, use
ansible-galaxy init <role_name>
to create the role directory structure. - We will create the role inside our
<project>/roles
directory i.e.~/base/roles/motd
- Don't put sensitive information in the role, but in the local playbooks or Ansible Vault instead
[ansible@controller ~]$ mkdir roles [ansible@controller ~]$ cd roles
Next use ansible-galaxy init
command to create ansible role. We will create motd
role:
[ansible@controller roles]$ ansible-galaxy init motd - motd was created successfully
Create ansible role command was successful. You can use tree command to list the ansible role directory structure for motd
:
[ansible@controller roles]$ tree motd
motd
├── defaults
│  └── main.yml
├── files
├── handlers
│  └── main.yml
├── meta
│  └── main.yml
├── README.md
├── tasks
│  └── main.yml
├── templates
├── tests
│  ├── inventory
│  └── test.yml
└── vars
└── main.yml
8 directories, 8 files
As you see all the directories which we discussed in our last article for ansible role are created
Step 2: Create ansible tasks
Now we know we want to update /etc/motd
file using ansible playbook roles so we must create tasks so we will use the main.yml
file present inside tasks
folder
[ansible@controller motd]$ cat tasks/main.yml --- # tasks file for motd - name: copy motd file template: src: templates/motd.j2 dest: /etc/motd owner: root group: root mode: 0444
We have defined the template path and destination detail to update /etc/motd
Step 3: Create ansible template
Next we will create the template content which will be used to update /etc/motd
in our ansible roles examples. I will create a new template file under templates
directory using some variables:
[ansible@controller motd]$ cat templates/motd.j2 Welcome to {{ ansible_hostname }} This file was created on {{ ansible_date_time.date }} Go away if you have no business being here Contact {{ system_manager }} if anything is wrong
Step 4: Create ansible variables
We will use defaults
folder to define custom variables which is used in our template file templates/motd.j2
.
[ansible@controller motd]$ cat defaults/main.yml
---
# defaults file for motd
system_manager: admin@golinuxcloud.com
Step 5 : Remove unwanted directories (Optional)
This step is completely optional. In this ansible roles example we will not use other directories so we are deleting them. After deleting the additional directories you can use tree
command to list the directory structure of motd
roles
[ansible@controller motd]$ rm -rf handlers tests vars [ansible@controller motd]$ tree . ├── defaults │  └── main.yml ├── files ├── meta │  └── main.yml ├── README.md ├── tasks │  └── main.yml └── templates └── motd.j2 5 directories, 5 files
Step 6: Create ansible role playbook
Now after you create ansible role structure, we need a playbook file which will deploy the role to our managed hosts. I will create my playbook file motd-role.yml
under base
project directory.
[ansible@controller base]$ cat motd-role.yml --- - name: use motd role playbook hosts: server1.example.com user: ansible become: true roles: - role: motd system_manager: admin@golinuxcloud.com
As you see I have only provided the roles
information and no other tasks are specified in the playbook file.
Step 7: Deploy ansible playbook roles
After we create ansible role from scratch and playbook file, we will next deploy our ansible playbook roles to execute the motd
role on our managed host.
[ansible@controller base]$ ansible-playbook motd-role.yml PLAY [use motd role playbook] *********************************************************************************** TASK [Gathering Facts] ****************************************************************************************** ok: [server1.example.com] TASK [motd : copy motd file] ************************************************************************************ changed: [server1.example.com] PLAY RECAP ****************************************************************************************************** server1.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
In the ansible roles example our ansible deployment was successful.
Step 8: Verification
After ansible playbook deployment, verify the task status on your managed host which for us is server1.example.com
[root@server1 ~]# cat /etc/motd Welcome to server1 This file was created on 2020-02-01 Go away if you have no business being here Contact admin@golinuxcloud.com if anything is wrong
So the content from our motd
file is updated properly on server1
at /etc.motd
.
Example 2: Configure Virtual Hosting with Ansible Role
This is our second ansible roles example. This play will be operated on server2.example.com
and we are going to use "vhost
" role for the operation.
Step 1: Create Ansible Role - vhost
We will use our existing ~/base/roles/<rolename>
project to create ansible roles directory structure using "vhost
" role
[ansible@controller base]$ cd roles/
To create ansible role vhost
use ansible-galaxy init <rolename>
command as shown below:
[ansible@controller roles]$ ansible-galaxy init vhost - vhost was created successfully
You can use tree
command to check the structure of the vhost
directory:
[ansible@controller roles]$ tree . └── vhost ├── defaults │  └── main.yml ├── files ├── handlers │  └── main.yml ├── meta │  └── main.yml ├── README.md ├── tasks │  └── main.yml ├── templates ├── tests │  ├── inventory │  └── test.yml └── vars └── main.yml 9 directories, 8 files
Step 2: Create ansible tasks
- In the
main.yml
inside tasks folder we define the tasks to be performed - Install httpd using yum module
- Start and enable the httpd service using the service module
- Next source the
vhost.conf.j2
file to destination using template module available under templates directory
[ansible@controller base]$ cat roles/vhost/tasks/main.yml --- # tasks file for vhost - name: install http yum: name: httpd state: latest - name: start and enable httpd service: name: httpd state: started enabled: true - name: install vhost config file template: src: vhost.conf.j2 dest: /etc/httpd/conf.d/vhost.conf owner: root group: root mode: 0644
Step 3: Create ansible handlers
In roles we separate tasks
with ansible handlers. So in this ansible roles example in handlers/main.yml
we instruct ansible to restart httpd
once the tasks
are done
[ansible@controller base]$ cat roles/vhost/handlers/main.yml --- # handlers file for vhost - name: restart_httpd service: name: httpd state: restarted
Step 4: Create ansible template
Below is our virtual host configuration using variables under templates
folder. The variables will be auto filled on destination names.
[ansible@controller base]$ cat roles/vhost/templates/vhost.conf.j2 # {{ ansible_managed }} <VirtualHost *:80> ServerAdmin webmaster@{{ ansible_fqdn }} ServerName {{ ansible_fqdn }} ErrorLog logs/{{ ansible_hostname }}-error.log CustomLog logs/{{ansible_hostname }}-common.log common DocumentRoot /var/www/vhosts/{{ ansible_hostname }}/ <Directory /var/www/vhosts/{{ ansible_hostname }}> Options +Indexes +FollowSymlinks +Includes Order allow,deny Allow from all </Directory> </VirtualHost>
Step 5: Remove unwanted directories (Optional)
Now similar to our ansible roles example for motd
, we will remove our unwanted directories.
[ansible@controller vhost]$ rm -rf defaults files tests vars
Next you can use tree
command to list the remaining directories of vhost
role.
[ansible@controller vhost]$ tree
.
├── handlers
│  └── main.yml
├── meta
│  └── main.yml
├── README.md
├── tasks
│  └── main.yml
└── templates
4 directories, 4 files
Step 6: Create post execution tasks
Also we have added post_tasks
to copy index.html
from localhost
to destination on managed host (server2.example.com
) under /var/www/html/<hostname>/
So we will create an index.html
on the localhost
which we want to be copied to the destination with our playbook:
[ansible@controller base]$ mkdir -p files/html [ansible@controller base]$ echo "Welcome to this host" >> files/html/index.html [ansible@controller base]$ cat files/html/index.html Welcome to this host
Step 7: Create ansible role playbook
Now after you create ansible role structure, we need a playbook file which will deploy the role to our managed hosts. I will create apache-vhost.yml
playbook file under the base
project directory.
[ansible@controller base]$ cat apache-vhost.yml --- - name: create apache vhost hosts: server2.example.com ## Execute on this host only become: true ## Perform tasks as root user roles: - vhost post_tasks: - name: install contents from local file copy: src: files/html/ dest: "/var/www/vhosts/{{ ansible_hostname }}" changed_when: true ## This is to forcefully mark a change notify: restart_httpd ## Execute the handler with the name restart_httpd
Step 8: Deploy ansible playbook roles
After we create ansible role from scratch and playbook file, we will next deploy our ansible playbook roles to execute the vhost
role on our managed host.
[ansible@controller base]$ ansible-playbook apache-vhost.yml PLAY [create apache vhost] ************************************************************************************** TASK [Gathering Facts] ****************************************************************************************** ok: [server2.example.com] TASK [vhost : install http] ************************************************************************************* ok: [server2.example.com] TASK [vhost : start and enable httpd] *************************************************************************** ok: [server2.example.com] TASK [vhost : install vhost config file] ************************************************************************ changed: [server2.example.com] TASK [install contents from local file] ************************************************************************* changed: [server2.example.com] RUNNING HANDLER [vhost : restart_httpd] ************************************************************************* changed: [server2.example.com] PLAY RECAP ****************************************************************************************************** server2.example.com : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
So looks like our ansible playbook roles has successfully executed. We can verify the same by running ansible ad-hoc
commands
-include: <path/of/handler/main.yml>
to manually execute the file.
Step 9: Verification
To check if httpd
service is active on our managed host server2.example.com
[ansible@controller base]$ ansible server2.example.com -a 'systemctl is-active httpd' server2.example.com | CHANGED | rc=0 >> active
As we see the service active
, we can also check the output of vhost.conf
which we had populated. Execute the below command using the controller node
[ansible@controller base]$ ansible server2.example.com -a 'cat /etc/httpd/conf.d/vhost.conf'
server2.example.com | CHANGED | rc=0 >>
# Ansible managed
<VirtualHost *:80>
ServerAdmin webmaster@server2.example.com
ServerName server2.example.com
ErrorLog logs/server2-error.log
CustomLog logs/server2-common.log common
DocumentRoot /var/www/vhosts/server2/
<Directory /var/www/vhosts/server2>
Options +Indexes +FollowSymlinks +Includes
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
What’s Next
Next in our Ansible Tutorial we will learn about Ansible Vaults
References:
Red Hat Certified Engineer (RHCE) EX294: Red Hat Ansible Automation
yes, very simple and clear.
Thanks a lot it had really helped me to get a view on ansible roles easily
creation of vhosts directory on target not mentioned anywhere how will it create /var/www/vhosts
In your playbook there is no handler restart task was executed , I think you missed the notify after the copy, Please check once
Thank you for highlighting this, I may have overlooked the output. I have updated the article with additional NOTE
very simple and clear thank you.