Ansible 未在其处理程序中检测角色默认变量
Ansible not detecting Role default variables in its handler
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
据我所知,一切看起来都不错。但是,我在剧本执行期间收到此错误
FAILED! => {"failed": true, "msg": "the field 'args' has an invalid
value, which appears to include a variable that is undefined. The
error was: 'gu_log' is undefined\n\nThe error appears to have been in
'/roles/gunicorn/handlers/main.yml':
line 3, column 3, but may\nbe elsewhere in the file depending on the
exact syntax problem.\n\nThe offending line appears to be:\n\n\n-
name: Restart 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
输出
PLAY [Deploy]
TASK [setup]
******************************************************************* ok: [localhost]
TASK [Test Handlers]
*********************************************************** fatal: [localhost]: FAILED! => {"failed": true, "msg": "the field 'args' has
an invalid value, which appears to include a variable that is
undefined. The error was: 'gu_log' is undefined\n\nThe error appears
to have been in '/rtindru-test/roles/finalize/tasks/main.yml': line 2,
column 3, but may\nbe elsewhere in the file depending on the exact
syntax problem.\n\nThe offending line appears to be:\n\n---\n- name:
Test Handlers\n ^ here\n"} to retry, use: --limit
@/rtindru-test/playbook.retry
PLAY RECAP
********************************************************************* localhost : ok=1 changed=0 unreachable=0
failed=1
您既没有定义也没有使用任何角色。具有以下任务:
- include: roles/finalize/tasks/main.yml
您只是将一个任务文件包含到您的剧本中。它与角色无关。
要分配一个角色,您应该指定一个角色列表(一个或多个):
role:
- my_role1
- my_role2
请查看 roles 上的文档,并随意使用由以下脚本创建的剧本和结构。
Does ansible pass Role Default variables to the Handlers within the same Role?
是的。
为了证明 运行 下面的 bash 脚本创建并 运行 是一个最小的例子。它完整地从问题中获取 gunicorn/defaults/main.yml
和 gunicorn/handlers/main.yml
的内容,并添加缺少的组件:任务和剧本。它创建一个要删除的文件和 运行 剧本。
#!/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
解读:
在 运行 执行剧本之前,文件 /tmp/gunicorn.log
已创建并已验证其存在:
-rw-r--r-- 1 techraf wheel 0 Dec 23 07:57 /tmp/gunicorn.log
在 运行 执行剧本后,文件 /tmp/gunicorn.log
不存在:
ls: /tmp/gunicorn.log: No such file or directory
Ansible 正确地将变量 gu_log
值传递给删除文件的 Clear Gunicorn Log
处理程序。
最后的评论:
问题中描述的问题无法重现,因为问题不包含 complete 也不包含 verifiable 示例 MCVE.
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
据我所知,一切看起来都不错。但是,我在剧本执行期间收到此错误
FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'gu_log' is undefined\n\nThe error appears to have been in '/roles/gunicorn/handlers/main.yml': line 3, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Restart 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
输出
PLAY [Deploy]
TASK [setup] ******************************************************************* ok: [localhost]
TASK [Test Handlers] *********************************************************** fatal: [localhost]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'gu_log' is undefined\n\nThe error appears to have been in '/rtindru-test/roles/finalize/tasks/main.yml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: Test Handlers\n ^ here\n"} to retry, use: --limit @/rtindru-test/playbook.retry
PLAY RECAP ********************************************************************* localhost : ok=1 changed=0 unreachable=0
failed=1
您既没有定义也没有使用任何角色。具有以下任务:
- include: roles/finalize/tasks/main.yml
您只是将一个任务文件包含到您的剧本中。它与角色无关。
要分配一个角色,您应该指定一个角色列表(一个或多个):
role:
- my_role1
- my_role2
请查看 roles 上的文档,并随意使用由以下脚本创建的剧本和结构。
Does ansible pass Role Default variables to the Handlers within the same Role?
是的。
为了证明 运行 下面的 bash 脚本创建并 运行 是一个最小的例子。它完整地从问题中获取 gunicorn/defaults/main.yml
和 gunicorn/handlers/main.yml
的内容,并添加缺少的组件:任务和剧本。它创建一个要删除的文件和 运行 剧本。
#!/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
解读:
在 运行 执行剧本之前,文件
/tmp/gunicorn.log
已创建并已验证其存在:-rw-r--r-- 1 techraf wheel 0 Dec 23 07:57 /tmp/gunicorn.log
在 运行 执行剧本后,文件
/tmp/gunicorn.log
不存在:ls: /tmp/gunicorn.log: No such file or directory
Ansible 正确地将变量
gu_log
值传递给删除文件的Clear Gunicorn Log
处理程序。
最后的评论:
问题中描述的问题无法重现,因为问题不包含 complete 也不包含 verifiable 示例 MCVE.