From 4ab7369601b61ab8c0950f2ef5774c97009f8638 Mon Sep 17 00:00:00 2001 From: Philippe Schmid Date: Wed, 8 Nov 2023 16:19:12 +0100 Subject: [PATCH] refactor and add eda-server lab --- content/en/docs/01/01/_index.en.md | 8 +- content/en/docs/11/01/_index.en.md | 310 +++++++++++++++++++++-------- content/en/docs/11/_index.en.md | 283 +------------------------- 3 files changed, 227 insertions(+), 374 deletions(-) diff --git a/content/en/docs/01/01/_index.en.md b/content/en/docs/01/01/_index.en.md index 6fd4c0fa..ada87fe1 100644 --- a/content/en/docs/01/01/_index.en.md +++ b/content/en/docs/01/01/_index.en.md @@ -34,7 +34,6 @@ Now we initialize the `/home/ansible/techlab` folder as a local git repository a * Create a `README.md` file with a description of your repository * Add and commit the file `README.md` with an appropriate commit message. * Don't push your changes yet -* Push your changes to the remote repository on gitea {{% details title="Solution Task 2" %}} @@ -48,17 +47,16 @@ git remote add origin gitea@-controller.workshop.puzzle.ch:ansible/tec echo "This is my Ansible Techlab repo" > README.md git add README.md git commit -m "first commit" -git push --set-upstream origin main ``` {{% /details %}} ### Task 3 -* In Task 2 of Lab 1.0 you created ssh keys for the user ansible +* In Task 2 of Lab 1.0 you created ssh keys for the user ansible on controller node * Show the content of the ssh public key -* In the Gitea GUI, navigate to the `Settin`s` of your user -* Then go to the `SSH / GPG Keys` tab of the `Settings` +* In the Gitea GUI, navigate to the `Settings` of the user `ansible` +* On the right side chose the `SSH / GPG Keys` tab * Click the `Add Key` button * Set `ansible@-controller` as `Key Name` and paste the content of your public key in the `Content` field of the GUI * Click `Add Key` diff --git a/content/en/docs/11/01/_index.en.md b/content/en/docs/11/01/_index.en.md index 78d6db66..99876d15 100644 --- a/content/en/docs/11/01/_index.en.md +++ b/content/en/docs/11/01/_index.en.md @@ -1,82 +1,143 @@ --- -title: 11.1. Event Driven Ansible - Events and Facts +title: 11.1 Event Driven Ansible - Basics weight: 111 sectionnumber: 11 --- -In this lab we will have a closer look at events and facts. +In this lab we are going to learn how to use Event Driven Ansible. For the following tasks, server `node1` and `node2` act as webservers. You can use Lab 4.0 as a guideline. ### Task 1 -* Copy the rulebook from Lab 11 Task 3 to a new one with the name `debug_event_rulebook.yml`. -* Substitute the `run_playbook` action with a `debug` action. -* That debug action should print out all information from the event. -* Stop the httpd service on node1. -* Run the rulebook in verbose mode. The debug action should show all information about the event. +* Point your webbrowser to the official documentation of `ansible-rulebook`. +* Install and configure everything needed to run ansible-rulebook and source plugins. +* Check the version of `ansible-rulebook` {{% details title="Solution Task 1" %}} + +[https://ansible-rulebook.readthedocs.io/en/stable/index.html](https://ansible-rulebook.readthedocs.io/en/stable/index.html) + +Fedora 36+: ```bash -cat debug_event_rulebook.yml +sudo dnf --assumeyes install java-17-openjdk python3-pip +export JAVA_HOME=/usr/lib/jvm/jre-17-openjdk +pip install ansible ansible-rulebook +ansible-galaxy collection install ansible.eda +``` + +Enterprise Linux 9: +```bash +sudo dnf install java-17-openjdk +export JAVA_HOME=/usr/lib/jvm/jre-17-openjdk +sudo dnf install python3-pip +python3 -m venv ~/python +. ~/python/bin/activate +pip install --upgrade pip +pip install ansible ansible-rulebook + +ansible-galaxy collection install ansible.eda + +sudo dnf install systemd-devel gcc python3-devel + +pip install -r ~/.ansible/collections/ansible_collections/ansible/eda/requirements.txt +``` + +```bash +ansible-rulebook --version +``` +Output on EL9: +```bash +version__ = '1.0.0' +Executable location = /home/ansible/python/bin/ansible-rulebook +Drools_jpy version = 0.3.4 +Java home = /usr/lib/jvm/java-17-openjdk-17.0.7.0.7-3.el9.x86_64 +Java version = 17.0.7 +Python version = 3.9.16 (main, Dec 8 2022, 00:00:00) [GCC 11.3.1 20221121 (Red Hat 11.3.1-4)] +``` +{{% /details %}} + +### Task 2 + +* Write a playbook `webserver.yml` that installs the servers in group `web` as webservers. See Lab 4.0 for guidelines. +* Ensure that the playbook also sets a webpage at `/var/www/html/index.html`. +* Ensure that the inventory file `hosts` in the folder inventory has the group `web` with `node1` and `node2` as members. +* Run the playbook `webserver.yml` and check that the webservers are up and running. + +{{% details title="Solution Task 2" %}} + +```bash +cat webserver.yml ``` ```bash --- -- name: show event json if site down - hosts: web - sources: - - name: check webserver - ansible.eda.url_check: - urls: - - http://:80/ - - http://:80/ - delay: 8 - rules: - - name: check if site down and debug - condition: event.url_check.status == "down" - action: - debug: - var: event +- hosts: web + become: true + tasks: + - name: install httpd + ansible.builtin.dnf: + name: + - httpd + - firewalld + state: installed + - name: start and enable httpd + ansible.builtin.service: + name: httpd + state: started + enabled: yes + - name: put default webpage + ansible.builtin.copy: + content: "Ansible Labs by Puzzle ITC" + dest: /var/www/html/index.html + owner: root + group: root + - name: start and enable firewalld + ansible.builtin.service: + name: firewalld + state: started + enabled: yes + - name: open firewall for http + firewalld: + service: http + state: enabled + permanent: yes + immediate: yes ``` ```bash -ansible node1 -i inventory/hosts -b -m service -a "name=httpd state=stopped" +cat inventory/hosts ``` ```bash -ansible-rulebook --rulebook debug_event_rulebook.yml -i inventory/hosts -vv +[controller] +control0 ansible_host= + +[web] +node1 ansible_host= +node2 ansible_host= ``` ```bash -... -2023-06-26 15:04:55,381 - ansible_rulebook.rule_set_runner - INFO - call_action debug -2023-06-26 15:04:55,381 - ansible_rulebook.rule_set_runner - INFO - substitute_variables [{'var': 'event'}] [{'event': {'url_check': {'error_msg': "Cannot connect to host 5.102.146.223:80 ssl:default [Connect call failed ('5.102.146.223', 80)]", 'url': 'http://5.102.146.223/', 'status': 'down'}, 'meta': {'received_at': '2023-06-26T13:04:55.379428Z', 'source': {'name': 'check webserver', 'type': 'ansible.eda.url_check'}, 'uuid': '6710f9a8-c489-4699-a804-8e796855e290'}}}] -2023-06-26 15:04:55,381 - ansible_rulebook.rule_set_runner - INFO - action args: {'var': 'event'} -{'url_check': {'error_msg': "Cannot connect to host 5.102.146.223:80 ssl:default [Connect call failed ('5.102.146.223', 80)]", 'url': 'http://5.102.146.223/', 'status': 'down'}, 'meta': {'received_at': '2023-06-26T13:04:55.379428Z', 'source': {'name': 'check webserver', 'type': 'ansible.eda.url_check'}, 'uuid': '6710f9a8-c489-4699-a804-8e796855e290'}} -... +ansible-playbook -i inventory/hosts webserver.yml +sudo dnf install -y lynx +lynx http:// +lynx http:// ``` {{% /details %}} -### Task 2 - -* Rewrite the rulebook `debug_event_rulebook.yml`: -* Use a `run_playbook` action to start a playbook named `sos.yml` -* The playbook `sos.yml` should create an unattended sos report labeled with the fully qualified collection name of the source plugin used. Be sure to install the appropriate packages so that the sos report can be created. -* The name of the source plugin should be taken from the json output as a variable. -* The creation of the sos report takes quite some time. -* Ensure that the condition is throttled to run the action once within 5 minutes at most. -* The delay of the source check should stay at 8 seconds. -* Run the rulebook `debug_event_rulebook.yml` and ensure the sos reports on the webservers have the needed label. +### Task 3 +* Write a rulebook `webserver_rulebook.yml` that checks if the webpages on `node1` and `node2` are up and running. +* If the webpages are not available anymore, the `webserver.yml` playbook should be re-run. +* Use `url_check` from the `ansible.eda` collection as the source plugin in your rulebook. +* Check the availability of the websites every 8 seconds. {{% alert title="Note" color="primary" %}} -There are good onlinetools to convert [one-line json to multiline json](https://jsonformatter.curiousconcept.com) as well as [json to yaml converters](https://jsonformatter.org/json-to-yaml). Note: The json copied from the output has sometimes single quotes, RFC 8259 demands double quotes. Be sure that your converter fixes this as well. These converters can come in handy for easier reading of the output. +If you don't have the `ansible.eda` collection installed yet, `ansible-rulebook` would start, but fail because the `url_check` source plugin cannot be found. {{% /alert %}} -{{% details title="Solution Task 2" %}} -See the documentation on how to [throttle event storms](https://ansible.readthedocs.io/projects/rulebook/en/stable/conditions.html#throttle-actions-to-counter-event-storms-reactive). - +{{% details title="Solution Task 3" %}} ```bash -cat debug_event_rulebook.yml +cat webserver_rulebook.yml ``` ```bash --- -- name: run sos playbook if site down +- name: rebuild webservers if site down hosts: web sources: - name: check webserver @@ -88,65 +149,140 @@ cat debug_event_rulebook.yml rules: - name: check if site down and rebuild condition: event.url_check.status == "down" - throttle: - once_within: 5 minutes - group_by_attributes: - - event.meta.source.type action: run_playbook: - name: sos.yml + name: webserver.yml ``` +{{% /details %}} +### Task 4 + +* Start `webserver_rulebook.yml` in verbose mode. +* Stop the httpd service on `node1` with ansible from another terminal on `control0` and see how the playbook `webserver.yml` is re-run. (You could also just stop the service directly on `node1`.) + +{{% details title="Solution Task 4" %}} ```bash -cat sos.yml +ansible-rulebook --rulebook webserver_rulebook.yml -i inventory/hosts --verbose + +ansible node1 -i inventory/hosts -b -m service -a "name=httpd state=stopped" ``` +{{% /details %}} + + +### Task 5 + +* Write the rulebook `webhook_rulebook.yml` that opens a webhook on port 5000 of the control node `control0`. +* The rulebook should re-run the playbook `webserver.yml` if the webhook receives a message matching exactly the string "webservers down". +* Use `webhook` from the `ansible.eda` collection as the source plugin in your rulebook. + +{{% details title="Solution Task 5" %}} ```bash +cat webhook_rulebook.yml +``` +```yaml --- -- hosts: web - become: true - tasks: - - name: install sos package - ansible.builtin.dnf: - name: - - sos - state: installed - - - name: create a sos report unattended containing no sensitive information - ansible.builtin.command: | - "sos report --clean --batch --label {{ ansible_eda.event.meta.source.type }}" +- name: rebuild webserver if webhook receives message that matches rule condition + hosts: web + sources: + - name: start webhook and listen for messages + ansible.eda.webhook: + host: 0.0.0.0 + port: 5000 + rules: + - name: rebuild webserver if monitoring tool sends alert + condition: event.payload.message == "webservers down" + action: + run_playbook: + name: webserver.yml ``` +{{% /details %}} + +### Task 6 +* Run the rulebook `webhook_rulebook.yml` in verbose mode. +* Send the string "webservers running" to the webhook. +* You can do this by issuing: `curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers running\"}" 127.0.0.1:5000/endpoint` +* See how the message is received, processed, but no actions are taken since the message doesn't match the condition defined. +* Now send the message "webservers down" to the webhook. See how the playbook `webserver.yml` is run. + +{{% details title="Solution Task 6" %}} +```bash +ansible-rulebook --rulebook webhook_rulebook.yml -i inventory/hosts --verbose +``` ```bash -ansible-rulebook --rulebook debug_event_rulebook.yml -i inventory/hosts -vv +curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers running\"}" 127.0.0.1:5000/endpoint ``` ```bash -... -2023-06-28 11:15:53,766 - ansible_rulebook.builtin - INFO - ruleset: show event \ - json if site down, rule: check if site down and rebuild -2023-06-28 11:15:53,766 - ansible_rulebook.builtin - INFO - Calling Ansible runner +curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers down\"}" 127.0.0.1:5000/endpoint +``` +{{% /details %}} + +### Task 7 -PLAY [web] ********************************************************************* +* Write the rulebook `complex_rulebook.yml`. It has to meet the following requirements: +* It should check for three things: + * check if the website on one of the two webservers is down. (Same as Task 3 above) + * check if the message matches exactly the string "webservers down" (Same as Task 5 above) + * check if the message contains the string "ERROR" or "error" +* If one of the criterias above are met, do two things: + 1. run the ansible shell module to print the string "WEBSERVER ISSUES, REMEDIATION IN PROGRESS." into the journald log. (Use the command `systemd-cat echo "WEBSERVER ISSUES, REMEDIATION IN PROGRESS."`) + 2. run playbook `webservers.yml` +* Start the rulebook `complex_rulebook.yml` and send the message "webservers down" to the webhook again. -TASK [Gathering Facts] ********************************************************* -ok: [node1] +{{% details title="Solution Task 7" %}} -TASK [install sos package] ***************************************************** -ok: [node1] +```bash +cat complex_rulebook.yml +``` +```bash +--- +- name: rebuild webserver if webhook receives message that matches rule condition + hosts: web + sources: + - name: check webserver + ansible.eda.url_check: + urls: + - http://:80/ + - http://:80/ + delay: 8 + - name: start webhook and listen for messages + ansible.eda.webhook: + host: 0.0.0.0 + port: 5000 + rules: + - name: rebuild webserver if any source reports an alert + condition: + any: + - event.url_check.status == "down" + - event.payload.message == "webservers down" + - event.payload.message is search("ERROR",ignorecase=true) + actions: + - run_module: + name: ansible.builtin.shell + module_args: + cmd: "systemd-cat echo \"WEBSERVER ISSUES, REMEDIATION IN PROGRESS.\"" + - run_playbook: + name: webserver.yml +``` -TASK [create a sos report unattended containing no sensitive information] ****** -changed: [node1] -... -PLAY RECAP ********************************************************************* -node1 : ok=3 changed=1 unreachable=0 failed=0 -skipped=0 rescued=0 ignored=0 -2023-06-28 11:17:59,741 - ansible_rulebook.builtin - INFO - Ansible Runner \ - Queue task cancelled -2023-06-28 11:17:59,742 - ansible_rulebook.builtin - INFO - Playbook rc: 0, \ - status: successful -... +```bash +ansible-rulebook --rulebook complex_rulebook.yml -i inventory/hosts --verbose ``` +```bash +curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers down\"}" 127.0.0.1:5000/endpoint +``` +Note, that you would have to open port 5000 on the firewall if the curl command is not sent from the controller itself. +{{% /details %}} + +### Task 8 + +* What source plugins are available in the `ansible.eda` collection? [Search the content of event-driven-ansible on github.com](https://github.com/ansible/event-driven-ansible). + +{{% details title="Solution Task 8" %}} +[Event Driven Ansible on Github](https://github.com/ansible/event-driven-ansible/tree/main/extensions/eda/plugins/event_source) {{% /details %}} ### All done? -* [Preview of AAP EDA-Controller GUI](https://www.youtube.com/watch?v=7i_EzHyrKQc&t=178s) +* [Ansible-rulebook documentation](https://ansible-rulebook.readthedocs.io/en/stable/) +* [AnsibleAutomates Youtube channel for more examples](https://www.youtube.com/@AnsibleAutomation/videos) diff --git a/content/en/docs/11/_index.en.md b/content/en/docs/11/_index.en.md index e1278c37..28a19281 100644 --- a/content/en/docs/11/_index.en.md +++ b/content/en/docs/11/_index.en.md @@ -4,285 +4,4 @@ weight: 110 sectionnumber: 11 --- -In this lab we are going to learn how to use Event Driven Ansible. For the following tasks, server `node1` and `node2` act as webservers. You can use Lab 4.0 as a guideline. - -### Task 1 - -* Point your webbrowser to the official documentation of `ansible-rulebook`. -* Install and configure everything needed to run ansible-rulebook and source plugins. -* Check the version of `ansible-rulebook` - -{{% details title="Solution Task 1" %}} - -[https://ansible-rulebook.readthedocs.io/en/stable/index.html](https://ansible-rulebook.readthedocs.io/en/stable/index.html) - -Fedora 36+: -```bash -sudo dnf --assumeyes install java-17-openjdk python3-pip -export JAVA_HOME=/usr/lib/jvm/jre-17-openjdk -pip install ansible ansible-rulebook -ansible-galaxy collection install ansible.eda -``` - -Enterprise Linux 9: -```bash -sudo dnf install java-17-openjdk -export JAVA_HOME=/usr/lib/jvm/jre-17-openjdk -sudo dnf install python3-pip -python3 -m venv ~/python -. ~/python/bin/activate -pip install --upgrade pip -pip install ansible ansible-rulebook - -ansible-galaxy collection install ansible.eda - -sudo dnf install systemd-devel gcc python3-devel - -pip install -r ~/.ansible/collections/ansible_collections/ansible/eda/requirements.txt -``` - -```bash -ansible-rulebook --version -``` -Output on EL9: -```bash -version__ = '1.0.0' -Executable location = /home/ansible/python/bin/ansible-rulebook -Drools_jpy version = 0.3.4 -Java home = /usr/lib/jvm/java-17-openjdk-17.0.7.0.7-3.el9.x86_64 -Java version = 17.0.7 -Python version = 3.9.16 (main, Dec 8 2022, 00:00:00) [GCC 11.3.1 20221121 (Red Hat 11.3.1-4)] -``` -{{% /details %}} - -### Task 2 - -* Write a playbook `webserver.yml` that installs the servers in group `web` as webservers. See Lab 4.0 for guidelines. -* Ensure that the playbook also sets a webpage at `/var/www/html/index.html`. -* Ensure that the inventory file `hosts` in the folder inventory has the group `web` with `node1` and `node2` as members. -* Run the playbook `webserver.yml` and check that the webservers are up and running. - -{{% details title="Solution Task 2" %}} - -```bash -cat webserver.yml -``` -```bash ---- -- hosts: web - become: true - tasks: - - name: install httpd - ansible.builtin.dnf: - name: - - httpd - - firewalld - state: installed - - name: start and enable httpd - ansible.builtin.service: - name: httpd - state: started - enabled: yes - - name: put default webpage - ansible.builtin.copy: - content: "Ansible Labs by Puzzle ITC" - dest: /var/www/html/index.html - owner: root - group: root - - name: start and enable firewalld - ansible.builtin.service: - name: firewalld - state: started - enabled: yes - - name: open firewall for http - firewalld: - service: http - state: enabled - permanent: yes - immediate: yes -``` -```bash -cat inventory/hosts -``` -```bash -[controller] -control0 ansible_host= - -[web] -node1 ansible_host= -node2 ansible_host= -``` -```bash -ansible-playbook -i inventory/hosts webserver.yml -sudo dnf install -y lynx -lynx http:// -lynx http:// -``` -{{% /details %}} - -### Task 3 - -* Write a rulebook `webserver_rulebook.yml` that checks if the webpages on `node1` and `node2` are up and running. -* If the webpages are not available anymore, the `webserver.yml` playbook should be re-run. -* Use `url_check` from the `ansible.eda` collection as the source plugin in your rulebook. -* Check the availability of the websites every 8 seconds. - -{{% alert title="Note" color="primary" %}} -If you don't have the `ansible.eda` collection installed yet, `ansible-rulebook` would start, but fail because the `url_check` source plugin cannot be found. -{{% /alert %}} - -{{% details title="Solution Task 3" %}} -```bash -cat webserver_rulebook.yml -``` -```bash ---- -- name: rebuild webservers if site down - hosts: web - sources: - - name: check webserver - ansible.eda.url_check: - urls: - - http://:80/ - - http://:80/ - delay: 8 - rules: - - name: check if site down and rebuild - condition: event.url_check.status == "down" - action: - run_playbook: - name: webserver.yml -``` -{{% /details %}} - -### Task 4 - -* Start `webserver_rulebook.yml` in verbose mode. -* Stop the httpd service on `node1` with ansible from another terminal on `control0` and see how the playbook `webserver.yml` is re-run. (You could also just stop the service directly on `node1`.) - -{{% details title="Solution Task 4" %}} -```bash -ansible-rulebook --rulebook webserver_rulebook.yml -i inventory/hosts --verbose - -ansible node1 -i inventory/hosts -b -m service -a "name=httpd state=stopped" -``` -{{% /details %}} - - -### Task 5 - -* Write the rulebook `webhook_rulebook.yml` that opens a webhook on port 5000 of the control node `control0`. -* The rulebook should re-run the playbook `webserver.yml` if the webhook receives a message matching exactly the string "webservers down". -* Use `webhook` from the `ansible.eda` collection as the source plugin in your rulebook. - -{{% details title="Solution Task 5" %}} -```bash -cat webhook_rulebook.yml -``` -```yaml ---- -- name: rebuild webserver if webhook receives message that matches rule condition - hosts: web - sources: - - name: start webhook and listen for messages - ansible.eda.webhook: - host: 0.0.0.0 - port: 5000 - rules: - - name: rebuild webserver if monitoring tool sends alert - condition: event.payload.message == "webservers down" - action: - run_playbook: - name: webserver.yml -``` -{{% /details %}} - -### Task 6 - -* Run the rulebook `webhook_rulebook.yml` in verbose mode. -* Send the string "webservers running" to the webhook. -* You can do this by issuing: `curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers running\"}" 127.0.0.1:5000/endpoint` -* See how the message is received, processed, but no actions are taken since the message doesn't match the condition defined. -* Now send the message "webservers down" to the webhook. See how the playbook `webserver.yml` is run. - -{{% details title="Solution Task 6" %}} -```bash -ansible-rulebook --rulebook webhook_rulebook.yml -i inventory/hosts --verbose -``` -```bash -curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers running\"}" 127.0.0.1:5000/endpoint -``` -```bash -curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers down\"}" 127.0.0.1:5000/endpoint -``` -{{% /details %}} - -### Task 7 - -* Write the rulebook `complex_rulebook.yml`. It has to meet the following requirements: -* It should check for three things: - * check if the website on one of the two webservers is down. (Same as Task 3 above) - * check if the message matches exactly the string "webservers down" (Same as Task 5 above) - * check if the message contains the string "ERROR" or "error" -* If one of the criterias above are met, do two things: - 1. run the ansible shell module to print the string "WEBSERVER ISSUES, REMEDIATION IN PROGRESS." into the journald log. (Use the command `systemd-cat echo "WEBSERVER ISSUES, REMEDIATION IN PROGRESS."`) - 2. run playbook `webservers.yml` -* Start the rulebook `complex_rulebook.yml` and send the message "webservers down" to the webhook again. - -{{% details title="Solution Task 7" %}} - -```bash -cat complex_rulebook.yml -``` -```bash ---- -- name: rebuild webserver if webhook receives message that matches rule condition - hosts: web - sources: - - name: check webserver - ansible.eda.url_check: - urls: - - http://:80/ - - http://:80/ - delay: 8 - - name: start webhook and listen for messages - ansible.eda.webhook: - host: 0.0.0.0 - port: 5000 - rules: - - name: rebuild webserver if any source reports an alert - condition: - any: - - event.url_check.status == "down" - - event.payload.message == "webservers down" - - event.payload.message is search("ERROR",ignorecase=true) - actions: - - run_module: - name: ansible.builtin.shell - module_args: - cmd: "systemd-cat echo \"WEBSERVER ISSUES, REMEDIATION IN PROGRESS.\"" - - run_playbook: - name: webserver.yml -``` - -```bash -ansible-rulebook --rulebook complex_rulebook.yml -i inventory/hosts --verbose -``` -```bash -curl -H 'Content-Type: application/json' -d "{\"message\": \"webservers down\"}" 127.0.0.1:5000/endpoint -``` -Note, that you would have to open port 5000 on the firewall if the curl command is not sent from the controller itself. -{{% /details %}} - -### Task 8 - -* What source plugins are available in the `ansible.eda` collection? [Search the content of event-driven-ansible on github.com](https://github.com/ansible/event-driven-ansible). - -{{% details title="Solution Task 8" %}} -[Event Driven Ansible on Github](https://github.com/ansible/event-driven-ansible/tree/main/extensions/eda/plugins/event_source) -{{% /details %}} - -### All done? - -* [Ansible-rulebook documentation](https://ansible-rulebook.readthedocs.io/en/stable/) -* [AnsibleAutomates Youtube channel for more examples](https://www.youtube.com/@AnsibleAutomation/videos) +In this lab we are going to learn how to use Event Driven Ansible.