如何为角色指定 Ansible pretasks?

64

如何定义前置任务以满足角色依赖关系。 我目前有一个apache角色,其中有一个用户变量,因此在我的角色中,在<role>/meta/main.yml文件中,我会做类似以下的事情:

---
dependencies:
  - { role: apache, user: proxy }

目前的问题是我仍然没有指定的用户,当角色尝试在不存在的用户下启动 apache 服务器时,会出现错误。

我尝试在<role>/tasks/main.yml中创建一个任务:

---
- user: name=proxy

然而,仅在运行依赖项中的apache任务后才会创建用户(这是可以预期的)。因此,是否有一种方法可以创建一个任务,在运行依赖项中的角色之前创建用户?


你能发布完整的playbook以及你的自定义角色吗? - Kashyap
你是不是把 - user: name=proxy 放在了 <role>/tasks/main.yml 文件的 pre_tasks: 或者 tasks 中了? - Kashyap
实际上,除了上面一行的---部分和下面- user: name=proxy之外,这就是我拥有的整个文件。我已经编辑了内容,以使我的文件看起来更清晰,但除了apache角色之外,我现在几乎没有别的了。 - Kęstutis
6个回答

67

我使用pre_tasks在执行角色之前完成一些任务,感谢Kashyap

#!/usr/bin/env ansible-playbook

---
- hosts: all
  become: true
  pre_tasks:
    - name: start tasks and sent notifiaction to HipChat
      hipchat:
        color: purple
        token: "{{ hipchat_token }}"
        room: "{{ hipchat_room }}"
        msg: "[Start] Run 'foo/setup.yml' playbook on {{ ansible_nodename }}."

  roles:
    - chusiang.vim-and-vi-mode

  vars:
    ...

  tasks:
    - name: include main task
      include: tasks/main.yml

  post_tasks:
    - name: finish tasks and sent notifiaction to HipChat
      hipchat:
        color: green
        token: "{{ hipchat_token }}"
        room: "{{ hipchat_room }}"
        msg: "[Finish] Run 'foo/setup.yml' playbook on {{ ansible_nodename }}."

# vim:ft=ansible :

现在,我喜欢使用pre_taskspost_tasks来做些事情。 - Chu-Siang Lai

13

1
我认为值得注意的是,如果我没有弄错的话,这可以放在 tasks/main.yml 中。 - Jonathan
2
从Ansible 2.4开始,现在也有import_role https://docs.ansible.com/ansible/latest/modules/import_role_module.html - Morgan Christiansson

12

你可以通过在未命名的<role>apache角色中添加另一个依赖项来简单解决此问题。

新代理用户角色的整个内容:

---
- user: name=proxy
...

然后在 roles/apache/meta/main.yml 中添加一个依赖项。

---
dependencies:
  - proxy-user
...

或在 roles/<role>/meta/main.yml 中设置:

---
dependencies:
  - proxy-user
  - { role: apache, user: proxy }
...

11

简短回答:我认为这种语言不允许为角色指定pre_tasks

您可以通过将用户的创建移动到单独的playbook中并使用include而不是role来欺骗/解决问题。类似于以下内容:

my_fake_role_playbooks/user_and_apache.yml:

- hosts: "{{p_hosts}}"
  pre_tasks:
    user: name=proxy
  roles: [ apache ]

实际_playbook.yml:

- include: my_fake_role_playbooks/user_and_apache.yml p_hosts=[host1, host2]

* 代码未经测试。

希望对你有帮助


“pre_tasks”和“post_task”只能在playbooks中使用,而不能在roles中使用吗? - MUY Belgium
现在有include_varsinclude_tasksinclude_roles模块。这些都是模块,因此它们作为任务、pre_tasks或post_tasks,在角色或任务中运行,甚至可能是处理程序。是的,pre_taskspost_tasks在playbooks中使用,而不是角色。严格来说,tasks部分也仅在playbooks中使用,因为角色任务在单独的文件中。 - Jeter-work

8

刚刚需要解决的问题是,预任务很可能比角色更加具体。做后任务很容易,因为你只需创建一个新的依赖角色,这被称为“包装角色”……或者至少在Chef中是这样称呼的,用于扩展某些内容。

对于预任务,你需要稍微修改层次结构,使用“包装角色”和我所谓的“同级角色”。因此,依赖逻辑应该如下:

  • 包装角色
    • 同级角色
    • 原始角色

包装角色有两个依赖项,但一定要确保在依赖列表中先添加“同级角色”。由于Ansible会从上到下执行。

最后,你应该将vars放在包装角色中,以便可以从playbook中覆盖它们。尽可能遵循变量的层次结构,不要跨越兄弟节点。


1

我有类似的需求,并通过在角色vars中定义变量来解决它。也就是说,创建一个<role>/vars/main.yml文件,其中包含以下内容:

---
user: proxy

这应该覆盖在apache模块中定义的user变量,但是将其写入您的模块defaults目录则不会覆盖。

我正在使用ansible 1.9,不确定这种行为存在多长时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接