在 Ansible 任务中,如何注册一个变量,以便我可以将其用作模板中的检查语句。任务是:
- name: Check if certificate file exists
stat: path=/etc/nginx/ssl/{{ sitename }}.pem
register: ssl_cert_check
- name: Create vhost from template
template: "src={{ vhost_conf }} dest=/etc/nginx/conf/vhost.conf"
在 vhost 的模板中,listen 80
始终可用,我想仅在证书可用时添加listen 443
块:
server {
listen 80;
........
}
{% if ssl_cert_check == True %} # This doesn't issue error but doesn't work either
server {
listen 443;
..............
}
{% endif %}
当我运行上述情况时,第二个服务器块没有执行,这意味着在vhost配置中只打印了服务器侦听80。
但是,如果我删除 True for if
语句并在模板中添加stat.exists
,则会出现错误:
# This issues error
{% if ssl_cert_check.stat.exists %}
server {
listen 443;
..............
}
{% endif %}
错误是: "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'stat'
即使我在注册变量之前使用了统计模块。
有没有其他方法可以传递 Ansible 任务中定义的变量并在 Jinja2 模板中使用它?
- debug: var=ssl_cert_check
任务在Create vhost from template
之前显示的值为:
"ssl_cert_check": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"changed": false,
"invocation": {
"module_args": {
"checksum_algorithm": "sha1",
"follow": false,
"get_checksum": true,
"get_md5": true,
"mime": false,
"path": "/etc/nginx/ssl/abc.pem"
},
"module_name": "stat"
},
"item": {
........
},
"stat": {
"exists": false
}
}
]
}
如果您查看您拥有的ssl_cert_check
,您会注意到布尔键exists
存储在results
列表下的stat
字典中,因此实际上您应该迭代模板内列表中的项目。
如果您发布的内容是一致的示例,则可以使用以下方法引用列表中的第一项:
{% if ssl_cert_check.results[0].stat.exists %}
但是,在您的情况下创建ssl_cert_check
的方式很可能意味着:
- 你的代码中有某种循环
-
sitename
不是标量值,而是列表本身
如果循环运行次数较多,或者您sitename
上有多个项目,则结果可能不一致。
您应该修复根本原因,而不是使用results[0]
解决方法。
请注意:跳过的任务仍将注册变量:
- name: Check if certificate file exists
stat: path=/etc/nginx/ssl/{{ sitename }}.pem
register: ssl_cert_check
- name: Check if certificate file exists
stat: path=/etc/nginx/ssl/{{ sitename }}.pem
register: ssl_cert_check
when: nonexistent is defined
在这种情况下,寄存器将具有以下值:
"ssl_cert_check": {
"changed": false,
"skip_reason": "Conditional result was False",
"skipped": true
}
最好为每个寄存器使用唯一的名称?