lab05
inside ansible-labs
lab05
folderinventory
folder from lab04
to lab05
cp -r ../lab04/inventory ./inventory
A role is a way of organizing tasks, handlers, variables, and other files in a structured way.
When you create a role, you create a directory structure that contains the role’s tasks, handlers, and other files.
Let’s create a role named lab.usersandgroups
:
ansible-galaxy role init --init-path=./roles/ lab.usersandgroups
This command will create a directory structure for the role in the roles
folder.
Navigate to the roles/lab.usersandgroups
folder and check the files created.
You must see the following files and directories:
.
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
On next steps you’ll update the files and directories created.
Pay attention when pasting the content of the files, because the files have been initialized with some content that you’ll need to replace.
If you not replace that code, you’ll get errors when executing the playbook.
Update the README.md
file with the role description and usage with the content available on this README.md file.
Update the meta/main.yml
file with the role metadata with following content:
galaxy_info:
role_name: usersandgroups
author: Ansible Training
description: Manage users and groups on Linux/Unix systems
company: Ansible Training
min_ansible_version: "2.9"
license: MIT
# List of platforms you support and the versions, e.g., EL (Enterprise Linux) 7, 8, Ubuntu 18.04 (Bionic)
platforms:
- name: Rocky
versions:
- "8.0"
- "9.0"
- name: Ubuntu
versions:
- bionic
- focal
- name: Debian
versions:
- stretch
- buster
- bullseye
# List of categories this role falls into, from Galaxy's predefined list
galaxy_tags:
- system
- users
- groups
- management
# Dependencies are other roles that this role depends upon to function
dependencies: []
Edit the defaults/main.yml
file with the following content:
---
users_list:
- name: exampleuser
state: present
password: "examplepassword"
groups: ["examplegroup"]
shell: "/bin/bash"
createhome: yes
generate_ssh_key: true
default_folders:
- "Documents"
- "Downloads"
- "Music"
- "Pictures"
- "Videos"
# Default list of groups to manage
groups_list:
- name: examplegroup
state: present
# Path to keep the fetched SSH keys
destination_path_on_control_node: "/tmp"
Please go through the file and understand the variables defined.
These list are the parameters that you can use to manage users and groups.
Check the password hash generation using the password_hash
filter: examplepassword
.
This filter will generate the password hash for the user exampleuser
using the sha512
algorithm.
For now we’re setting this sensitive information in plain text, but in a real-world scenario you should use Ansible Vault to encrypt this information.
We’ll go through Ansible Vault in the next lab.
On this step, you’ll use the include_tasks
module to include the tasks from the users.yml
and groups.yml
file.
Let’s update the tasks/main.yml
file with the following content:
---
# Loop to create groups
- name: Create groups
include_tasks: groups.yml # include the tasks from the groups.yml file
loop: "" # loop over the groups_list variable
loop_control:
loop_var: group # change the loop variable name to group
# Loop to create users and subfolders
- name: Create user and subfolders
include_tasks: users.yml # include the tasks from the users.yml file
loop: "" # loop over the users_list variable
loop_control:
loop_var: user # change the loop variable name to user
Now, let’s create a users.yml
file inside the tasks
directory with the following content:
---
- name: Print user details
debug:
var: user
# Create users
- name: Ensure users are present or absent
ansible.builtin.user:
name: ""
state: ""
password: ""
groups: ""
shell: ""
createhome: ""
generate_ssh_key: ""
ssh_key_bits: 2048
ssh_key_file: ".ssh/id_rsa"
- name: Ensure home subfolders exist
ansible.builtin.file:
path: "/home//"
state: directory
owner: ""
group: ""
mode: '0755'
loop: ""
- name: Fetch private SSH key to control node
ansible.builtin.fetch:
src: "/home//.ssh/id_rsa"
dest: "/__id_rsa"
flat: yes
notify: reload sshd
On this file you created the following tasks:
user
variable, that was defined on the loop in the main.yml
file.Then, let’s create a groups.yml
file inside the tasks
directory with the following content:
---
- name: Ensure groups are present or absent
ansible.builtin.group:
name: ""
state: ""
This file is simpler than the users.yml
file, it only ensures that the groups are present or absent.
Now, let’s edit the handlers/main.yml
file with the following content:
---
# Optional: Reload SSH daemon if necessary
- name: Reload SSH daemon
ansible.builtin.service:
name: sshd
state: reloaded
listen: "reload sshd"
This handler show another way to use handlers, you can use the listen
directive to define a custom trigger for the handler instead of using the handler name.
The handler is notified by the fetch
task in the users.yml
file.
Since the handlers only run when notified by a task that results in a change, you only see this handler to run if the fetch
task copied a newer version of the SSH key to the control node.
Now it’s time for you to use the role in a playbook.
Create a playbook named playbook.yml
on folder lab05
.
This playbook will use the role lab.usersandgroups
to manage the users and groups.
The file should have the following content:
---
- name: Manage users and groups
hosts: db
become: true
roles:
- role: lab.usersandgroups
when: ansible_os_family == "RedHat"
vars:
users_list:
- name: adminuser
state: present
password: "password123"
groups: ["wheel"]
createhome: yes
generate_ssh_key: true
shell: "/bin/bash"
default_folders:
- "Documents"
- "Downloads"
- "Music"
- "Pictures"
- "Videos"
- name: devuser
state: present
password: "password123"
groups: ["wheel", "developers"]
createhome: yes
generate_ssh_key: true
shell: "/bin/bash"
default_folders:
- "Documents"
- "Downloads"
- "Work"
- name: testeruser
state: present
password: "password123"
groups: ["testers"]
createhome: yes
generate_ssh_key: true
shell: "/bin/bash"
default_folders:
- "Documents"
- "Downloads"
- "Tests"
groups_list:
- name: developers
state: present
- name: testers
state: present
On this playbook you use your role for creating 2 groups and 3 users.
Pay attention on the when
directive on the role definition, this is a conditional statement that will only run the role if the ansible_os_family
is RedHat
.
Run the playbook using the following command:
ansible-playbook -i inventory playbook.yml
Take some time to look at the output and understand what is happening.
Now execute the playbook again using the following command:
ansible-playbook -i inventory playbook.yml
Check the output and see if there’s any change.
In particular, check that the handler is not running again, because the SSH key was already fetched.
Since you didn’t change the destination_path_on_control_node
variable, the SSH keys were fetch for the folder /tmp
on the control node as defined as default on the defaults/main.yml
file.
Just confirm that you got the keys from each user, running the following command:
ls -l /tmp
If you want to make your role available on a Git repository, you can use the following steps:
lab.usersandgroups
role to the repository. The root dir of your repo should contain the folders of the role.Create a requirements.yml
file with the following content:
- src: <URL of your git repo>
version: main
name: lab.usersandgroups
lab.usersandgroups
role from your local machineRun the following command to install the role from the repository:
ansible-galaxy install -r requirements.yml
Run the playbook using the role from the repository:
ansible-playbook -i inventory playbook.yml
You’ve created your first Ansible role and used it in a playbook.
This lab allow you to understand the role structure, how to create a role, use the role in a playbook and understand the role variables.
Additionally, you used some other techniques when authoring Ansible code.