yourlabs.remember
yourlabs.remember
`````````````````
Ansible自动化架构师的元角色。
这个角色为智能化Ansible角色工作流提供了魔力:
- 极大加速:只需一次且仅需一次依赖角色
- 无库存干燥:记住从CLI注入的主机变量
- CLI变量提示:与用户互动提问以获取信息
.. 注意:: 这个角色不会自动下载依赖角色:这
是 bigsudo <https://pypi.org/project/bigsudo/>
_ 命令的工作。
演示
体验它的最简单方式::
pip install --user bigsudo ~/.local/bin/bigsudo yourlabs.fqdn user@somehost
或者如果你敢于尝试(跳过主机名以在本地主机上应用)
~/.local/bin/bigsudo yourlabs.traefik
当然你也可以使用 ansible
命令,但这样会需要更多的命令和选项。我们受到 kubectl 这个实践的启发,适用于小型服务器、非HA服务和披萨团队。即使如此,如果我必须配置k8s实例,我个人仍然会使用 bigsudo yourlabs.k8s
...
用法
这个角色允许你定义在自己的角色中所需的变量,以及将向用户显示的描述、默认值、正则表达式验证等等。
OAOO角色依赖注入
我以 yourlabs.traefik
(一个基于Docker的负载均衡器)为例,它依赖于 yourlabs.docker
,后者仅安装Docker。
然而,为了举例,我将使用 your.parent
和 your.child
来分别表示 yourlabs.docker
和 yourlabs.traefik
的使用情况。
在 your.child/requirements.yml
中::
- your.parent
在 your.parent/requirements.yml
中::
- yourlabs.remember
因此,your.child
依赖于 your.parent
,而 your.parent
依赖于 yourlabs.remember
。
.. 注意:: bigsudo 确保在你运行 bigsudo your.child
时递归安装依赖。
没有 remember
角色时,你通常会在 your.child/tasks/main.yml
的顶部这样包含 your.parent
角色::
- name: 在运行我们的任务之前安装 your.parent include_role: name=your.parent
然而,这将使得每次执行时都需要重复执行此角色,从而增加执行时间。如果你不想每次执行 your.child
时都等待 your.parent
完全执行,你可以在 your.child/tasks/main.yml
顶部将上述任务转换如下:
.. code-block:: yaml
- name: 如果从未在此主机上完成,安装 your.parent include_role: name=your.parent when: ansible_facts['ansible_local']['your_parent']['state']|default('') != 'success'
为了使其工作,你需要在 your.parent/tasks/main.yml
的末尾添加以下内容:
.. code-block:: yaml
- include_role: name=yourlabs.remember tasks_from=success
这样,运行 bigsudo your.parent
(也适用于ansible)将会创建 /etc/ansible/facts.d/your_parent.fact
,内容如下::
#!/bin/sh echo '{ "state": "success" }'
这就是你可以跳过下次包含该角色的方法。
继续阅读,以交互式配置添加自定义持久角色变量。
交互式角色配置
在 your.parent/vars/main.yml
中,定义 remember_fact
,这是此角色部署变量的命名空间,以及此角色依赖的变量,如下所示::
remember_fact: your_parent remember:
- name: email_enable question: 启用自定义电子邮件? default: false type: bool
- name: email question: 使用什么电子邮件? type: email default: '{{ lookup("env", "USER") }}@{{ inventory_hostname }}' when: email_enable
然后,在 your.parent/tasks/main.yml
中,你可以包括 yourlabs.remember
,它将加载变量并快速与用户互动询问新变量,这得益于动作插件::
- include_role: name=yourlabs.remember
你可以做更多,当然可以参考 test.yml
的剧本,我用 ansible-playbook -c local -i localhost, test.yml -v --become
运行:
.. include:: test.yml
多个部署:变量命名空间
为了在同一主机上启用角色的多个部署,即启用 极限DevOps,你需要你的 remember_fact
依赖于一个变量。
例如,你想在主机上的不同目录中部署docker-compose。因此,你需要一个 home
变量:
.. code-block:: yaml
remember:
- name: home
question: 要部署到哪个主目录?(必须以 /home 开头,以便使用正则表达式示例)
default: /home/test
type: path
regexp: /home.*
这意味着如果用户没有在命令行上传递 home
变量(例如,使用 -e home=/home/bar
),它将提示输入主目录。现在,我们所要做的就是将此home变量重新用于 remember_fact
,以便根据主目录命名变量:
.. code-block:: yaml
remember_fact: your_role_j2((home))
如你所见,我们在使用 j2(( ))
而不是 {{ }}
,这是为了防止Ansible在获取home变量的值之前就渲染它。实际上,remember动作插件将会:
- 尝试渲染
remember_fact
来加载现有变量(如果有), - 捕获
AnsibleUndefinedVariable
异常, - 找到需要的未定义变量的定义在
remember
中, - 在不保存的情况下进行询问
- 加载现有变量
- 并询问任何新变量
结论
最终,我们达到了一个明确且相对简单的方式来:
- 动态注入 依赖角色,以加速角色的后续执行,有效防止不必要的双重执行依赖角色(如Docker、负载均衡器、底层自动化...)
- 抑制库存,因为每个服务器保留自己的变量,顺便提一句,这样也减少了一份你需要担心的代码库!
- 交互式事实提示,不再需要在执行你在互联网找到的角色之前阅读文档!
感谢
感谢来自 beta.gouv.fr
的 totakoko,感谢他进行的长时间讨论,并向我展示我的库存过于复杂,而实现这一切是可能的 ;)
感谢 #ansible
@irc.freenode.net
,这是最好的IRC频道之一,特别感谢:
- agaffney
- mackerman
- jborean93
也感谢 你 阅读我的小冒险故事!