ansible-playbook循环---loops

可以重复引用某个模块,不用再使用多个tasks。
如下:

with_item的值是Python list数据结构,可以理解为每个tasks会循环读取list里面的值,
然后key的值的名称是item,list里面也支持python字典,如下:
1:如下:
---
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="name  ------>  {{ item }}"
      
      with_items:
        - one 
        - two

[root@ansible-1 ansible]# ansible-playbook -i hosts loops.yaml 

PLAY [all] ***********************************************

TASK [debug loops] *****************************************
ok: [192.168.124.129] => (item=one) => {
    "changed": false, 
    "item": "one", 
    "msg": "name  ------>  one"
}
ok: [192.168.124.129] => (item=two) => {
    "changed": false, 
    "item": "two", 
    "msg": "name  ------>  two"
}

PLAY RECAP ***************************************
192.168.124.129    : ok=1    changed=0    unreachable=0    failed=0
2:如下:
---
- hosts: all
  gather_facts: False
  tasks:
    - name: config the loop
      debug: msg="name  ----->{{ item.key }} vlaue ----->{{ item.value }}"
      with_items:
      - { key: "one", value: "VALUE1" }
      - { key: "two", value: "VALUE2" }

[root@ansible-1 ansible]# ansible-playbook -i hosts loops-1.yaml 

PLAY [all] ***********************************************************

TASK [config the loop] *************************************************
ok: [192.168.124.129] => (item={u'key': u'one', u'value': u'VALUE1'}) => {
    "changed": false, 
    "item": {
        "key": "one", 
        "value": "VALUE1"
    }, 
    "msg": "name  -----> one  vlaue -----> VALUE1"
}
ok: [192.168.124.129] => (item={u'key': u'two', u'value': u'VALUE2'}) => {
    "changed": false, 
    "item": {
        "key": "two", 
        "value": "VALUE2"
    }, 
    "msg": "name  -----> two  vlaue -----> VALUE2"
}

PLAY RECAP **********************************************
192.168.124.129   : ok=1 changed=0    unreachable=0    failed=0   
3:使用loops创建目录,如下:
---
- hosts: all
  gather_facts: False
  tasks:
    - name: Ensuring config directories exist
      file:
        path: "{{ item }}"
        state: "directory"
        recurse: true
      with_items:
      - "/etc/os-net-config"
      - "/var/lib/os-net-config"
      - "/etc/wei/zhibiao/123/"
      check_mode: no
 #####################################################
 with_items:的特殊用法如下:
 - name: Copying files for keystone-ssh
  vars:
    keystone_ssh: "{{ keystone_services['keystone-ssh'] }}"
  template:
    src: "{{ item.src }}"
    dest: "{{ node_config_directory }}/keystone-ssh/{{ item.dest }}"
    mode: "0660"
  become: true
  with_items:
    - { src: "sshd_config.j2", dest: "sshd_config" }
    - { src: "id_rsa.pub", dest: "id_rsa.pub" }
  when:
    - inventory_hostname in groups[keystone_ssh.group]
    - keystone_ssh.enabled | bool
  notify:
    - Restart keystone-ssh container
同一个item定义 两个key,前后对应,src------> dest 
4:使用loops进行文件匹配,如下:不加班
---
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="files -----> {{ item }}"
      with_fileglob:
      - /etc/ansible/site-1.yml
5:随机选择loops使用,如下:
---
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="files -----> {{ item }}"
      with_random_choice:
      - "ansibel-1"
      - "ansible-2"
      - "ansible-3"
6:条件判断loops,如下:
---
- hosts: all
  gather_facts: False
  tasks:
    - name: if else
      shell: cat /etc/ansible/hosts
      register: host   ##将shel输出定义为变量
      until: host.stdout.startswith("Master")   ##判断变量是否是Master开头     
      retries: 5   ###重试次数
      deply: 5   ###重试时间间隔
      ignore_errors: True   ###如果有错误可以强制成功,继续执行下面的task。
      
输出结果如下:
TASK [if else] *****************************
FAILED - RETRYING: if else (5 retries left).
FAILED - RETRYING: if else (4 retries left).
FAILED - RETRYING: if else (3 retries left).
FAILED - RETRYING: if else (2 retries left).
FAILED - RETRYING: if else (1 retries left).
fatal: [192.168.124.129]: FAILED! => {"attempts": 5, "changed": true, 
"cmd": "cat /etc/ansible/hosts", "delta": "0:00:00.003797", "end": 
"2020-03-13 15:22:45.048290", "rc": 0, "start": "2020-03-13 15:22:45.044493",
 "stderr": "", "stderr_lines": [], "stdout": "# This is the default 
 ansible 'hosts' file.\n#\n# It should live in /etc/ansible/hosts\n#\n#  
  - Comments begin with the '#' character\n#   - Blank lines are ignored\n
  #   - Groups of hosts are delimited by [header] elements\n#   - 
  You can enter hostnames or ip addresses\n#   - A hostname/ip can be 
  a member of multiple groups\n\n# Ex 1: Ungrouped hosts, specify before 
  any group headers.\n\n## green.example.com\n## blue.example.com\n## 
  192.168.100.1\n## 192.168.100.10\n\n# Ex 2: A collection of hosts 
  belonging to the 'webservers' group\n\n## [webservers]\n## 
  alpha.example.org\n## beta.example.org\n## 192.168.1.100\n## 
  192.168.1.110\n\n# If you have multiple hosts following a pattern 
  you can specify\n# them like this:\n\n## www[001:006].example.com\n\n# 
  Ex 3: A collection of database servers in the 'dbservers' group\n\n## 
  [dbservers]\n## \n## db01.intranet.mydomain.net\n## 
  db02.intranet.mydomain.net\n## 10.25.1.56\n## 10.25.1.57\n\n# 
  Here's another example of host ranges, this time there are no\n# 
  leading 0s:\n\n## db-[99:101]-node.example.com\n[test]\n192.168.124.129 
  key=www ", "stdout_lines": ["# This is the default ansible 'hosts'
   file.", "#", "# It should live in /etc/ansible/hosts", "#", "#   - 
   Comments begin with the '#' character", "#   - Blank lines are ignored",
    "#   - Groups of hosts are delimited by [header] elements", "#   
    - You can enter hostnames or ip addresses", "#   - A hostname/ip can 
    be a member of multiple groups", "", "# Ex 1: Ungrouped hosts, 9 key=www "]}
	to retry, use: --limit @/etc/ansible/loops-1.retry

PLAY RECAP ******************************************
192.168.124.129            : ok=4    changed=0    unreachable=0    failed=1   

7:register loops,定义一个registry,多个tasks使用jinja2的for循环显示结果,如下:
---
- hosts: all
  gather_facts: False
  tasks:
    - name: debug lopps-1
      shell: "{{ item }}"
      with_items:
      - hostname
      - uname -a
      register: ret

    - name: dispaly loops
      debug: msg="{% for i in ret.results %} {{ i.stdout }} {% endfor %}"
;输出结果如下:
TASK [debug lopps-1] **********
changed: [192.168.124.129] => (item=hostname)
changed: [192.168.124.129] => (item=uname -a)

TASK [dispaly loops] ***********************************************
ok: [192.168.124.129] => {
    "msg": " ansible-1  Linux ansible-1 3.10.0-1062.el7.x86_64 #1 SMP Wed Aug 7 18:08:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux "
}

PLAY RECAP ************************************************************
192.168.124.129            : ok=6    changed=1    unreachable=0    failed=0   

8:with_dict:
举例如下:
---
- hosts: testB
  remote_user: root
  gather_facts: no
  vars:
    users:
      alice: female
      bob: male
  tasks:
  - debug:
      msg: "{{item}}"
    with_dict: "{{users}}"

从上述可以看出,变量users中的key为alice/bob,value为female/male
输出结果如下:
TASK [debug] ***********************************************
Tuesday 14 April 2020  11:11:44 +0800 (0:00:00.286)      0:00:00.286 ********* 
ok: [192.168.124.129] => (item={'value': {u'gender': u'male', u'name': u'Bob Jack', u'telephone': u'987-654-321'}, 'key': u'bob'}) => {
    "msg": {
        "key": "bob", 
        "value": {
            "gender": "male", 
            "name": "Bob Jack", 
            "telephone": "987-654-321"
        }
    }
}
ok: [192.168.124.129] => (item={'value': {u'gender': u'female', u'name': u'Alice Natasha', u'telephone': u'123-456-789'}, 'key': u'alice'}) => {
    "msg": {
        "key": "alice", 
        "value": {
            "gender": "female", 
            "name": "Alice Natasha", 
            "telephone": "123-456-789"
        }
    }
}

PLAY RECAP **********************************************
192.168.124.129            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
从输出信息可以看出,字典格式的users变量经过"with_dict"处理后,
字典中的每个键值对被放到了item变量中,而且,键值对中的"键"被放入了"key"关键字中,
键值对中的"值"被放入了"value"关键字中,所以,我们可以通过key关键字和value关键字
分别获取到字典中键值对的"键"和"值",示例playbook如下

扩展:
---
- hosts: testB
  remote_user: root
  gather_facts: no
  vars:
    users:
      alice:
        name: Alice Natasha
        gender: female
        telephone: 123-456-789
      bob:
        name: Bob Jack
        gender: male
        telephone: 987-654-321
  tasks:
  - debug:
      msg: "User {{item.key}} is {{ item.value.name }}, Gender: {{ item.value.gender }}, Tel: {{ item.value.telephone }}"
    with_dict: "{{users}}"
以上可以看出,value定义了name,gender,telephone,获取value的值。
每一个key需要有相同的value。
输出结果如下:
[root@ansible129 ansible]# ansible-playbook -i hosts  debug-1.yml 

PLAY [control] *************************************************************************************

TASK [debug] ***************************************************************************************
Tuesday 14 April 2020  11:17:24 +0800 (0:00:00.102)       0:00:00.102 ********* 
ok: [192.168.124.129] => (item={'value': {u'gender': u'male', u'name': u'Bob Jack', u'telephone': u'987-654-321'}, 'key': u'bob'}) => {
    "msg": "User bob is Bob Jack, Gender: male, Tel: 987-654-321"
}
ok: [192.168.124.129] => (item={'value': {u'gender': u'female', u'name': u'Alice Natasha', u'telephone': u'123-456-789'}, 'key': u'alice'}) => {
    "msg": "User alice is Alice Natasha, Gender: female, Tel: 123-456-789"
}

PLAY RECAP ********************************************************************************************
192.168.124.129            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Tuesday 14 April 2020  11:17:24 +0800 (0:00:00.358)       0:00:00.461 ********* 
=============================================================================== 

9:with_subelements复合变量
---
- hosts: testB
  remote_user: root
  gather_facts: no
  vars:
    users:
    - name: alice
      gender: female
      hobby:
        - Music
    - name: bob 
      gender: male
      hobby: 
        - Skateboard 
        - VideoGame
  tasks:
  - debug:
      msg: "{{item}}“
      msg: "{{item.0.name}}'s hobby is {{item.1}}"
    with_subelements: 
    - "{{users}}"
    - hobby
由于item由两个整体组成,所以,我们通过item.0获取到第一个小整体,
即gender和name属性,然后通过item.1获取到第二个小整体,即hobby列表中的每一项,    
输出结果如下:
TASK [debug] ***************************************************************
Tuesday 14 April 2020  15:31:53 +0800 (0:00:00.306)       0:00:32.743 ********* 
ok: [192.168.124.129] => (item=[{u'gender': u'female', u'name': u'alice'}, u'Music']) => {
    "msg": "alice's hobby is Music"
}
ok: [192.168.124.129] => (item=[{u'gender': u'male', u'name': u'bob'}, u'Skateboard']) => {
    "msg": "bob's hobby is Skateboard"
}
ok: [192.168.124.129] => (item=[{u'gender': u'male', u'name': u'bob'}, u'VideoGame']) => {
    "msg": "bob's hobby is VideoGame"
}

10:with_first_found遍历文件
- name: Copying over definitions.json
  become: true
  vars:
    service: "{{ rabbitmq_services['rabbitmq'] }}"
  template:
    src: "{{ item }}"
    dest: "{{ node_config_directory }}/{{ project_name }}/definitions.json"
    mode: "0660"
  with_first_found:   ###匹配存在的文件,不存在则不匹配
    - "{{ node_custom_config }}/rabbitmq/{{ inventory_hostname }}/definitions.json"
    - "{{ node_custom_config }}/rabbitmq/definitions.json"
    - "definitions.json.j2"
  when:
    - inventory_hostname in groups[service.group]
    - service.enabled | bool
  notify:
    - Restart rabbitmq container (first node)
    - Restart rabbitmq container (rest of nodes)
注释:当使用notify时,如需要立刻执行时,则添加如下:
- name: Flush handlers
  meta: flush_handlers    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值