【问题标题】:Ansible: variable interpolation in task nameAnsible:任务名称中的变量插值
【发布时间】:2015-03-12 03:45:42
【问题描述】:

我无法让这个看似简单的示例在 Ansible 1.8.3 中运行。变量插值不会在任务名称中起作用。我见过的所有examples 似乎都表明这应该可行。鉴于变量是在 vars 部分中定义的,我希望任务名称打印变量的值。为什么这不起作用?

即使是来自 Ansible documentation 的示例似乎也没有打印变量值。

---
- hosts: 127.0.0.1
  gather_facts: no
  vars:
    vhost: "foo"
  tasks:
    - name: create a virtual host file for {{ vhost }}
      debug: msg="{{ vhost }}"

这会产生以下输出:

PLAY [127.0.0.1]     
************************************************************** 

TASK: [create a virtual host file for {{ vhost }}] 
**************************** 
ok: [127.0.0.1] => {
   "msg": "foo"
}

PLAY RECAP 
******************************************************************** 
127.0.0.1                  : ok=1    changed=0    unreachable=0    failed=0   

更新 这适用于 1.7.2,但不适用于 1.8.3。所以要么这是一个错误,要么是一个功能。

【问题讨论】:

标签: ansible ansible-playbook


【解决方案1】:

变量未在name 中解析。只有在实际任务/条件等内部,占位符才会被解析。我想这是设计使然。假设您有一个with_items 循环并在name 中使用{{ item }}。任务name 只会打印一次,但{{ item }} 会在每次迭代中改变。

我看到了示例,即使是您链接到的文档中的示例,也使用了 name 中的变量。但这并不意味着结果会像您预期的那样。文档由社区管理。可能有人只是将那条线放在那里而没有对其进行测试 - 或者它曾经在以前版本的 Ansible 中像这样工作,并且当时文档还没有更新。 (我只使用 Ansible 大约一年)。但即使它不像我们希望的那样工作,我仍然在我的name 中使用变量,只是为了表明该任务是基于动态参数的。可能是出于相同的意图编写的示例。

我最近做了一个有趣的观察(Ansible 1.9.4),默认值写在任务名称中。

- name: create a virtual host file for {{ vhost | default("foo") }}

执行时,Ansible 会将任务标题显示为:

任务:[为 foo 创建一个虚拟主机文件]

这样可以避免输出中出现难看的任务名称。

【讨论】:

  • 这有点……有道理。就像你假设的那样,这曾经在 1.7.x 中工作,但在 1.8 中停止工作。哦,好吧...
  • 啊,感谢您提到版本,我认为这是因为我将我的任务变成了一个模块,数字我的名字停止插值因为我更新了 Ansible。
  • 我正在使用一种解决方法,不知道这是否是唯一的方法。我在任务之前包含了调试语句
【解决方案2】:

说明

变量是否被插值取决于它的声明位置。

假设您有两个主机:AB

  • 如果变量 foo 仅具有每个主机的值,则当 Ansible 运行播放时,它无法决定使用哪个值。
  • 另一方面,如果它有一个 global 值(在主机不变性的意义上是全局的),那么使用哪个值就不会混淆。

来源:https://github.com/ansible/ansible/issues/3103#issuecomment-18835432

实践手册

  • ansible_user 是库存变量
  • greeting 是一个不变量
- name: Test variable substitution in names
  hosts: localhost
  connection: local
  vars:
    greeting: Hello
  tasks:
    - name: Sorry {{ ansible_user }}
      debug:
        msg: this won't work
    - name: You say '{{ greeting }}'
      debug:
        var: ansible_user

【讨论】:

    【解决方案3】:

    我今天在我的一个 Ansible 角色中遇到了同样的问题,我发现了一些有趣的事情。
    当我在任务名称中使用 var 之前使用 set_fact 模块时,它们实际上会被转换为正确的值。

    在本例中,我想为远程用户设置密码:
    请注意,我使用了我之前设置为事实的变量 test_useruser_password

    - name: Prepare to set user password
      set_fact:
        user_password: "{{ linux_pass }}"
        user_salt: "s0m3s4lt"
        test_user: "{{ ansible_user }}"
    
    - name: "Changing password for user {{ test_user }} to {{ user_password }}"
      user:
       name: "{{ ansible_user }}"
       password: "{{ user_password | password_hash('sha512', user_salt) }}"
       state: present
       shell: /bin/bash
       update_password: always
    

    这给了我以下输出:

    TASK [install : Changing password for user linux to LiNuXuSeRPaSs#]
    

    所以这解决了我的问题。

    【讨论】:

      【解决方案4】:

      这可能很难看,但您可以通过以下方式解决一些问题:

      - name: create a virtual host file
        debug:  
          msg: "Some command result"
        loop: "{{ [ vhost ] }}"
      

      - name: create a virtual host file
        debug:  
          msg: "Some command result"
        loop_control:
          label: "{{ vhost }}"
        loop: [1]
      

      我一般不会这样做,但它显示了如何使用项目或标签来提供命令结果之外的信息。虽然它可能不会

      来源:https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-05
        相关资源
        最近更新 更多