 [](https://www.linkedin.com/in/nirgeier/) [](mailto:nirgeier@gmail.com) [](mailto:nirg@codewizard.co.il)
this project Roles¶
What are Ansible roles?¶
- Roles let you automatically load related vars, files, tasks, handlers, and other Ansible artifacts based on a known file structure.
- After you group your content into roles, you can easily reuse them and share them with other users.
- By default, Ansible will look in each directory within a role for file names
main/main.yml/main.yaml.
Ansible roles file structure¶
| Files | Description |
|---|---|
| tasks | the main list of tasks that the role executes. |
| handlers | handlers, which may be used within or outside this role. |
| library | modules, which may be used within this role (see Embedding modules and plugins in roles for more information). |
| defaults | default variables for the role (see Using Variables for more information). These variables have the lowest priority of any variables available and can be easily overridden by any other variable, including inventory variables. |
| vars | other variables for the role (see Using Variables for more information). |
| files | files that the role deploys. |
| templates | templates that the role deploys. |
| meta | metadata for the role, including role dependencies and optional Galaxy metadata such as platforms supported. |
Building Ansible role¶
- In this demo we will create a role for deploying a nodeJS app
- The app will be deployed from a pre-defined code.
- Each server will be deployed with its own configuration (values)
- We will also deploy some other files for learning purposes
01. Initialize file structure¶
# Lets create the roles file structure
ansible-galaxy init codewizard_lab_role
# The file system of the role will look like

02. Create the role content¶
02.01. Create the defaults/main.yml¶
---
### defaults/main.yml
###
### This file contain the variables for the Demo lab
###
# Defaults file for codewizard_lab_role
motd_message: "Welcome to Ansible Roles Lab"
### The package we wish to install on the servers
apt_packages:
- python3
- nodejs
- npm
# Packages to verify that they were installed
apt_packages_verify:
- python3
- npm
package_state: latest
02.02. Create the templates¶
### templates/motd.j2
_____ _ _ _ _ _
/ __ \ | | | | | |(_) | |
| / \/ ___ __| | ___ | | | | _ ____ __ _ _ __ __| |
| | / _ \ / _` | / _ \ | |/\| || ||_ // _` || '__|/ _` |
| \__/\| (_) || (_| || __/ \ /\ /| | / /| (_| || | | (_| |
\____/ \___/ \__,_| \___| \/ \/ |_|/___|\__,_||_| \__,_|
{{ motd_message }}
System information:
-------------------
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
Hostname: {{ inventory_hostname }}
{{ custom_message | default('') }}
### templates/node-server.j2
const
// Set the server port which will be listening to
// Those 2 values are passed from the env file
SERVER_PORT = 5000,
SERVER_NAME = "{{ inventory_hostname }}";
// Create the basic http server
require('http')
.createServer((request, response) => {
// Send reply to user
response.end(`<h1>Hello from ${SERVER_NAME}.</h1>`);
}).listen(SERVER_PORT, () => {
// Notify users that the server is up and running
console.log(`${SERVER_NAME} is up.
Please click or point your browser to:
http://localhost:${SERVER_PORT}`);
});
02.03. Create the tasks for the role¶
- In this example we will have multiple tasks for learning purposes
- We will need to create the tasks for each role
- Once the task are ready we can define them in the main task file
### tasks/pre-requirements.yaml
---
- name: Install Packages
ansible.builtin.apt:
name: "{{ item }}"
state: "{{ package_state }}"
# Loop over the required packages to install
with_items: "{{ apt_packages }}"
- name: Verify Packages Installation
ansible.builtin.command: "{{ item }} --version"
register: packages_version
with_items: "{{ apt_packages_verify }}"
- name: Print package version
ansible.builtin.debug:
msg: "{{ item.stdout_lines }}"
with_items: "{{ packages_version.results }}"
### tasks/node-server.yaml
---
- name: Copy Node server
ansible.builtin.template:
src: templates/node-server.j2
dest: /node-server.js
mode: 600
become: true
become_method: ansible.builtin.su
- name: Install "pm2" node.js package.
community.general.npm:
name: "pm2"
global: true
become: true
become_method: ansible.builtin.su
- name: Get running node processes
shell: "ps -ef | grep -v grep | grep -w node | awk '{print $2}'"
register: running_processes
- name: Kill running node server (if any)
shell: "kill {{ item }}"
with_items: "{{ running_processes.stdout_lines }}"
- name: Wait for the process to die
wait_for:
path: "/proc/{{ item }}/status"
state: absent
with_items: "{{ running_processes.stdout_lines }}"
ignore_errors: true
register: killed_processes
- name: Force kill stuck processes
shell: "kill -9 {{ item }}"
with_items: "{{ killed_processes.results | select('failed') | map(attribute='item') | list }}"
- name: Start Node server
ansible.builtin.command:
chdir: /
cmd: "pm2 start -f /node-server.js"
register: server_status
changed_when: server_status.rc != 0
- name: Print server status
ansible.builtin.debug:
msg: "{{ server_status.stdout_lines }}"
when: server_status.rc == 0
- name: Check server
uri:
url: http://localhost:5000
method: GET
status_code: 200
register: server_status
- name: Print server status
ansible.builtin.debug:
msg: "{{ server_status.status }} - {{ server_status.msg }}"
```
```yaml
### tasks/motd.j2
---
- name: Copy template
ansible.builtin.template:
src: templates/motd.j2
dest: /etc/motd
mode: preserve
become: true
become_method: ansible.builtin.su
```
```yaml
### tasks/main.yml
---
- name: Include Pre-Requirements task
ansible.builtin.include_tasks:
file: pre-requirements.yaml
- name: Include motd task
ansible.builtin.include_tasks:
file: motd.yaml
- name: Deploy node server
ansible.builtin.include_tasks:
file: node-server.yaml
```
#### 02.04. Create the playbook for the role
```yaml
### 009-role-playbook.yml
---
###
### The playbook for using our role
###
- name: Executing codewizard_lab_role
hosts: all
become: true
become_method: ansible.builtin.su
roles:
- codewizard_lab_role
:arrow_backward: /Labs/008-challenges Back to labs list /Labs/010-loops-and-conditionals :arrow_forward: