【问题标题】:How can I write variables inside the tasks file in ansible如何在ansible的任务文件中写入变量
【发布时间】:2014-04-26 17:00:31
【问题描述】:

我有这个play.yml

---
- hosts: 127.0.0.1
  connection: local
  sudo: false

  tasks:
     - include: apache.yml

我的 Apache 是这样的:

vars:
    url: czxcxz

- name: Download apache
  shell: wget {{url}} 

这给了我错误。

如果我删除vars,那么它会起作用。但是我想在任务中包含变量,以便我可以为不同的任务保留不同的变量。

【问题讨论】:

    标签: ansible ansible-playbook


    【解决方案1】:

    注意: 如下所述使用set_fact 将事实/变量设置到任务正在运行的远程服务器上。然后,此事实/变量将在您的剧本的整个持续时间内持续存在于后续任务中。

    此外,这些事实是不可变的(在剧本期间),一旦设置就无法更改。


    原始答案

    在你的任务之前使用set_fact 来设置事实,这似乎可以与变量互换:

    - name: Set Apache URL
      set_fact:
        apache_url: 'http://example.com/apache'
    
    - name: Download Apache
      shell: wget {{ apache_url }}
    

    官方说法见http://docs.ansible.com/set_fact_module.html

    【讨论】:

    • 这似乎是一个更好的解决方案,因为您可以将事实用作变量。
    • 请注意与变量相比的细微差别:此模块允许设置新变量。变量是逐个主机设置的,就像设置模块发现的事实一样。 这些变量将在播放之间保留。
    • 旁注:看来,您无法使用set_fact 就地更改变量...因此,如果该名称已被变量占用,则不会对其进行修改...在更高级别的剧本上将变量设置为相同名称可能容易出错。所以请确保您不会这样做(例如,使用可能唯一的名称,而不是“项目”)。
    • 请注意您的笔记...Also, these facts are immutable (for the duration of the playbook), and cannot be changed once set. -- 这并非完全正确。您可以覆盖在较早的任务中使用set_fact 创建的事实,但不能以任何其他方式覆盖变量集...例如,如果您循环执行一组任务,并且在每个任务的开头循环迭代你使用set_fact: loop_item='{{ item }}',然后使用debug: msg='{{ loop_item }}',你会看到fact随着每次循环迭代而改变。
    【解决方案2】:

    我知道,这是很久以前的事了,但由于尚未发布最简单的答案,我会为其他可能经过的用户这样做。

    只需将 var 移到“名称”块中即可:

    - name: Download apache
      vars:
        url: czxcxz
      shell: wget {{url}} 
    

    【讨论】:

      【解决方案3】:

      变量定义旨在用于任务。但是如果你想将它们包含在任务中,可以使用register 指令。像这样:

      - name: Define variable in task.
        shell: echo "http://www.my.url.com"
        register: url
      
      - name: Download apache
        shell: wget {{ item }}
        with_items: url.stdout
      

      您还可以将roles 视为根据不同角色roles 分离任务的一种方式。这样,您可以为每个角色拥有单独的变量。例如,您可能有一个用于apache1url 变量和一个用于角色apache2 的单独的url 变量。

      【讨论】:

      • 我认为 register 只适用于命令的输出?如何在角色的roles/<role>/tasks/main.yml 中创建静态变量?
      • @ThorSummoner 你的意思是这就像一个常规变量? docs.ansible.com/… 也许是这个? docs.ansible.com/playbooks_roles.html#role-default-variables
      • 这个解决方案完全是矫枉过正。 U 通过 ssh 将 var 值发送到远程主机,然后将其取回,以便在控制节点上本地使用它!!
      【解决方案4】:

      在您的示例中,apache.yml 是任务列表,但不是剧本

      取决于所需的架构,您可以执行以下操作之一:

      1. 将 apache.yml 转换为角色。然后在 roles/apache/tasks/mail.yml 中定义任务和在 roles/apache/defaults/mail.yml 中定义变量(应用角色时可以覆盖默认值中的变量)

      2. 在 play.yml playbook 中设置 vars

      play.yml

      ---
      - hosts: 127.0.0.1
        connection: local
        sudo: false
      
        vars:
          url: czxcxz
      
        tasks:
           - include: apache.yml
      

      apache.yml

      - name: Download apache
        shell: wget {{url}} 
      

      【讨论】:

        【解决方案5】:

        如果您需要仅通过特定任务持续存在的局部变量,您可以这样做:

        - name: My Task
          vars:
            my_var: 123
        

        当您希望拥有更多可重用的角色时,这可能很有用,它需要一些通用变量(参数)。例如:

        my_debug_role/main.yml:

        - name: Output me
          ansible.builtin.debug:
            msg: "Your output was: {{ my_msg }}"
        

        然后在您的剧本中,您可以使用更具体的变量重用它,例如:

        my_playbook.yml:

        - name: Output my custom log
          include_role:
            name: my_debug_role
          vars:
            my_msg: "{{ some_custom_specific_variable }}"
        

        【讨论】:

          【解决方案6】:

          只要在 ansible 的同一行中有一个模块后跟一个变量,解析器就会将引用变量视为内联字典的开头。例如:

          - name: some example
            command: {{ myapp }} -a foo
          

          这里默认将{{ myapp }} -a foo的第一部分解析为字典而不是字符串,会报错。

          所以你必须像这样引用参数:

          - name: some example
            command: "{{ myapp }} -a foo"
          

          【讨论】:

          • 这是真的,但它没有回答问题。
          猜你喜欢
          • 1970-01-01
          • 2015-05-11
          • 2022-01-23
          • 1970-01-01
          • 1970-01-01
          • 2020-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多