ansible-playbook循环(loop)

一.简述:

  在使用ansible做配置管理工作中,经常会遇到很多的task都需要重复的引用某一个模块比如:一次同步N个文件,创建N个用户等,按照之前的文档来看就需要写N个task,尽管功能可以实现,但代码量会非常大/臃肿。对于这种情况,ansible是可以通过循环(loop)方式处理。

二.使用方式:

 1. 标准loops(with_items):

       应用环境比较常见,如同时copy 操作主机的aaaa和bbbb文件到被操作主机上:

---
- hosts: test

  tasks:
      - name: test
        copy: src=/tmp/{{ item }} dest=/tmp/{{ item }}
        with_items:         #也可以直接写成- ['aaaa', 'bbbb']
            - aaaa          #同样,也支持变量(with_items: "{{somelist}}")
            - bbbb

另外,with_items还支持python的字典类型:

  tasks:
      - name: test
        debug: msg="{{ item.key }}======= {{ item.var }}"
        with_items:
            - {key: 'aaaa', var: 'bbbb'}
            - {key: 'bbbb', var: 'cccc'}

2. 嵌套循环(with_nested):

     主要实现一对多或者多对多的情况,如ab组合ac组合等:

  tasks:
      - name: test
        debug: msg="{{ item[0] }}--{{ item[1] }}---{{ item[2] }}"
        with_nested:
            - ['aaaa', 'bbbb']          #同样支持变量
            - ['cccc', 'dddd', 'eeee']
            - ['ffff', 'gggg']

3. 数据并行循环(with_together):

    如上面嵌套循环,with_together可以实现aaaa cccc ffff 并行的集合循环:

  tasks:
      - name: test
        debug: msg="{{ item[0] }}--{{ item[1] }}---{{ item[2] }}"
        with_together:
            - ['aaaa', 'bbbb']
            - ['cccc', 'dddd', 'eeee']
            - ['ffff', 'gggg']

4. hash表循环(with_dict):

      ansible1.5版本以上支持,主要针对hash结构的数据进行循环,这里套用官方的例子:

---
- hosts: test
  vars:
      users:      #定义users变量
          alice:                        #用户 名字  telephone
              name: Alice Appleworth    
              telephone: 123-456-7890
          bob:
              name: Bob Bananarama
              telephone: 987-654-3210
  tasks:
      - name: test             #打印出每个用户的名字和电话
        debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
        with_dict: "{{ users }}"

变量也可直接定义为json格式:

- hosts: test
  vars:
      users: {"alice":{'name':'ace','telephone':'123-123'},"bob":{'name':'boe','telephone':'321-321'}}


可以通过with_subelements对子元素进行循环,参考http://docs.ansible.com/ansible/playbooks_loops.html

5. 文件列表循环(with_fileglob):

   个人理解with_fileglob就是针对文件名进行匹配,然后进行操作:

  tasks:
      - name: test
        debug: msg="file------>{{ item }}"
        with_fileglob:
            /tmp/a*.yaml        #匹配/tmp/目录下以a开头yaml结尾的文件debug处理

其实就是使用python的glob模块模糊匹配(glob.glob('/tmp/a*.yaml'))

6. 整数循环(with_sequence):

      可以针对一个数字范围安装升序进行循环,可以指定起始值、终止值,以及一个可选的递增值,数字值可以被指定为10进制,16进制(0x3f8)或者八进制(0600):

---
- hosts: all
  tasks:
    - bug: msg="file------user{{ item }}"
      with_sequence: start=4 end=16 stride=2  #从4开始到16以2递增

    - user: name=usertest{{ item }} state=present groups=evens  #创建用户usertest(1到4)
      with_sequence: count=4              #从1到4

7. 随机选择(with_random_choice):

类似于python的random模块功能,即从list中随机选择一个:

tasks:
      - name: tes
        debug: msg={{ item }}
        with_random_choice:
            - aa
            - bbb
            - ccc

8. 条件循环(until):

       可判断循环的结果是否达到设置的条件,当达到时,结束循环,当未达到时,可设置循环的次数,及一次循环和下次循环的间隔时间,当达到循环次数还未达到设置的条件时,fatal failed退出:

  tasks:
      - name: tes
        shell: tail -10 /var/log/messages
        register: error
        until: error.stdout.find('error') != -1 #检测结果是否包含‘error’信息,存在时(!=-1)退出循环
        retries: 5   循环次数
        delay: 3     间隔时间

9. 第一个匹配的文件(with_first_found):

     这个参数跟上面文件循环的区别在于,只获取第一个匹配的文件,另外:不能使用通配符的匹配(如*):

  tasks:
      - name: tes
        debug: msg={{ item }}  
        with_first_found:         #匹配当前目录下或tmp目录下的dddd.yaml
            - “dddd.yaml”
            - "/tmp/dddd.yaml"


#还有一种可以指定路径的方式:

  tasks:
      - name: tes
        debug: msg={{ item }}
        with_first_found:
            - files:
              - "ddd.yaml"
              - "dddd.yaml"
              paths:
                  - /tmp
                  - /root

10. 循环中变量赋值:

    之前已经了解过通过register可以在task直接进行赋值,register不仅可以用于单一的task中赋值临时存储,也支持接受多个task的结果作为变量临时存储,例如:

  tasks:
      - name: tes
        shell: "{{ item }}"    #循环执行hostnaem和uptime命令
        with_items:
            - hostname
            - uptime
        register: ret         然后将两者结果赋值给ret变量

      - name: test
        debug: msg="{% for i in ret.results %} --{{ i.stdout }} {% endfor %}"  #打印变量结果

执行结果如下:

其他一些方法参考:http://docs.ansible.com/ansible/playbooks_loops.html

----------------------------------------------------------------------------------------------

深耕运维行业多年,擅长linux、容器云原生、运维自动化等方面。
承接各类运维环境部署、方案设计/实施、服务代运维工作,欢迎沟通交流 !

<think>首先,用户的问题是关于Ansible Playbook中debug模块的使用,具体是msg参数和变量值显示的问题。用户说:“我想在Ansible Playbook中使用debug模块时,输出消息的格式或变量值出现问题,用户希望了解如何正确使用debug模块的msg参数或显示变量内容。” 所以,我的回答需要专注于Ansible debug模块的正确使用,特别是msg参数和变量引用。 现在,回顾系统级指令: - 所有行内数学表达式必须用$...$,但这个问题不涉及数学表达式,所以可能不需要。 - 独立公式用$$...$$,但同样,这里可能不适用。 - LaTeX语法正确:确保任何技术内容正确。 - 使用中文回答:整个回答用中文。 - 生成相关问题:在回答结束后,添加相关问题。 - 引用段落末尾添加引用标识:如[^1]。 用户可见层: - 回答结构清晰,逐步解决问题。 - 保证真实可靠:基于我的知识和提供的引用。 提供的引用: - [^1]: 关于通过ansible-playbook命令行传入变量。 - [^2]: 关于使用ansible_facts命名空间。 - [^3]: 关于命令行传入变量和playbook逻辑控制。 - [^4]: 关于循环语句的使用。 - [^5]: 关于在playbook中引入角色。 这些引用是关于Ansible的变量传递、循环等,但用户的问题特定于debug模块。我需要整合相关信息。 关键点: - debug模块用于调试,显示变量值或消息。 - msg参数:用于指定要显示的消息。可以是字符串,也可以包含变量。 - 变量引用:在Ansible中,变量用{{ variable_name }}格式。 - 常见问题:变量未定义、格式错误、输出不显示等。 结构回答: 1. **介绍debug模块**:简要解释debug模块的作用。 2. **正确使用msg参数**:说明如何设置msg参数,包括静态文本和变量。 3. **变量引用**:强调正确的变量引用语法。 4. **示例**:提供代码示例来演示。 5. **常见问题解决**:讨论用户可能遇到的格式或变量值问题。 6. **相关提示**:结合引用,如变量传递方式可能影响debug输出。 最后,生成相关问题。 确保回答用中文。 大纲: - 开头:直接回应用户问题。 - 步骤1:debug模块基础。 - 步骤2:msg参数的使用。 - 步骤3:变量显示。 - 步骤4:示例代码。 - 步骤5:故障排除。 - 结尾:总结。 - §§相关问题§§:生成3-5个相关问题。 生成相关问题: 1. 如何调试Ansible Playbook中的变量未定义错误? 2. 在Ansible中,除了debug模块,还有哪些调试方法? 3. 如何格式化debug模块的输出? 4. Ansible变量作用域如何影响debug输出? 5. 在循环中如何使用debug模块? 参考引用: - 引用[^3]提到命令行传入变量,这可能与变量值相关。 - 引用[^4]提到循环,如果在循环中使用debug,需要注意。 - 引用[^2]提到facts命名空间,对于ansible_facts变量。 在回答中自然地引用这些。</think>### Ansible Playbook中debug模块的msg参数和变量显示的正确使用 在Ansible Playbook中,`debug`模块是调试的核心工具,用于输出消息或变量值。用户在使用`msg`参数时,常见问题包括变量未正确引用、输出格式混乱或变量值未显示。下面我将逐步解释正确用法,确保输出清晰可靠。 #### 1. **debug模块基础** - `debug`模块用于在Playbook执行期间打印消息或变量内容,帮助诊断问题。 - 基本语法: ```yaml - name: 调试示例 ansible.builtin.debug: msg: "消息内容" ``` - `msg`参数:接受字符串或变量引用。如果消息包含变量,必须使用Jinja2模板语法`{{ variable_name }}`包裹变量。 #### 2. **正确使用msg参数** - **静态消息**:直接提供字符串,例如: ```yaml - debug: msg: "这是一个测试消息" ``` - **动态消息(包含变量)**:变量必须用`{{ }}`引用。例如,显示主机名: ```yaml - debug: msg: "当前主机是 {{ ansible_hostname }}" ``` - 注意:变量名区分大小写,且需确保变量已定义。如果变量未初始化,输出会显示错误(如`VARIABLE IS NOT DEFINED!`)。 - **引用facts变量**:Ansible facts(系统信息)通过`ansible_facts`命名空间访问。例如: ```yaml - debug: msg: "系统IP地址是 {{ ansible_facts.default_ipv4.address }}" ``` 这遵循了Ansible 2.5+的推荐实践,避免直接使用旧式变量注入[^2]。 #### 3. **显示变量内容** - **基本变量**:直接引用playbook中定义的变量或命令行传入的变量。例如: ```yaml vars: user_name: "michael" tasks: - debug: msg: "用户名是 {{ user_name }}" ``` - **命令行传入变量**:通过`--extra-vars`传入的变量可直接在`msg`中使用。例如: ```bash ansible-playbook playbook.yml --extra-vars "ssh_pass=hello" ``` 在playbook中: ```yaml - debug: msg: "SSH密码是 {{ ssh_pass }}" ``` 输出类似:`"msg": "The 192.168.3.154 ssh_pass is hello"`[^1][^3]。 - **循环中显示变量**:在循环(如`with_items`)中,使用`{{ item }}`引用当前元素。例如: ```yaml - name: 显示列表元素 debug: msg: "当前项是 {{ item }}" with_items: "{{ data_list }}" ``` 这避免了输出格式混乱,确保每个迭代独立显示[^4]。 #### 4. **完整示例代码** 以下Playbook示例演示了`msg`参数的正确使用,包括静态消息、变量引用和循环: ```yaml --- - hosts: all vars: user_list: ["alice", "bob"] tasks: - name: 显示静态消息 debug: msg: "开始调试过程" - name: 显示变量值 debug: msg: "用户列表是 {{ user_list }}" - name: 在循环中显示元素 debug: msg: "处理用户: {{ item }}" loop: "{{ user_list }}" ``` - **输出示例**: ``` TASK [显示变量值] ********************************************************** ok: [192.168.1.10] => { "msg": "用户列表是 ['alice', 'bob']" } TASK [在循环中显示元素] **************************************************** ok: [192.168.1.10] => (item=alice) => { "msg": "处理用户: alice" } ok: [192.168.1.10] => (item=bob) => { "msg": "处理用户: bob" } ``` #### 5. **常见问题及解决** - **问题:变量值未显示或报错** - **原因**:变量未定义或拼写错误。Ansible严格检查变量作用域。 - **解决**:使用`-v`(verbose模式)运行playbook查看详细错误;或添加条件检查: ```yaml - debug: msg: "{{ variable_name | default('变量未定义') }}" ``` - **问题:输出格式混乱** - **原因**:`msg`中包含未转义的特殊字符(如`{ }`),或变量是复杂对象(如字典)。 - **解决**:使用`to_json`过滤器美化输出: ```yaml - debug: msg: "{{ complex_variable | to_nice_json }}" ``` - **问题:在角色中debug不工作** - **原因**:角色变量作用域问题。 - **解决**:确保在角色任务中正确引用变量,例如在角色定义中明确变量[^5]。 #### 总结 正确使用`debug`模块的`msg`参数需注意:变量必须用`{{ }}`包裹,避免语法错误;对于动态内容,优先使用`ansible_facts`命名空间;在循环中,结合`loop`或`with_items`确保迭代输出清晰。如果问题持续,检查变量定义方式(如命令行传入或playbook vars)[^1][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值