入门指南
如果尚未安装 ansible-rulebook,请参考 安装指南 进行安装。
Hello world!
现在,让我们通过一个简单的 hello world 示例来熟悉相关概念。请将以下内容保存到 simple-rulebook.yml 文件中
---
- name: Hello Events
hosts: localhost
sources:
- eda.builtin.range:
limit: 5
rules:
- name: Say Hello
condition: event.i == 1
action:
run_playbook:
name: ansible.eda.hello
事件来自事件源 (event source),然后根据规则 (rules) 进行检查,以确定是否应采取操作 (action)。如果规则的条件 (condition) 与事件匹配,它将运行该规则对应的操作。
在本例中,事件源 (eda.builtin.range) 是 Python 的 range 函数。它会产生从 i=0 到 i=<limit> 的计数事件。
当 i 等于 1 时,Say Hello 规则的条件匹配,随后它将运行 ansible.eda 集合中提供的简单 hello playbook。
现在您可以运行该 rulebook 以查看结果
$ ansible-rulebook -i inventory.yml -r simple-rulebook.yml
PLAY [hello] *******************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "hello"
}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Webhook 示例
通常,事件来自监控和告警系统或其他软件。以下是一个更完整的示例,它可以接收来自 Alertmanager 的告警
---
- name: Automatic Remediation of a webserver
hosts: all
sources:
- name: listen for alerts
ansible.eda.alertmanager:
host: 0.0.0.0
port: 8000
rules:
- name: restart web server
condition: event.alert.labels.job == "fastapi" and event.alert.status == "firing"
action:
run_playbook:
name: ansible.eda.start_app
...
此示例设置了一个 webhook 以接收来自 alertmanager 的事件,然后匹配 fastapi 作业告警状态为 firing 的事件。这将运行一个用于修复该问题的 playbook。
让我们构建一个通过 webhook 触发操作的示例 rulebook。我们将寻找来自 webhook 的特定有效载荷 (payload),如果 webhook 事件满足该条件,那么 ansible-rulebook 将触发所需的操作。以下是我们的示例 rulebook webhook-example.yml
---
- name: Listen for events on a webhook
hosts: all
## Define our source for events
sources:
- eda.builtin.webhook:
host: 0.0.0.0
port: 5000
## Define the conditions we are looking for
rules:
- name: Say Hello
condition: event.payload.message == "Ansible is super cool"
## Define the action we should take should the condition be met
action:
run_playbook:
name: say-what.yml
Playbook say-what.yml
- hosts: localhost
connection: local
tasks:
- debug:
msg: "Thank you, my friend!"
观察这个示例,我们可以看到 rulebook 的结构。其中定义了源 (sources)、规则 (rules) 和操作 (actions)。我们使用了 ansible.eda 集合中的 webhook 源插件,并寻找包含 “Ansible is super cool” 的 webhook 消息有效载荷。一旦满足此条件,将触发我们定义的操作,在本例中即触发一个 playbook。
关于 ansible-rulebook 有一点需要特别注意:它不同于 ansible-playbook(后者运行 playbook 并在完成后退出)。ansible-rulebook 会持续运行,等待事件并进行匹配;它仅在执行关闭操作或事件源本身出现问题时才会退出(例如,您使用 ansible.eda.url-check 插件监控的网站停止工作)。
rulebook 构建完成后,我们只需告知 ansible-rulebook 将其作为规则集使用并等待事件
root@ansible-rulebook:/root# ansible-rulebook --rulebook webhook-example.yml -i inventory.yml --verbose
INFO:ansible_events:Starting sources
INFO:ansible_events:Starting sources
INFO:ansible_events:Starting rules
INFO:root:run_ruleset
INFO:root:{'all': [{'m': {'payload.message': 'Ansible is super cool!'}}], 'run': <function make_fn.<locals>.fn at 0x7ff962418040>}
INFO:root:Waiting for event
INFO:root:load source
INFO:root:load source filters
INFO:root:Calling main in eda.builtin.webhook
现在,ansible-rulebook 已准备就绪,正在等待匹配事件。如果触发了 webhook 但有效载荷不符合规则中的条件,我们可以在 ansible-rulebook 的详细 (verbose) 输出中看到该过程
…
INFO:root:Calling main in eda.builtin.webhook
INFO:aiohttp.access:127.0.0.1 [14/Oct/2022:09:49:32 +0000] "POST /endpoint HTTP/1.1" 200 158 "-" "curl/7.61.1"
INFO:root:Waiting for event
但一旦有效载荷与我们要寻找的内容匹配,神奇的事情就发生了,因此我们将使用正确的有效载荷来模拟一个 webhook
curl -H 'Content-Type: application/json' -d "{\"message\": \"Ansible is super cool\"}" 127.0.0.1:5000/endpoint
INFO:root:Calling main in eda.builtin.webhook
INFO:aiohttp.access:127.0.0.1 [14/Oct/2022:09:50:28 +0000] "POST /endpoint HTTP/1.1" 200 158 "-" "curl/7.61.1"
INFO:root:calling Say Hello
INFO:root:call_action run_playbook
INFO:root:substitute_variables [{'name': 'say-what.yml'}] [{'event': {'payload': {'message': 'Ansible is super cool'}, 'meta': {'endpoint': 'endpoint', 'headers': {'Host': '127.0.0.1:5000', 'User-Agent': 'curl/7.61.1', 'Accept': '*/*', 'Content-Type': 'application/json', 'Content-Length': '36'}}}, 'fact': {'payload': {'message': 'Ansible is super cool'}, 'meta': {'endpoint': 'endpoint', 'headers': {'Host': '127.0.0.1:5000', 'User-Agent': 'curl/7.61.1', 'Accept': '*/*', 'Content-Type': 'application/json', 'Content-Length': '36'}}}}]
INFO:root:action args: {'name': 'say-what.yml'}
INFO:root:running Ansible playbook: say-what.yml
INFO:root:Calling Ansible runner
PLAY [say thanks] **************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Thank you, my friend!"
}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
INFO:root:Waiting for event
从上述输出可以看到,webhook 满足了条件,随后 ansible-rulebook 触发了我们的操作 run_playbook。我们定义的 playbook 被触发执行,在执行完成后,我们可以看到状态恢复到 “Waiting for event”。
事件驱动型 Ansible (Event-Driven Ansible) 为更快速的故障解决和更强大的环境自动化观测开辟了可能性。它有可能简化许多技术人员以及那些睡眠不足的工程师们的生活。
附加内容
视频:编写 Rulebooks