入门

如果 ansible-rulebook 尚未安装,请按照 安装指南 进行安装。

现在让我们从一个简单的 hello world 示例开始,熟悉相关概念。

---
- name: Hello Events
  hosts: localhost
  sources:
    - ansible.eda.range:
        limit: 5
  rules:
    - name: Say Hello
      condition: event.i == 1
      action:
        run_playbook:
          name: ansible.eda.hello

事件来自事件源,然后根据规则进行检查以确定是否应该采取操作。如果规则的条件与事件匹配,它将运行该规则的操作。

在这个示例中,事件源是 Python range 函数。它生成从 i=0i=<limit> 的事件。

i 等于 1 时,Say Hello 规则的条件匹配,它将运行一个剧本。

通常,事件来自监控和告警系统或其他软件。以下是一个更完整的示例,它接受来自 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 的事件。这将运行一个剧本来修复问题。

让我们构建一个示例规则手册,它将从 webhook 触发操作。我们将寻找 webhook 的特定有效负载,如果 webhook 事件满足该条件,那么 ansible-rulebook 将触发所需的操作。以下是我们的示例规则手册

---
- name: Listen for events on a webhook
  hosts: all

  ## Define our source for events

  sources:
    - ansible.eda.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

剧本 say-what.yml

- hosts: localhost
  connection: local
  tasks:
    - debug:
        msg: "Thank you, my friend!"

如果我们看一下这个示例,我们可以看到规则手册的结构。我们的来源、规则和操作都被定义了。我们使用的是 ansible.eda 集合中的 webhook 源插件,并且我们正在寻找来自 webhook 的包含“Ansible is super cool”的消息有效负载。一旦满足该条件,我们定义的操作将被触发,在本例中,它将触发一个剧本。

需要注意的是,ansible-rulebook 与 ansible-playbook 不同,ansible-playbook 会运行一个剧本,一旦剧本完成,它就会退出。对于 ansible-rulebook 来说,它会继续运行,等待事件并匹配这些事件,它只会响应关闭操作或事件源本身出现问题(例如,如果使用 url-check 插件监视的网站停止工作)时才会退出。

构建好规则手册后,我们只需告诉 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 ansible.eda.webhook

现在,ansible-rulebook 已准备就绪,它正在等待匹配的事件。如果 webhook 被触发,但有效负载与规则中的条件不匹配,我们可以在 ansible-rulebook 的详细输出中看到它。

…
INFO:root:Calling main in ansible.eda.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 ansible.eda.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 然后触发了我们的操作,即运行剧本。我们定义的剧本随后被触发,一旦它完成,我们可以看到我们恢复到“正在等待事件”。

事件驱动的 Ansible 为更快地解决问题以及对我们的环境进行更深入的自动化观察开辟了可能性。它有可能简化许多技术和睡眠不足的工程师的生活。

附加

视频: 编写规则手册