You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2024/day27.md
+174-1Lines changed: 174 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -128,7 +128,7 @@ ansible \
128
128
129
129
Go on and check if the web servers are running on the respective hosts.
130
130
131
-
> [!TIP]
131
+
> [!HINT]
132
132
> Ansible is **idempotent** - try running the commands again and see how the output differs.
133
133
134
134
</details>
@@ -166,3 +166,176 @@ ansible-playbook \
166
166
```
167
167
168
168
</details>
169
+
170
+
### Lab 2: Event-Driven Ansible
171
+
172
+
<details>
173
+
174
+
<summary>Receive Generic Events via Webhook</summary>
175
+
176
+
#### Receive Generic Events via Webhook
177
+
178
+
If you followed the setup instructions for the EDA lab, you should already have a running EDA instance on the `eda-controller.example.com` VM.
179
+
180
+
If you navigate to `/etc/edacontroller/rulebook.yml` on the VM, you'll see the following rulebook:
181
+
182
+
```yaml
183
+
---
184
+
- name: Listen to webhook events
185
+
hosts: all
186
+
sources:
187
+
- ansible.eda.webhook:
188
+
host: 0.0.0.0
189
+
port: 5000
190
+
rules:
191
+
- name: Debug event output
192
+
condition: 1 == 1
193
+
action:
194
+
debug:
195
+
msg: "{{ event }}"
196
+
197
+
- name: Listen to Alertmanager alerts
198
+
hosts: all
199
+
sources:
200
+
- ansible.eda.alertmanager:
201
+
host: 0.0.0.0
202
+
port: 9000
203
+
data_alerts_path: alerts
204
+
data_host_path: labels.instance
205
+
data_path_separator: .
206
+
rules:
207
+
- name: Restart MySQL server
208
+
condition: event.alert.labels.alertname == 'MySQL not running' and event.alert.status == 'firing'
209
+
action:
210
+
run_module:
211
+
name: ansible.builtin.service
212
+
module_args:
213
+
name: mysql
214
+
state: restarted
215
+
- name: Debug event output
216
+
condition: 1 == 1
217
+
action:
218
+
debug:
219
+
msg: "{{ event }}"
220
+
221
+
```
222
+
223
+
For this part of the lab, the **first rule** is the one we're interested in: It listens to a generic webhook on port `5000` and prints the event's **metadata** to its logs.
224
+
225
+
To test this, we can use the `curl` command to send a `POST` request to the webhook `/endpoint` from the VM itself:
226
+
227
+
```console
228
+
curl \
229
+
-X POST \
230
+
-H "Content-Type: application/json" \
231
+
-d '{"foo": "bar"}' \
232
+
http://localhost:5000/endpoint
233
+
```
234
+
235
+
If you now check the logs of the EDA controller, you should see the following output:
A rule that always evaluates to `true` is not very useful, so let's change the rule to only print the the value of `foo` if the `foo` key is present in the event's payload, and `no foo :(` otherwise:
247
+
248
+
```yaml
249
+
---
250
+
- name: Listen to webhook events
251
+
hosts: all
252
+
sources:
253
+
- ansible.eda.webhook:
254
+
host: 0.0.0.0
255
+
port: 5000
256
+
rules:
257
+
- name: Foo
258
+
condition: event.payload.foo is defined
259
+
action:
260
+
debug:
261
+
msg: "{{ event.payload.foo }}"
262
+
- name: No foo
263
+
condition: 1 == 1
264
+
action:
265
+
debug:
266
+
msg: "no foo :("
267
+
```
268
+
269
+
Send the same `curl` request again and check the logs, you should see a line saying `bar` now.
270
+
271
+
Let's also try a `curl` request with a different payload:
272
+
273
+
```console
274
+
curl \
275
+
-X POST \
276
+
-H "Content-Type: application/json" \
277
+
-d '{"bar": "baz"}' \
278
+
http://localhost:5000/endpoint
279
+
```
280
+
281
+
This time, the output should be `no foo :(`.
282
+
283
+
</details>
284
+
285
+
<details>
286
+
287
+
<summary>Restarting Services Automatically with EDA</summary>
288
+
289
+
#### Restarting Services Automatically with EDA
290
+
291
+
The last lab is more of a demo - it shows how you can use EDA to automatically react on events observed by **Prometheus** and **Alertmanager**.
292
+
293
+
For this demo, the second **ruleset** in our rulebook is the one we're interested in:
294
+
295
+
```yaml
296
+
- name: Listen to Alertmanager alerts
297
+
hosts: all
298
+
sources:
299
+
- ansible.eda.alertmanager:
300
+
host: 0.0.0.0
301
+
port: 9000
302
+
data_alerts_path: alerts
303
+
data_host_path: labels.instance
304
+
data_path_separator: .
305
+
rules:
306
+
- name: Restart MySQL server
307
+
condition: event.alert.labels.alertname == 'MySQL not running' and event.alert.status == 'firing'
308
+
action:
309
+
run_playbook:
310
+
playbook: ./playbook.yml
311
+
- name: Debug event output
312
+
condition: 1 == 1
313
+
action:
314
+
debug:
315
+
msg: "{{ event }}"
316
+
```
317
+
318
+
With this rule, we can restart our MySQL server if it's not running! But how do we get the event to trigger? With **Prometheus** and **Alertmanager**!
319
+
320
+
When you ran the setup playbook, it installed **Prometheus** and **Alertmanager** on the `eda-controller.example.com` VM. You can access the **Prometheus** UI at `http://<eda-controller-ip>:9090` and the **Alertmanager** UI at `http://<eda-controller-ip>:9093`.
321
+
322
+
It also installed a **Prometheus exporter** for the **MySQL** database that runs on the server.
323
+
324
+
With this setup, we can now shut down our MySQL server and see what happens - make sure to watch the output of the EDA controller's logs:
325
+
326
+
```console
327
+
systemctl stop mysql
328
+
journalctl -fu edacontroller
329
+
```
330
+
331
+
332
+
Within 30-90 seconds, you should see EDA running our **playbook** and restarting the MySQL server. You can track that process by watching the Prometheus/Alertmanager UIs for firing alerts.
333
+
334
+
Once you see the playbook being executed in the logs, you can check the MySQL state once more:
0 commit comments