Ansible在任务中注册变量并在模板中使用它

时间:2017-01-09 22:34:33

标签: ansible jinja2 ansible-2.x ansible-template

在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"

listen 80的vhost模板中始终可用,我只想在证书可用时添加listen 443块:

server {
  listen 80;
  ........

}
{% if ssl_cert_check == True %} # This doesn't issue error but doesn't work either
server {
  listen 443;
  ..............
}
{% endif %}

当我运行上述情况时,第二个服务器块没有被执行,这意味着只有服务器listen 80被打印在vhost配置中。

但是,如果删除True if语句并在模板中添加stat.exists,则会收到错误消息:

# This issues error
{% if ssl_cert_check.stat.exists %}
server {
  listen 443;
  ..............
}
{% endif %}

错误是: "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'stat'即使我在注册变量之前使用了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
                }
            }
        ]
    }

2 个答案:

答案 0 :(得分:0)

如果您查看自己的ssl_cert_check,您会注意到布尔键exists存储在stat列表下的results字典中,所以实际上你应该迭代模板内列表中的项目。

如果您发布的内容是一致的示例,则可以使用以下命令引用列表中的第一项:

{% if ssl_cert_check.results[0].stat.exists %}

但是,在您的情况下创建ssl_cert_check的方式很可能意味着:

  • 你的代码中有某种循环
  • sitename不是标量值,而是列表本身

如果循环次数较多,或者sitename上有多个项目,则结果可能不一致。

您应该确定根本原因,而不是使用results[0]解决方法。

答案 1 :(得分: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
}

最有可能最好为每个寄存器使用唯一的名称?