【问题标题】:Ansible not detecting Role default variables in its handlerAnsible 未在其处理程序中检测角色默认变量
【发布时间】:2017-05-08 04:34:36
【问题描述】:

ansible 是否将角色默认变量传递给同一角色中的处理程序?

以下是有问题的剧本的一小段摘录:

角色层次结构

- playbook.yml
- roles/
  - gunicorn/
    - defaults/
      - main.yml
    - handlers/
      - main.yml
  - code-checkout/
    - tasks/
      - main.yml

这是文件内容

gunicorn/defaults/main.yml

---
gu_log: "/tmp/gunicorn.log"

gunicorn/handlers/main.yml

---
- name: Clear Gunicorn Log
  shell: rm {{ gu_log }}

finalize/tasks/main.yml

---
- name: Test Handlers
  shell: ls
  notify:
    - Restart Gunicorn

playbook.yml

---
  - name: Deploy
    hosts: webservers
    tasks:
      - include: roles/finalize/tasks/main.yml
    handlers:
      - include: roles/gunicorn/handlers/main.yml

AFAIK 一切看起来都不错。但是,我在 playbook 执行期间收到此错误

失败了! => {"failed": true, "msg": "'args' 字段无效 值,它似乎包含一个未定义的变量。这 错误是:“gu_log”未定义\n\n错误似乎已在 '/roles/gunicorn/handlers/main.yml': 第 3 行第 3 列,但可能\n位于文件中的其他位置,具体取决于 确切的语法问题。\n\n违规行似乎是:\n\n\n- name: 重启 Gunicorn\n ^ here\n"}

在 Ubuntu 12.04 LTS 上使用 Ansible 2.2

这是 techraf 脚本的修改版本,它创建所有目录并演示我的问题

#!/bin/bash

mkdir -p ./rtindru-test/roles/gunicorn
mkdir -p ./rtindru-test/roles/gunicorn/defaults
mkdir -p ./rtindru-test/roles/gunicorn/handlers
mkdir -p ./rtindru-test/roles/finalize/tasks

cat >./rtindru-test/roles/finalize/tasks/main.yml <<HANDLERS_END
---
- name: Test Handlers
  shell: rm {{ gu_log }}
HANDLERS_END

cat >./rtindru-test/roles/gunicorn/handlers/main.yml <<HANDLERS_END
---
- name: Clear Gunicorn Log
  shell: rm {{ gu_log }}
HANDLERS_END

cat >./rtindru-test/roles/gunicorn/defaults/main.yml <<DEFAULTS_END
---
gu_log: "/tmp/gunicorn.log"
DEFAULTS_END

cat >./rtindru-test/playbook.yml <<PLAYBOOK_END
---
  - name: Deploy
    hosts: localhost
    tasks:
      - include: roles/finalize/tasks/main.yml
    handlers:
      - include: roles/gunicorn/handlers/main.yml
PLAYBOOK_END

touch /tmp/gunicorn.log
ls -l /tmp/gunicorn.log
ansible-playbook ./rtindru-test/playbook.yml
ls -l /tmp/gunicorn.log

输出

播放[部署]


任务 [设置] ****************************************************** ***************** 好的:[本地主机]

TASK [测试处理程序] ****************************************************** ********* 致命:[本地主机]:失败! => {"failed": true, "msg": "'args' 字段有 一个无效值,它似乎包含一个变量 不明确的。错误是:“gu_log”未定义\n\n出现错误 已经在'/rtindru-test/roles/finalize/tasks/main.yml':第2行, 第 3 列,但可能\n位于文件中的其他位置,具体取决于确切的 语法问题。\n\n违规行似乎是:\n\n---\n- 名称: 测试处理程序\n ^ here\n"} 重试,使用:--limit @/rtindru-test/playbook.retry

播放回顾 ****************************************************** ******************* 本地主机:好的=1 更改=0 无法访问=0
失败=1

【问题讨论】:

  • @techraf Ansible 角色旨在相当独立 - 这是我的“完整”角色。您还需要回复哪些信息?
  • 试试gu_log = "/tmp/gunicorn.log"只是猜测
  • 您的库存和/或剧本丢失
  • 既然您包含了缺失的部分,很明显您既没有定义也没有使用任何role。您只是包含了您命名的子目录中的一些文件,以模仿角色内的目录名称。我之前发布的答案更加有效 - 请注意剧本中的roles:
  • 我已经在答案中回复了——如果你想使用角色,你需要使用角色。您不能包含一个文件并期望角色的功能神奇地出现。我不明白你想通过复制问题答案中的代码、修改代码来破坏它并声称它不起作用来实现什么。是的,如果你破坏了代码,它就不起作用了。

标签: ansible ansible-2.x ansible-role ansible-handlers


【解决方案1】:

您既没有定义也没有使用任何角色。完成以下任务:

- include: roles/finalize/tasks/main.yml

您只是将一个任务文件包含在您的剧本中。它与角色无关。

要分配一个角色,您应该指定一个角色的列表(一个或多个):

role:
  - my_role1
  - my_role2

请查看roles 上的文档,并随意使用由以下脚本创建的剧本和结构。

ansible 是否将角色默认变量传递给同一角色中的处理程序?

是的。

为了证明,请运行以下 bash 脚本,该脚本创建并运行一个最小示例。它完整​​地从问题中获取gunicorn/defaults/main.ymlgunicorn/handlers/main.yml 的内容,并添加缺失的组件:任务和剧本。它会创建一个要删除的文件并运行 playbook。

#!/bin/bash

mkdir -p ./so41285033/roles/gunicorn
mkdir -p ./so41285033/roles/gunicorn/defaults
mkdir -p ./so41285033/roles/gunicorn/handlers
mkdir -p ./so41285033/roles/gunicorn/tasks

cat >./so41285033/roles/gunicorn/tasks/main.yml <<TASKS_END
---
- debug:
  changed_when: true
  notify: Clear Gunicorn Log
TASKS_END

cat >./so41285033/roles/gunicorn/handlers/main.yml <<HANDLERS_END
---
- name: Clear Gunicorn Log
  shell: rm {{ gu_log }}
  when: "'apiservers' not in group_names"
HANDLERS_END

cat >./so41285033/roles/gunicorn/defaults/main.yml <<DEFAULTS_END
---
gu_log: "/tmp/gunicorn.log"
DEFAULTS_END

cat >./so41285033/playbook.yml <<PLAYBOOK_END
---
- hosts: localhost
  gather_facts: no
  connection: local
  roles:
    - gunicorn
PLAYBOOK_END

touch /tmp/gunicorn.log
ls -l /tmp/gunicorn.log
ansible-playbook ./so41285033/playbook.yml
ls -l /tmp/gunicorn.log

结果:

-rw-r--r--  1 techraf  wheel  0 Dec 23 07:57 /tmp/gunicorn.log
 [WARNING]: Host file not found: /etc/ansible/hosts

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [localhost] ***************************************************************

TASK [gunicorn : debug] ********************************************************
ok: [localhost] => {
    "msg": "Hello world!"
}

RUNNING HANDLER [gunicorn : Clear Gunicorn Log] ********************************
changed: [localhost]
 [WARNING]: Consider using file module with state=absent rather than running rm


PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=2    unreachable=0    failed=0

ls: /tmp/gunicorn.log: No such file or directory

解读:

  • 在运行 playbook 之前,已创建文件 /tmp/gunicorn.log 并验证其存在:

    -rw-r--r--  1 techraf  wheel  0 Dec 23 07:57 /tmp/gunicorn.log
    
  • 运行 playbook 后文件 /tmp/gunicorn.log 不存在:

    ls: /tmp/gunicorn.log: No such file or directory
    
  • Ansible 正确地将变量 gu_log 值传递给删除文件的 Clear Gunicorn Log 处理程序。

最后一句话:

所描述的问题无法重现,因为该问题不包含MCVE含义中的completeverifiable示例。

【讨论】:

  • 非常感谢!我理解您关于问题不完整的观点 - 我已根据您的 cmets 添加了详细信息。我立即注意到的一点不同是,我的剧本包括个人任务而不是角色。另一个区别是 gunicorn(没有“tasks/main.yml”)仅包含在处理程序部分(不在任务或角色中)。
  • 两个快速跟进问题: 1. 是否建议按照您的方式包含角色?如果我的角色之一纯粹是一个处理程序,就像 gunicorn 角色 2 的情况一样。是否有必要明确地包含一个角色/任务,以便它的处理程序可以使用变量?
猜你喜欢
  • 1970-01-01
  • 2015-05-21
  • 1970-01-01
  • 2018-11-06
  • 2014-05-04
  • 2013-03-17
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
相关资源
最近更新 更多