Skip to content

Commit 005b06d

Browse files
author
Roland Wolters
authoredAug 6, 2020
Merge pull request ansible#941 from giannisalinetti/pr-ansible-collections
Adding exercises for Ansible Collections I'll merge this for now. There is some more work needed until we will add it to the main README.md and make it an official lab which can be picked and deployed. But we can work in dedicated PRs on that.
2 parents 51d5aef + 1c7a589 commit 005b06d

File tree

28 files changed

+1811
-0
lines changed

28 files changed

+1811
-0
lines changed
 

‎exercises/ansible_collections/1-create-collections/README.md

+626
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/usr/bin/python
2+
3+
import random
4+
5+
ANSIBLE_METADATA = {
6+
'metadata_version': '1.0',
7+
'status': ['preview'],
8+
'supported_by': 'community'
9+
}
10+
11+
DOCUMENTATION = '''
12+
---
13+
module: demo_hello
14+
short_description: A module that says hello in many languages
15+
version_added: "2.8"
16+
description:
17+
- "A module that says hello in many languages."
18+
options:
19+
name:
20+
default: John Doe
21+
author:
22+
- Gianni Salinetti (@giannisalinetti)
23+
'''
24+
25+
EXAMPLES = '''
26+
# Pass in a custom name
27+
- name: Say hello to Linus Torwalds
28+
demo_hello:
29+
name: "Linus Torwalds"
30+
'''
31+
32+
RETURN = '''
33+
fact:
34+
description: Hello string
35+
type: str
36+
sample: Hello John Doe!
37+
'''
38+
39+
from ansible.module_utils.basic import AnsibleModule
40+
41+
42+
FACTS = [
43+
"Hello {name}!",
44+
"Bonjour {name}!",
45+
"Hola {name}!",
46+
"Ciao {name}!",
47+
"Hallo {name}!",
48+
"Hei {name}!",
49+
]
50+
51+
52+
def run_module():
53+
module_args = dict(
54+
name=dict(type='str', default='John Doe'),
55+
)
56+
57+
module = AnsibleModule(
58+
argument_spec=module_args,
59+
supports_check_mode=True
60+
)
61+
62+
result = dict(
63+
changed=False,
64+
fact=''
65+
)
66+
67+
result['fact'] = random.choice(FACTS).format(
68+
name=module.params['name']
69+
)
70+
71+
if module.check_mode:
72+
return result
73+
74+
module.exit_json(**result)
75+
76+
77+
def main():
78+
run_module()
79+
80+
81+
if __name__ == '__main__':
82+
main()
83+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
language: python
3+
python: "2.7"
4+
5+
# Use the new container infrastructure
6+
sudo: false
7+
8+
# Install ansible
9+
addons:
10+
apt:
11+
packages:
12+
- python-pip
13+
14+
install:
15+
# Install ansible
16+
- pip install ansible
17+
18+
# Check ansible version
19+
- ansible --version
20+
21+
# Create ansible.cfg with correct roles_path
22+
- printf '[defaults]\nroles_path=../' >ansible.cfg
23+
24+
script:
25+
# Basic role syntax check
26+
- ansible-playbook tests/test.yml -i tests/inventory --syntax-check
27+
28+
notifications:
29+
webhooks: https://galaxy.ansible.com/api/v1/notifications/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Role Name
2+
=========
3+
4+
A brief description of the role goes here.
5+
6+
Requirements
7+
------------
8+
9+
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
10+
11+
Role Variables
12+
--------------
13+
14+
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
15+
16+
Dependencies
17+
------------
18+
19+
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
20+
21+
Example Playbook
22+
----------------
23+
24+
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
25+
26+
- hosts: servers
27+
roles:
28+
- { role: username.rolename, x: 42 }
29+
30+
License
31+
-------
32+
33+
BSD
34+
35+
Author Information
36+
------------------
37+
38+
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
# defaults file for redhat.demo_nginx
3+
friend_name: "John Doe"
4+
build_dir_path: "/tmp/demo_nginx_build"
5+
image_registry: "quay.io"
6+
registry_username: ""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM nginx
2+
3+
COPY index.html /usr/share/nginx/html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
galaxy_info:
3+
author: Ansible Automation Platform Hackaton Team
4+
description: Basic builder role based on podman
5+
company: Red Hat
6+
7+
license: Apache-2.0
8+
9+
min_ansible_version: 2.8
10+
11+
12+
platforms:
13+
- name: Fedora
14+
versions:
15+
- 31
16+
- 32
17+
- 33
18+
19+
galaxy_tags: ["demo", "podman"]
20+
21+
dependencies: []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
# tasks file for redhat.demo_nginx
3+
- name: Ensure podman is present in the host
4+
dnf:
5+
name: podman
6+
state: present
7+
become: true
8+
9+
- name: Generate greeting and store result
10+
demo_hello:
11+
name: "{{ friend_name }}"
12+
register: demo_greeting
13+
14+
- name: Create build directory
15+
file:
16+
path: "{{ build_dir_path }}"
17+
state: directory
18+
mode: 0755
19+
20+
- name: Copy Dockerfile
21+
copy:
22+
src: files/Dockerfile
23+
dest: "{{ build_dir_path }}"
24+
mode: 0644
25+
26+
- name: Copy custom index.html
27+
template:
28+
src: templates/index.html.j2
29+
dest: "{{ build_dir_path }}/index.html"
30+
mode: 0644
31+
32+
- name: Build and Push OCI image
33+
podman_image:
34+
name: demo-nginx
35+
path: "{{ build_dir_path }}"
36+
build:
37+
annotation:
38+
app: nginx
39+
function: demo
40+
info: Demo app for Ansible Collections workshop
41+
format: oci
42+
push: true
43+
force: true
44+
push_args:
45+
dest: "{{ image_registry }}/{{ registry_username }}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!doctype html>
2+
3+
<html lang="en">
4+
<head>
5+
<meta charset="utf-8">
6+
7+
<title>Ansible Collections Workshop</title>
8+
<meta name="description" content="Demo Nginx">
9+
<meta name="author" content="gsalinet@redhat.com">
10+
11+
<link rel="stylesheet" href="css/styles.css?v=1.0">
12+
13+
</head>
14+
15+
<body>
16+
<h1>
17+
{{ demo_greeting.fact }}
18+
</h1>
19+
</body>
20+
</html>
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Exercise 2 - Using Ansible Collections
2+
3+
## Table of Contents
4+
5+
- [Objective](#objective)
6+
- [Guide](#guide)
7+
- [Step 1 - Install the Ansible Collection](#step-1---install-the-ansible-collection)
8+
- [Step 2 - Write an Ansible Playbook](#step-2---write-an-ansible-playbook)
9+
- [Step 3 - Test the playbook](#step-3---test-the-playbook)
10+
- [Step 4 - Simplify the namespace](#step-4---simplify-the-namespace)
11+
- [Step 5: Test the change](#step-5-test-the-change)
12+
13+
# Objective
14+
15+
In this part of the lab, you will learn how to use an Ansible Collection in your playbook. To identify a specific module from an Ansible Collection, we have to use the fully qualified collection name. This name is built from the name of the author, the name of the collection and the name of the module.
16+
17+
<author>.<collection>.<module>
18+
19+
For the following exercise, we will use a collection written by the Ansible Core Team. The name of the author is therefore "ansible". You can find a list of all modules and collections written by the Ansible Core Team on [Ansible Galaxy](https://galaxy.ansible.com/ansible).
20+
21+
As you can see they maintain several collections and roles. One of their collections is called "posix" and we can find the documentation and additional details on the [Ansible Galaxy POSIX Collection](https://galaxy.ansible.com/ansible/posix) page.
22+
23+
One of the modules provided by this collection allows us to manage [SELinux](https://www.redhat.com/en/topics/linux/what-is-selinux) settings. The fully qualified collection name for this module is therefore `ansible.posix.selinux`.
24+
25+
You can find more details about [using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) in the [Ansible Documentation](https://docs.ansible.com/).
26+
27+
# Guide
28+
29+
## Step 1 - Install the Ansible Collection
30+
31+
The `ansible.posix.selinux` module which we want to use for this exercise, it part of the `ansible.posix` collection. We have to install this collection first, before we can use its modules. The `ansible-galaxy` command line tool can be used to automate the installation. It us preconfigured to search for roles and collections on [Ansible Galaxy](https://galaxy.ansible.com/) so we can just specify the collection name and it will take care of the rest:
32+
33+
ansible-galaxy collection install ansible.posix
34+
35+
This will install collection on your system, only if it wasn't installed before. To force the installation, for example to make sure you're on the latest version, you can add the force switch `-f`.
36+
37+
ansible-galaxy collection install -f ansible.posix
38+
39+
This will always download and install the latest version, even if it was already up to date. Ansible Collections can have dependencies for other Ansible Collections as well - if you want to make sure those dependencies are refreshed as well, you can use the `--force-with-deps` switch.
40+
41+
By default the installation is stored in your local `~/.ansible` directory. This can be overwritten by using the `-p /path/to/collection` switch. Keep in mind though that `ansible-playbook` will only use that directory if you change your `ansible.cfg` accordingly.
42+
43+
## Step 2 - Documentation
44+
45+
The `ansible-doc` command only searches the system directories for documentation. You can still use it though to read up on modules you installed from Ansible Collections by using the fully qualified collection name.
46+
47+
Let's have a look at the module documentation for the `selinux` module which we are going to use in the next part of the exercise:
48+
49+
```bash
50+
ansible-doc ansible.posix.selinux
51+
```
52+
53+
> **NOTE**: Depending on your screen resolution you might have to press `q` to leave the documentation viewer.
54+
55+
## Step 3 - Write an Ansible Playbook
56+
57+
We want to use the SELinux module to make sure it is configured in enforcing mode. SELinux is a kernel feature which brings extra security to our Linux system and it is highly recommended to always keep it enabled and in enforcing mode. If you're new to SELinux, there is a nice article on [What is SELinux](https://www.redhat.com/en/topics/linux/what-is-selinux) to get you started.
58+
59+
Let's write a simple playbook which enables SELinux and sets it to enforcing mode on the local machine.
60+
61+
```yaml
62+
---
63+
- name: set SELinux to enforcing
64+
hosts: localhost
65+
become: yes
66+
tasks:
67+
- name: set SElinux to enforcing
68+
ansible.posix.selinux:
69+
policy: targeted
70+
state: enforcing
71+
```
72+
73+
Save the playbook as `enforce-selinux.yml` for later.
74+
75+
> **NOTE**: Pay special attention to the module name. Typically you would see something like `selinux`, but since we are using a module provided by an Ansible Collection, we have to specify the fully qualified module name.
76+
77+
## Step 4 - Test the playbook
78+
79+
You can run the Playbook and see what happens:
80+
81+
ansible-playbook enforce-selinux.yml
82+
83+
You should see output like this:
84+
85+
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
86+
87+
PLAY [set SELinux to enforcing] ***********************************************************************************
88+
89+
TASK [Gathering Facts] ********************************************************************************************
90+
ok: [localhost]
91+
92+
TASK [set SElinux to enforcing] ***********************************************************************************
93+
ok: [localhost]
94+
95+
PLAY RECAP ********************************************************************************************************
96+
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
97+
98+
If SELinux was not set to enforcing before, you might see "changed" instead of ok. If it did say "changed" and you run it a second time, you should now see "ok" - the magic of [Ansible idempotency](https://docs.ansible.com/ansible/latest/reference_appendices/glossary.html).
99+
100+
## Step 5 - Simplify the namespace
101+
102+
If you use many modules from Ansible Collections in your Playbook, the <author>.<collection> prefix can become quite annoying it reading your Playbook can become harder as well.
103+
104+
You can use the `collections` key word to skip defining the namespace with every task.
105+
106+
```yaml
107+
---
108+
- name: set SELinux to enforcing
109+
hosts: localhost
110+
become: yes
111+
collections:
112+
- ansible.posix
113+
tasks:
114+
- name: set SElinux to enforcing
115+
selinux:
116+
policy: targeted
117+
state: enforcing
118+
```
119+
120+
> **NOTE**: Although the syntax looks similar to how you specify roles, this works different. They keyword `roles` will execute the `tasks/main.yml` in each role. The `collections` keyword is merely a shortcut so you can skip the author and namespace every time you use a module in a task.
121+
122+
## Step 6: Test the change
123+
124+
When running the Playbook again, you shouldn't actually see any difference in the output. As explained before, the `collections` keyword only simplifies writing your Playbook.
125+
126+
----
127+
**Navigation**
128+
<br>
129+
[Previous Exercise](../1-create-collections/) - [Next Exercise](../3-collections-from-roles)
130+
131+
[Click here to return to the Ansible for Red Hat Enterprise Linux Workshop](../README.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
# Exercise 3 - Running Collections from Roles
2+
3+
## Table of Contents
4+
5+
- [Objective](#objective)
6+
- [Guide](#guide)
7+
- [Step 1: Understand collections lookup](#step-1-understand-collections-lookup)
8+
- [Step 2: Running collections from a role](step-2-running-collections-from-a-role)
9+
- [Takeaways](#takeaways)
10+
11+
# Objective
12+
13+
This exercise will help users understand how collections are used from within roles.
14+
15+
Covered topics:
16+
17+
- Explain collection resolution logic
18+
19+
- Demonstrate how to call collections from roles using collection fully qualified collection name (FQCN)
20+
21+
# Guide
22+
23+
## Step 1: Understand collections lookup
24+
25+
Ansible Collections use a simple method to define collection namespaces. Anyway, if
26+
your playbook loads collections using the `collections` key and one or more roles, then
27+
the roles will not inherit the collections set by the playbook.
28+
29+
This leads to the main topic of this exercise: roles have an independent collection
30+
loading method based on the role's metadata.
31+
To control collections search for the tasks inside the role, users can choose between
32+
two approaches:
33+
34+
- **Approach 1**: Pass a list of collections in the `collections` field inside the `meta/main.yml` file within the role.
35+
This will ensure that the collections list searched by the role will have higher priority than
36+
the collections list in the playbook. Ansible will use the collections list defined inside the role
37+
even if the playbook that calls the role defines different collections in a separate `collections` keyword entry.
38+
39+
```yaml
40+
# myrole/meta/main.yml
41+
collections:
42+
- my_namespace.first_collection
43+
- my_namespace.second_collection
44+
- other_namespace.other_collection
45+
```
46+
47+
- **Approach 2**: Use the collection fully qualified collection name (FQCN) directly from a task in the role.
48+
In this way the collection will always be called with its unique FQCN, and override any other
49+
lookup in the playbook
50+
51+
```yaml
52+
- name: Create an EC2 instance using collection by FQCN
53+
amazon.aws.ec2:
54+
key_name: mykey
55+
instance_type: t2.micro
56+
image: ami-123456
57+
wait: yes
58+
group: webserver
59+
count: 3
60+
vpc_subnet_id: subnet-29e63245
61+
assign_public_ip: yes
62+
```
63+
64+
Roles defined **within** a collection always implicitly search their own collection
65+
first, so there is no need to use the `collections` keyword in the role metadata to access modules, plugins, or other roles.
66+
67+
## Step 2: Running collections from a role
68+
69+
Create the exercise folder:
70+
71+
```bash
72+
mkdir exercise-03
73+
cd esercise--3
74+
```
75+
76+
For this lab, we will use the `ansible.posix` collection, which contains a series of POSIX
77+
oriented modules and plugins for systems management.
78+
79+
```bash
80+
ansible-galaxy collection install ansible.posix
81+
```
82+
83+
### Approach 1: Collections loaded as metadata
84+
85+
> **TIP**: You can go though the exercise steps or copy the finished role from `solutions/selinux_manage_meta`.
86+
87+
Create a new role using the `ansible-galaxy init` command:
88+
89+
```bash
90+
ansible-galaxy init --init-path roles selinux_manage_meta
91+
```
92+
93+
Edit the `roles/selinux_manage_meta/meta/main.yml` file and append the following lines at the end of the file, beginning at column 1:
94+
95+
```yaml
96+
# Collections list
97+
collections:
98+
- ansible.posix
99+
```
100+
101+
Edit the `roles/selinux_manage_meta/tasks/main.yml` file and add the following tasks:
102+
103+
```yaml
104+
---
105+
# tasks file for selinux_manage_meta
106+
- name: Enable SELinux enforcing mode
107+
selinux:
108+
policy: targeted
109+
state: "{{ selinux_mode }}"
110+
111+
- name: Enable booleans
112+
seboolean:
113+
name: "{{ item }}"
114+
state: true
115+
persistent: true
116+
loop: "{{ sebooleans_enable }}"
117+
118+
- name: Disable booleans
119+
seboolean:
120+
name: "{{ item }}"
121+
state: false
122+
persistent: true
123+
loop: "{{ sebooleans_disable }}"
124+
```
125+
126+
> **NOTE:** We're using the simple module name. Ansible uses the information from the
127+
> `collections` list in the metadata file to locate the collection(s) used.
128+
129+
Edit the `roles/selinux_manage_meta/defaults/main.yml` to define default values for role variables:
130+
131+
```yaml
132+
---
133+
# defaults file for selinux_manage_meta
134+
selinux_mode: enforcing
135+
sebooleans_enable: []
136+
sebooleans_disable: []
137+
```
138+
139+
Cleanup unused folders in the role:
140+
141+
```bash
142+
rm -rf roles/selinux_manage_meta/{tests,vars,handlers,files,templates}
143+
```
144+
145+
We can now test the new role with a basic playbook. Create the `playbook.yml` file
146+
in the current folder with the following content:
147+
148+
```yaml
149+
---
150+
- hosts: localhost
151+
become: true
152+
vars:
153+
sebooleans_enable:
154+
- httpd_can_network_connect
155+
- httpd_mod_auth_pam
156+
sebooleans_disable:
157+
- httpd_enable_cgi
158+
roles:
159+
- selinux_manage_meta
160+
```
161+
162+
Run the playbook and check the results:
163+
164+
```bash
165+
$ ansible-playbook playbook.yml
166+
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
167+
168+
PLAY [localhost] ******************************************************************************************************
169+
170+
TASK [Gathering Facts] ************************************************************************************************
171+
ok: [localhost]
172+
173+
TASK [selinux_manage_meta : Enable SELinux enforcing mode] ************************************************************
174+
ok: [localhost]
175+
176+
TASK [selinux_manage_meta : Enable booleans] **************************************************************************
177+
changed: [localhost] => (item=httpd_can_network_connect)
178+
changed: [localhost] => (item=httpd_mod_auth_pam)
179+
180+
TASK [selinux_manage_meta : Disable booleans] *************************************************************************
181+
changed: [localhost] => (item=httpd_can_network_connect)
182+
183+
PLAY RECAP ************************************************************************************************************
184+
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
185+
```
186+
187+
### Approach 2: Collections loaded with FQCN
188+
189+
The second approach uses the collection FQCN to call the related modules and plugins. To better demonstrate the differences, we will implement a new version of the previous role with the FQCN approach without changing the inner logic.
190+
191+
> **TIP**: You can go though the exercise steps or copy the finished role from `solutions/selinux_manage_fqcn`.
192+
193+
Create a new role using the `ansible-galaxy init` command:
194+
195+
```bash
196+
ansible-galaxy init --init-path roles selinux_manage_fqcn
197+
```
198+
199+
Edit the `roles/selinux_manage_fqcn/tasks/main.yml` file and add the following tasks:
200+
201+
```yaml
202+
---
203+
# tasks file for selinux_manage_fqcn
204+
- name: Enable SELinux enforcing mode
205+
ansible.posix.selinux:
206+
policy: targeted
207+
state: "{{ selinux_mode }}"
208+
209+
- name: Enable booleans
210+
ansible.posix.seboolean:
211+
name: "{{ item }}"
212+
state: true
213+
persistent: true
214+
loop: "{{ sebooleans_enable }}"
215+
216+
- name: Disable booleans
217+
ansible.posix.seboolean:
218+
name: "{{ item }}"
219+
state: false
220+
persistent: true
221+
loop: "{{ sebooleans_disable }}"
222+
```
223+
224+
> **NOTE**: Notice the usage of the modules FQCN in the role tasks. Ansible will directly
225+
> look for the installed collection from within the role task, no matter if
226+
> the `collections` keyword is defined at playbook level.
227+
228+
Edit the `roles/selinux_manage_fqcn/defaults/main.yml` to define default values for role variables:
229+
230+
```yaml
231+
---
232+
# defaults file for selinux_manage_fqcn
233+
selinux_mode: enforcing
234+
sebooleans_enable: []
235+
sebooleans_disable: []
236+
```
237+
238+
Cleanup unused folders in the role:
239+
240+
```bash
241+
rm -rf roles/selinux_manage_meta/{tests,vars,handlers,files,templates}
242+
```
243+
244+
Modify the previous `playbook.yml` file to use the new role:
245+
246+
```yaml
247+
---
248+
- hosts: localhost
249+
become: true
250+
vars:
251+
sebooleans_enable:
252+
- httpd_can_network_connect
253+
- httpd_mod_auth_pam
254+
sebooleans_disable:
255+
- httpd_enable_cgi
256+
roles:
257+
- selinux_manage_FQCN
258+
```
259+
260+
Run the playbook again and check the results:
261+
262+
```bash
263+
$ ansible-playbook playbook.yml
264+
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
265+
266+
PLAY [localhost] ******************************************************************************************************
267+
268+
TASK [Gathering Facts] ************************************************************************************************
269+
ok: [localhost]
270+
271+
TASK [selinux_manage_meta : Enable SELinux enforcing mode] ************************************************************
272+
ok: [localhost]
273+
274+
TASK [selinux_manage_meta : Enable booleans] **************************************************************************
275+
changed: [localhost] => (item=httpd_can_network_connect)
276+
ok: [localhost] => (item=httpd_mod_auth_pam)
277+
278+
TASK [selinux_manage_meta : Disable booleans] *************************************************************************
279+
changed: [localhost] => (item=httpd_can_network_connect)
280+
281+
PLAY RECAP ************************************************************************************************************
282+
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
283+
```
284+
285+
This concludes the guided exercise.
286+
287+
# Takeaways
288+
289+
- Collections can be called from roles using the `collections` list defined in `meta/main.yml`.
290+
291+
- Collections can be called from roles using their FQCN directly from the role task.
292+
293+
----
294+
**Navigation**
295+
<br>
296+
[Previous Exercise](../2-collections-from-playbook/) - [Next Exercise](../4-collections-from-tower)
297+
298+
[Click here to return to the Ansible for Red Hat Enterprise Linux Workshop](../README.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
language: python
3+
python: "2.7"
4+
5+
# Use the new container infrastructure
6+
sudo: false
7+
8+
# Install ansible
9+
addons:
10+
apt:
11+
packages:
12+
- python-pip
13+
14+
install:
15+
# Install ansible
16+
- pip install ansible
17+
18+
# Check ansible version
19+
- ansible --version
20+
21+
# Create ansible.cfg with correct roles_path
22+
- printf '[defaults]\nroles_path=../' >ansible.cfg
23+
24+
script:
25+
# Basic role syntax check
26+
- ansible-playbook tests/test.yml -i tests/inventory --syntax-check
27+
28+
notifications:
29+
webhooks: https://galaxy.ansible.com/api/v1/notifications/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Role Name
2+
=========
3+
4+
A brief description of the role goes here.
5+
6+
Requirements
7+
------------
8+
9+
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
10+
11+
Role Variables
12+
--------------
13+
14+
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
15+
16+
Dependencies
17+
------------
18+
19+
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
20+
21+
Example Playbook
22+
----------------
23+
24+
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
25+
26+
- hosts: servers
27+
roles:
28+
- { role: username.rolename, x: 42 }
29+
30+
License
31+
-------
32+
33+
BSD
34+
35+
Author Information
36+
------------------
37+
38+
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
# defaults file for selinux_manage_fqdn
3+
selinux_mode: enforcing
4+
5+
sebooleans_enable: []
6+
sebooleans_disable: []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
galaxy_info:
3+
author: your name
4+
description: your role description
5+
company: your company (optional)
6+
7+
# If the issue tracker for your role is not on github, uncomment the
8+
# next line and provide a value
9+
# issue_tracker_url: http://example.com/issue/tracker
10+
11+
# Choose a valid license ID from https://spdx.org - some suggested licenses:
12+
# - BSD-3-Clause (default)
13+
# - MIT
14+
# - GPL-2.0-or-later
15+
# - GPL-3.0-only
16+
# - Apache-2.0
17+
# - CC-BY-4.0
18+
license: license (GPL-2.0-or-later, MIT, etc)
19+
20+
min_ansible_version: 2.9
21+
22+
# If this a Container Enabled role, provide the minimum Ansible Container version.
23+
# min_ansible_container_version:
24+
25+
#
26+
# Provide a list of supported platforms, and for each platform a list of versions.
27+
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
28+
# To view available platforms and versions (or releases), visit:
29+
# https://galaxy.ansible.com/api/v1/platforms/
30+
#
31+
# platforms:
32+
# - name: Fedora
33+
# versions:
34+
# - all
35+
# - 25
36+
# - name: SomePlatform
37+
# versions:
38+
# - all
39+
# - 1.0
40+
# - 7
41+
# - 99.99
42+
43+
galaxy_tags: []
44+
# List tags for your role here, one per line. A tag is a keyword that describes
45+
# and categorizes the role. Users find roles by searching for tags. Be sure to
46+
# remove the '[]' above, if you add tags to this list.
47+
#
48+
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
49+
# Maximum 20 tags per role.
50+
51+
dependencies: []
52+
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
53+
# if you add dependencies to this list.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
# tasks file for selinux_manage_fqdn
3+
- name: Enable SELinux enforcing mode
4+
ansible.posix.selinux:
5+
policy: targeted
6+
state: "{{ selinux_mode }}"
7+
8+
- name: Enable booleans
9+
ansible.posix.seboolean:
10+
name: "{{ item }}"
11+
state: true
12+
persistent: true
13+
loop: "{{ sebooleans_enable }}"
14+
15+
- name: Disable booleans
16+
ansible.posix.seboolean:
17+
name: "{{ item }}"
18+
state: false
19+
persistent: true
20+
loop: "{{ sebooleans_disable }}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
language: python
3+
python: "2.7"
4+
5+
# Use the new container infrastructure
6+
sudo: false
7+
8+
# Install ansible
9+
addons:
10+
apt:
11+
packages:
12+
- python-pip
13+
14+
install:
15+
# Install ansible
16+
- pip install ansible
17+
18+
# Check ansible version
19+
- ansible --version
20+
21+
# Create ansible.cfg with correct roles_path
22+
- printf '[defaults]\nroles_path=../' >ansible.cfg
23+
24+
script:
25+
# Basic role syntax check
26+
- ansible-playbook tests/test.yml -i tests/inventory --syntax-check
27+
28+
notifications:
29+
webhooks: https://galaxy.ansible.com/api/v1/notifications/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Role Name
2+
=========
3+
4+
A brief description of the role goes here.
5+
6+
Requirements
7+
------------
8+
9+
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
10+
11+
Role Variables
12+
--------------
13+
14+
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
15+
16+
Dependencies
17+
------------
18+
19+
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
20+
21+
Example Playbook
22+
----------------
23+
24+
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
25+
26+
- hosts: servers
27+
roles:
28+
- { role: username.rolename, x: 42 }
29+
30+
License
31+
-------
32+
33+
BSD
34+
35+
Author Information
36+
------------------
37+
38+
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
# defaults file for selinux_manage_meta
3+
selinux_mode: enforcing
4+
5+
sebooleans_enable: []
6+
sebooleans_disable: []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
galaxy_info:
3+
author: your name
4+
description: your role description
5+
company: your company (optional)
6+
7+
# If the issue tracker for your role is not on github, uncomment the
8+
# next line and provide a value
9+
# issue_tracker_url: http://example.com/issue/tracker
10+
11+
# Choose a valid license ID from https://spdx.org - some suggested licenses:
12+
# - BSD-3-Clause (default)
13+
# - MIT
14+
# - GPL-2.0-or-later
15+
# - GPL-3.0-only
16+
# - Apache-2.0
17+
# - CC-BY-4.0
18+
license: license (GPL-2.0-or-later, MIT, etc)
19+
20+
min_ansible_version: 2.9
21+
22+
# If this a Container Enabled role, provide the minimum Ansible Container version.
23+
# min_ansible_container_version:
24+
25+
#
26+
# Provide a list of supported platforms, and for each platform a list of versions.
27+
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
28+
# To view available platforms and versions (or releases), visit:
29+
# https://galaxy.ansible.com/api/v1/platforms/
30+
#
31+
# platforms:
32+
# - name: Fedora
33+
# versions:
34+
# - all
35+
# - 25
36+
# - name: SomePlatform
37+
# versions:
38+
# - all
39+
# - 1.0
40+
# - 7
41+
# - 99.99
42+
43+
galaxy_tags: []
44+
# List tags for your role here, one per line. A tag is a keyword that describes
45+
# and categorizes the role. Users find roles by searching for tags. Be sure to
46+
# remove the '[]' above, if you add tags to this list.
47+
#
48+
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
49+
# Maximum 20 tags per role.
50+
51+
dependencies: []
52+
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
53+
# if you add dependencies to this list.
54+
55+
# Collections list
56+
collections:
57+
- ansible.posix
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
# tasks file for selinux_manage_meta
3+
- name: Enable SELinux enforcing mode
4+
selinux:
5+
policy: targeted
6+
state: "{{ selinux_mode }}"
7+
8+
- name: Enable booleans
9+
seboolean:
10+
name: "{{ item }}"
11+
state: true
12+
persistent: true
13+
loop: "{{ sebooleans_enable }}"
14+
15+
- name: Disable booleans
16+
seboolean:
17+
name: "{{ item }}"
18+
state: false
19+
persistent: true
20+
loop: "{{ sebooleans_disable }}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Exercise 4 - How to use Collections on Red Hat Ansible Tower
2+
3+
## Table of Contents
4+
5+
- [Objective](#objective)
6+
- [Guide](#guide)
7+
- [Step 1 - Write a requirements.yml](#step-1---write-a-requirementsyml)
8+
- [Step 2 - Create Job Template](#step-2---create-job-template)
9+
- [Troubleshooting](#troubleshooting)
10+
11+
# Objective
12+
13+
Red Hat Ansible Tower supports Ansible Collections starting with version 3.5 - earlier version will not automatically install and configure them for you. To make sure Ansible Collections are recognized by Red Hat Ansible Tower a requirements file is needed and has to be stored in the proper directory.
14+
15+
Ansible Galaxy is already configured by default, however if you want your Red Hat Ansible Tower to prefer and fetch content from the Red Hat Automation Hub, additional configuration changes are required. They are addressed in a the chapter [Use Automation Hub](../7-use-automation-hub/) in this lab.
16+
17+
# Guide
18+
19+
In this exercise you will learn how to define an Ansible Collection as a requirement in a format recognized by Red Hat Ansible Tower.
20+
21+
## Step 1 - Write a requirements.yml
22+
23+
Red Hat Ansible Tower can download and install Ansible Collections automatically before executing a Job Template. If a `collections/requirements.yml` exists, it will be parsed and Ansible Collections specified in this file will be automatically installed.
24+
25+
> **NOTE**: Starting with Red Hat Ansible Tower 3.6 the working directory for the Job Template is in `/tmp`. Since the Ansible Collection is downloaded into this directory before the Job Template is executed, you will not find temporary files of your Ansible Collection in `/var/lib/awx/projects/`.
26+
27+
The format of the `requirements.yml` for Ansible Collections is very similar to the one for roles, however it is very important to store in the folder `collections`.
28+
29+
Here is an example to set the `ansible.posix` Ansible Collection as a requirement:
30+
31+
```yaml
32+
---
33+
collections:
34+
- ansible.posix
35+
```
36+
37+
## Step 2 - Create Job Template
38+
39+
When using Ansible Collections in your Playbook, there are no additional options to set in your Red Hat Ansible Tower Job Template. You specify the repository in which your Playbook is stored, inventory, credentials and other parameters, and execute it by clicking on the **Launch** button.
40+
41+
# Troubleshooting
42+
43+
Since Red Hat Ansible Tower does only check for updates in the the repository in which you stored your Playbook, it might not do a refresh if there was a change in the Ansible Collection used by your Playbook. This happens particularly if you also combine Roles and Collections.
44+
45+
In this case you should check the option **Delete on Update** which will delete the entire local directory during a refresh.
46+
47+
If there is a problem while parsing your `requirements.yml` it worth testing it with the `ansible-galaxy` command. As a reminder, Red Hat Ansible Tower basically also just runs the command for you with the appropriate parameters, so testing this works manually makes a lot of sense.
48+
49+
```bash
50+
ansible-galaxy collections install -r collections/requirements.yml -f
51+
```
52+
53+
> **NOTE**: The `-f` switch will forces a fresh installation of the specified Ansible Collections, otherwise `ansible-galaxy` will only install it, if it wasn't already installed. You can also use the `--force-with-deps` switch to make sure Ansible Collections which have dependencies to others are refreshed as well.
54+
55+
----
56+
**Navigation**
57+
<br>
58+
[Previous Exercise](../3-collections-from-roles/) - [Next Exercise](../5-use-automation-hub)
59+
60+
[Click here to return to the Ansible for Red Hat Enterprise Linux Workshop](../README.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Exercise 5 - How to use Red Hat Automation Hub?
2+
3+
## Table of Contents
4+
5+
- [Objective](#objective)
6+
- [Red Hat Automation Hub](#red-hat-automation-hub)
7+
- [Certified Content](#certified-content)
8+
- [Supported Automation](#supported-automation)
9+
- [Ansible Galaxy](#ansible-galaxy)
10+
- [How to use Automation Hub](#how-to-use-automation-hub)
11+
- [Accessing collections](#accessing-collections)
12+
- [Creating a token](#creating-a-token)
13+
- [Using authentication token](#using-authentication-token)
14+
- [Using Collections](#using-collections)
15+
- [Authenticate Tower to Automation Hub](#authenticate-tower-to-automation-hub)
16+
- [Takeaways](#takeaways)
17+
18+
# Objective
19+
20+
In this lab you will learn the value proposition of Red Hat Automation Hub and how to use the provided content.
21+
22+
# Red Hat Automation Hub
23+
24+
It is a service that is provided as part of the Red Hat SaaS Offering. It consists of the location where to discover and download only supported and certified Ansible Content Collections by Red Hat and its Partners. These content collections contain ways to consume automation, how-to-guides to implement them in your infrastructure. The support for Automation Hub is included with Red Hat Automation Platform subscription.
25+
26+
> **NOTE**: Red Hat Automation Hub resides on [https://cloud.redhat.com/ansible/automation-hub](https://cloud.redhat.com/ansible/automation-hub): requires Red Hat customer portal credentials and a valid Red Hat Automation Platform subscription.
27+
28+
## Certified Content
29+
30+
In the portal of Automation Hub, users have direct access to trusted content collections from Red Hat and Certified Partners. Certified collections are developed, tested, built, delivered, and supported by Red Hat and its Partners. To find more details about the scope of support, check the [Ansible Certified Content FAQ](https://access.redhat.com/articles/4916901),
31+
32+
## Supported Automation
33+
34+
Automation Hub is a one-stop-shop for Ansible content that is backed by support from Red Hat to deliver additional reassurance for customers. Additional supportability claims for these collections may be provided under the "Maintained and Supported By" one of Red Hat Partners.
35+
36+
# Ansible Galaxy
37+
38+
It is the location for wider Ansible community that initially started to provide pre-packaged units of work known as Ansible roles. Roles can be dropped into Ansible Playbooks and immediately put to work. in a recent version of Galaxy started to provide Ansible content collections as well.
39+
40+
Ansible Galaxy resides on [https://galaxy.ansible.com/](https://galaxy.ansible.com/)
41+
42+
# How to use Automation Hub
43+
44+
## Accessing collections
45+
46+
Ansible collections can be used and downloaded from multiple locations. They can either be downloaded using a requirement file, statically included in the git repository or eventually installed separately in the virtual environment.
47+
48+
In the scope of this exercise, the focus is on how access content from Automation Hub. This requires an authentication token and authentication URL. To do, some configuration steps need to be done in Ansible Tower.
49+
50+
## Authenticate Tower to Automation Hub
51+
52+
### Creating a token
53+
54+
Authenticating Ansible Tower requires a token. It can be achieved using the steps below:
55+
56+
1. Navigate to [https://cloud.redhat.com/ansible/automation-hub/token/](https://cloud.redhat.com/ansible/automation-hub/token/)
57+
58+
![Load token|845x550,20%](screenshots/create-token.png)
59+
60+
1. Click **Load Token**.
61+
62+
1. Click **copy icon** to copy the API token to the clipboard.
63+
64+
![Copy token|845x550,20%](screenshots/copy-token.png)
65+
66+
### Using authentication token
67+
68+
1. As user admin, navigate to the *Settings l> Jobs*
69+
70+
1. Set **PRIMARY GALAXY SERVER URL** to `https://cloud.redhat.com/api/automation-hub/`
71+
72+
1. Set **PRIMARY GALAXY AUTHENTICATION** URL to `https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token`
73+
74+
1. Set **PRIMARY GALAXY SERVER TOKEN** to <COPIED_TOKEN>
75+
76+
> **TIP**: It is recommended using Red Hat Automation Hub as primary Galaxy Server URL to ensure using certified and supported content by Red Hat and its partners via Red Hat Ansible Automation subscription.
77+
78+
![test image size](screenshots/token.png)
79+
80+
### Using collections
81+
82+
After authenticating Ansible Tower to access Automation Hub, using `collections/requirements.yml` file will automatically fetches the content collections from Automation Hub as first source.
83+
84+
# Takeaways
85+
86+
- The Red Hat Automation Hub provides certified collections that supported by Red Hat and its Partners. It's available via Red Hat Ansible Automation Platform.
87+
- Ansible Galaxy hosts upstream community content collections.
88+
- Red Hat Ansible Tower can be configured to authenticate to Red Hat Automation Hub in order to fetch certified and supported content collections that are utilized in a given project within tower.
89+
90+
----
91+
**Navigation**
92+
<br>
93+
[Previous Exercise](../4-collections-from-tower/)
94+
95+
[Click here to return to the Ansible for Red Hat Enterprise Linux Workshop](../README.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Loading
Loading
Loading
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Ansible Collections Workshop
2+
3+
This workshop is a step by step series of exercises to demonstrate
4+
features and benefits of Ansible Collections, a unique distribution
5+
format of Ansible content that can be used to package and distribute
6+
playbooks, roles, modules, and plugins.
7+
8+
## Time Planning
9+
10+
The average duration of this workshop depends on the Ansible skills of
11+
practitioner. The average duration should be around 3 hours or less with
12+
advanced Ansible users.
13+
14+
All exercises are self explanatory and guide the participants through the entire lab.
15+
Concepts are explained when they are introduced along with the practice exercise.
16+
17+
## Prerequisites
18+
19+
- Ansible v2.9
20+
21+
- An OS of choice between RHEL/CentOS 8.x, CentOS Stream, Fedora 31+
22+
23+
## Ansible Collections Exercises
24+
25+
The workshop is structured in a set of progressive exercises, covering collections creation,
26+
usage from playbooks, roles and Tower and an introduction to Ansible Automation Hub.
27+
28+
- [Exercise 1 - Create Collections](./1-create-collections)
29+
30+
- [Exercise 2 - Collections from playbook](./2-collections-from-playbook)
31+
32+
- [Exercise 3 - Collections from roles](./3-collections-from-roles)
33+
34+
- [Exercise 4 - Collections from tower](./4-collections-from-tower)
35+
36+
- [Exercise 5 - Use Automation Hub](./5-use-automation-hub)
37+
38+
## Additional Information
39+
40+
- [Ansible Docs: Using Collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html)
41+
42+
- [Ansible Collections Overview](https://github.com/ansible-collections/overview)
43+
44+
- [Ansible Docs: Developing Collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html)
45+
46+
- [Blog Post: Introducing: The AWX and Ansible Tower Collections](https://www.ansible.com/blog/introducing-the-awx-collection)
47+
48+
## Authors
49+
50+
Ansible Automation Platform 1.1 Hackfest - Team 1
51+
52+
- Christian Jung <cjung@redhat.com>
53+
54+
- Gianni Salinetti <gsalinet@redhat.com>
55+
56+
- David Sastre Medina <asastrem@redhat.com>
57+
58+
- Ismail Dhaoui <idhaoui@redhat.com>

0 commit comments

Comments
 (0)
Please sign in to comment.