Skip to content

Commit 1d81ab8

Browse files
committed
Adds resources for day 27
1 parent 9d44154 commit 1d81ab8

1 file changed

Lines changed: 199 additions & 0 deletions

File tree

2024/day27.md

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# Day 27: 90DaysofDevOps
2+
3+
## From Automated to Automatic - Event-Driven Infrastructure Management with Ansible
4+
5+
**Daniel Bodky**
6+
- [Twitter](https://twitter.com/d_bodky)
7+
- [LinkedIn](https://linkedin.com/in/daniel-bodky)
8+
- [Blog](https://dbodky.me)
9+
10+
## Overview
11+
12+
A universal truth and recurring theme in the DevOps world is automation. From providing infrastructure to testing code to deploying to production, many parts of the DevOps lifecycle get automated already. One popular technology for managing infrastructure and configuration in an automated way is Ansible, but are we fully utilizing its capabilities yet?
13+
14+
This presentation will give a broad overview of Ansible and its architecture and use-cases, before exploring a relatively new feature, Event-driven Ansible (EDA). Analzying applications of event-driven Ansible, participants will see that automated management is nice, but automatic management is awesome, not just regarding DevOps principles, but also in terms of reaction times, the human tendency for minor mistakes, and toil for operators.
15+
16+
Participants will get first-hand insights into Ansible, its strengths, weaknesses, and the potential of event-driven automation within the DevOps world.
17+
18+
## Demos
19+
20+
<details>
21+
22+
<summary>Prerequisites</summary>
23+
24+
### Ansible Inventory
25+
26+
> [!NOTE]
27+
> For this inventory file to work, you need to create VMs accordingly and adjust the IP addresses to fit your lab environment.
28+
29+
Ansible utilizes so-called inventories to manage a list of hosts and groups of hosts. Below is the inventory for the demo environment used in this presentation.
30+
31+
```yaml
32+
hosts:
33+
webservers:
34+
hosts:
35+
webshop.example.com: # Ubuntu
36+
ansible_host: 192.168.1.10
37+
webserver: apache2
38+
company.example.com: # Ubuntu
39+
ansible_host: 192.168.1.11
40+
webserver: nginx
41+
internal.example.com: # CentOS Stream
42+
ansible_host: 192.168.1.12
43+
webserver: httpd
44+
```
45+
46+
You can copy-paste this inventory into a file called `hosts.yml` and use it for the following demos.
47+
48+
</details>
49+
50+
<details>
51+
52+
<summary>Lab 1: Ansible Basics</summary>
53+
54+
### Demo 1: Ansible Basics
55+
56+
#### Ansible from the CLI via `ansible`
57+
58+
The first example installs a webserver on all hosts in the `webservers` group. The installed webserver is defined as a **host variable** in the inventory file `hosts.yml` (*see above*).
59+
60+
```console
61+
ansible \
62+
webservers \
63+
-i hosts.yml \
64+
-m package \
65+
-a 'name="{{ webserver }}"'
66+
```
67+
68+
#### Ansible from the CLI via `ansible-playbook`
69+
70+
The second example utilizes the following **playbook** to **install** and **start** the defined webserver on all hosts in the `webservers` group.
71+
72+
```yaml
73+
---
74+
- name: Install webservers
75+
hosts: webservers
76+
vars:
77+
package: "{{ webserver }}"
78+
become: true
79+
tasks:
80+
- name: Install webserver
81+
ansible.builtin.package:
82+
name: "{{ package }}"
83+
state: present
84+
85+
- name: Start webserver
86+
ansible.builtin.service:
87+
name: "{{ package }}"
88+
state: started
89+
```
90+
91+
Save this playbook as `playbook.yml` and run it with the following command.
92+
93+
```console
94+
ansible-playbook \
95+
-i hosts.yml \
96+
playbook.yml
97+
```
98+
99+
You will see a separated output for each task in the playbook. In the end, you should be able to access the webserver on each host in the `webservers` group.
100+
101+
> [!TIP]
102+
> Ansible is **idempotent** - try running the playbook again and see how the output differs.
103+
104+
</details>
105+
106+
<details>
107+
108+
<summary>Lab 2: Event-driven Ansible and Generic Webhooks</summary>
109+
110+
### Demo 2: Event-driven Ansible and Generic Webhooks
111+
112+
#### Prerequisites
113+
114+
For this demo, we will use `localhost` as the target host. Therefore, we need to adjust our inventory file `hosts.yml` accordingly:
115+
116+
```yaml
117+
hosts:
118+
localhost: {}
119+
120+
The first demo of event-driven Ansible shows how to use a generic webhook to trigger a playbook run. Copy the following rulebook into a file called `rulebook.yml`.
121+
122+
```yaml
123+
- name: Listen to webhook events
124+
hosts: all
125+
sources:
126+
- ansible.eda.webhook:
127+
host: 0.0.0.0
128+
port: 5000
129+
rules:
130+
- name: Debug event output
131+
condition: event.payload.greeting is defined
132+
action:
133+
debug:
134+
msg: "Hello {{ event.payload.greeting }}!"
135+
136+
- name: Greet stranger
137+
condition: 1 == 1 # default case
138+
action:
139+
debug:
140+
msg: Hello World!
141+
```
142+
143+
#### Start the EDA server
144+
145+
To start the EDA server, run the following command.
146+
147+
```console
148+
ansible-rulebook \
149+
-i hosts.yml \
150+
--rulebook rulebook.yml
151+
```
152+
153+
#### Trigger the webhook
154+
155+
Once the EDA server is running, we can open a second terminal session and double-check that it is listening on the correct port:
156+
157+
```console
158+
netstat -lntup | grep 5000
159+
```
160+
161+
Now, we can trigger the webhook from our second terminal session using `curl`, first with empty input:
162+
163+
```console
164+
curl \
165+
-H "Content-Type: application/json" \
166+
-d '{}' \
167+
http://localhost:5000/endpoint
168+
```
169+
170+
If we switch over to the first terminal session, we should see the output of the second rule, which is the default case:
171+
172+
```console
173+
Hello World!
174+
```
175+
176+
Now, we can trigger the webhook again, this time with a payload:
177+
178+
```console
179+
curl \
180+
-H "Content-Type: application/json" \
181+
-d '{"greeting": "Daniel"}' \
182+
http://localhost:5000/endpoint
183+
```
184+
185+
If we switch over to the first terminal session again, we should see the output of the first rule, which is the case for a defined `greeting` in the payload:
186+
187+
```console
188+
Hello Daniel!
189+
```
190+
191+
</details>
192+
193+
## Resources
194+
195+
- [Ansible Documentation](https://docs.ansible.com/)
196+
- [Installing Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-and-upgrading-ansible)
197+
- [Ansible Galaxy](https://galaxy.ansible.com/)
198+
- [EDA Documentation](https://ansible.readthedocs.io/projects/rulebook/en/stable/introduction.html)
199+
- [Installing and Running EDA](https://ansible.readthedocs.io/projects/rulebook/en/stable/installation.html)

0 commit comments

Comments
 (0)