实施任务-循环

编写循环

简单循环

  • 简单循环对一组项目迭代任务
  • loop关键字添加到任务中,将应对其迭代任务的项目列表取为值
  • 循环变量item保存每个迭代过程中使用的值

请思考以下代码片段,它使用两次service模块来确保两个网络服务处于运行状态:

- name: Postfix is running
  service:
    name: postfix
    state: started
    
- name: Devecot is running
  service:
    name: dovecot
    state: started

这两个任务可以重新编写为使用一个简单循环,从而只需一个任务来确保两个服务都在运行:

- name: Postfix and Devecot are running
  service:
    name: "{{ item }}"
    state: started
  loop:
    - postfix
    - dovecot
  • 使用简单循环批量创建用户
//编写playbook
[root@192 playbook]# vim user.yml 

---
- hosts: 192.168.218.128
  vars_files:
    - vars/user.yml
  tasks:
    - name: creat user
      user:
        name: "{{ item }}"
        state: present

      loop: 
        - tom1
        - tom2
        - tom3
        - tom4
        - tom4
        - tom5

//执行
[root@192 playbook]# ansible-playbook  user.yml 

//检查
[root@localhost ~]# id tom1
uid=6003(tom1) gid=6003(tom1) groups=6003(tom1)
[root@localhost ~]# id tom2
uid=6004(tom2) gid=6004(tom2) groups=6004(tom2)
[root@localhost ~]# id tom3
uid=6005(tom3) gid=6005(tom3) groups=6005(tom3)
...
  • 使用变量和循环,批量创建用户
//编写变量,创建tom1-tom8八个用户
[root@192 vars]# vim user.yml 
user:
  - tom1
  - tom2
  - tom3
  - tom4
  - tom5
  - tom6
  - tom7
  - tom8

//编辑playbook
[root@192 playbook]# vim user.yml 

---
- hosts: 192.168.218.128
  vars_files:
    - vars/user.yml
  tasks:
    - name: creat user
      user:
        name: "{{ item }}"
        state: present

      loop: "{{ user }}"

//执行playbook
[root@192 playbook]# ansible-playbook  user.yml 

//检查
[root@localhost ~]# id tom1
uid=6003(tom1) gid=6003(tom1) groups=6003(tom1)
[root@localhost ~]# id tom2
uid=6004(tom2) gid=6004(tom2) groups=6004(tom2)

循环散列或字典列表

//不使用变量
---
- hosts: 192.168.218.128
  tasks:
    - name: creat user
      user:
        name: "{{ item.name }}"
        uid: "{{ item.uid}}"
        state: absent

      loop:
        - name: tom1
          uid: 2100
        - name: tom2
          uid: 2111
          
//使用变量
//编辑变量
[root@192 vars]# vim user.yml 
user:
  - name: tom1
    uid: 2011
  - name: tom2
    uid: 2010

//编辑playbook
[root@192 playbook]# vim user.yml  

---
- hosts: 192.168.218.12
  vars_files:
    - vars/user.yml
  tasks:
    - name: creat user
      user:
        name: "{{ item.name }}"
        uid: "{{ item.uid}}"
        state: absent

      loop: "{{ user }}"


有条件地运行任务

在Ansible中使用条件的情况:

  • 可以在变量中定义硬限制(如min_memory)并将它与受管主机上的可用内存进行比较
  • Ansible可以捕获并评估命令的输出,以确定某一任务在执行进一步操作前是否已经完成。例如,如果某一程序失败,则将路过批处理
  • 可以利用Ansible事实来确定受管主机网络配置,并决定要发送的模板文件(如,网络绑定或中继)
  • 可以评估CPU的数量,来确定如何正确调节某一Web服务器
  • 将注册的变量与预定义的变量进行比较,以确定服务是否已更改。例如,测试服务配置文件的MD5检验以和查看服务是否已更改

条件任务语法

  • when语句用于有条件地运行任务

  • 取要测试的条件为值

  • 如果条件满足,则运行任务。如果条件不满足,则跳过任务

  • 可以测试的一个最简单条件是某一布尔变量是True还是False

//使用条件语句安装服务
//编写playbook
[root@192 playbook]# vim test.yml 

---
- hosts: 192.168.218.128
  vars:
    install: true   //若设为false,下面的任务将不会执行
  tasks:
    - name: install service
      yum:
        name: vsftpd
        state: present
      when: install
      
//检查
[root@192 playbook]# ansible-playbook test.yml 
[root@localhost ~]# rpm -qa |grep vsftpd
vsftpd-3.0.3-34.el8.x86_64  //变量为true时安装服务成功

  • 以下示例测试service_name变量是否具有值。若有值,则将service_name的值用作要安装的软件包的名称。如果未定义service_name变量,则跳过任务且不显示错误。
//定义service_name测试
[root@192 playbook]# vim test.yml 

---
- hosts: 192.168.218.128
  vars:
    service_name: vsftpd
  tasks:
    - name: install service
      yum:
        name: "{{ service_name }}" //引用变量
        state: present
      when: service_name is defined   //service_name被定义,安装服务任务将执行
      
//查看
[root@192 playbook]# ansible-playbook test.yml 
[root@localhost ~]# rpm -qa |grep vsftpd
vsftpd-3.0.3-34.el8.x86_64  //安装服务成功


//测试不定义service_name,执行看是否跳过
[root@192 playbook]# vim test.yml 

---
- hosts: 192.168.218.128
  vars:    //变量下没有定义service_name
  tasks:
    - name: install service
      yum:
        name: "{{ service_name }}"
        state: present
      when: service_name is defined
      
//查看
[root@192 playbook]# ansible-playbook test.yml 

PLAY [192.168.218.128] ********************************************************************

TASK [Gathering Facts] ********************************************************************
ok: [192.168.218.128]

TASK [install service] ********************************************************************
skipping: [192.168.218.128]   //skipping代表跳过,没有安装服务,跳过了,但是没有报错

PLAY RECAP ********************************************************************************
192.168.218.128            : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0  
[root@localhost ~]# rpm -qa |grep vsftpd
[root@localhost ~]# 


//总结:要想执行条件任务,变量中中的值需要设置为true;如果在条件中使用是否被定义,变量中需要定义变量,否则将跳过,不执行任务

下表显示在处理条件中可使用的一些算法:
示例条件:

操作示例
等于(值为字符串)ansible_machine == “x86_64”
等于(值为数字)max_memory == 512
小于min_memory < 128
大于min_memory > 256
min_memory > 256min_memory <= 256
大于等于min_memory >= 512
不等于min_memory != 512
变量存在min_memory is defined
变量不存在min_memory is not defined
布尔变量是True。1、True或yes的求值为Truememory_available
布尔变量是False。0、False或no的求值为Falsenot memory_available
第一个变量的值存在,作为第二个变量的列表中的值ansible_distribution in supported_distros

举例演示:

//想要在CentOS系统上安装服务vsftpd,若没有则跳过,定义变量系统名称时严格区分大小写,CentOS和centos不一样

---
- hosts: 192.168.218.128
  vars:
    platform:
      - redhat
      - CentOS
  tasks:
    - name: install service
      yum:
        name: vsftpd
        state: present
      when: ansible_facts['distribution'] in platform
      
//检查
[root@192 playbook]# ansible-playbook test.yml 
[root@localhost ~]# rpm -qa |grep vsftpd
vsftpd-3.0.3-34.el8.x86_64
     
//下面演示条件没有匹配到,跳过,不安装
[root@192 playbook]# vim test.yml 

---
- hosts: 192.168.218.128
  vars:
    platform:
      - redhat
      - centOS   //把CentOS改为centos
  tasks:
    - name: install service
      yum:
        name: vsftpd
        state: present
      when: ansible_facts['distribution'] in platform
      
//检查
[root@192 playbook]# ansible-playbook test.yml 

PLAY [192.168.218.128] ********************************************************************

TASK [Gathering Facts] ********************************************************************
ok: [192.168.218.128]

TASK [install service] ********************************************************************
skipping: [192.168.218.128]   //显示了跳过,没有执行安装任务

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

//检查受管主机是否安装服务
[root@localhost ~]# rpm -qa |grep vsftpd
[root@localhost ~]# 

测试多个条件

  • 一个when语句可用于评估多个条件。使用and和or关键字组合条件,并使用括号分组条件。

  • 如果任一条件为真时满足条件语句,则应当使用or语句。例如,如果计算机上运行的是redhat或CentOS,则下述条件得到满足:

when: ansible_facts['distrbution'] =='redhat' or ansible_facts['distrbution'] =='CentOS'
  • 使用and运算时,两个条件都必须为真,才能满足整个条件语句。例如,如果远程主机是CentOS主机,并且安装的内核是指定版本8,则将满足以下条件:
when: ansible_facts['distribution'] == CentOS and ansible_facts['distribution']['version'] == 8
//若满足上述条件则执行任务,否则跳过
  • when关键字还支持使用列表来描述条件列表。向when关键字提供列表时,将使用and运算组合所有条件。下面的示例演示了使用and运算符组合多个条件语句的另一方式:
when:
  - ansible_facts['distribution'] == 'CentOS'
  - ansible_facts['distribution']['version'] == '8'

//这种格式提高了可读性,而可读性是良好编写Ansible Playbook的关键目标
  • 通过使用括号分组条件,可以表达更复杂的条件语句。例如,如果计算机上运行的是红帽企业Linux7或Fedora28,则下述条件语句得到满足。此示例使用大于字符,这样长条件就可以在playbook中分成多行,以便于阅读。
when: >
  (ansible_facts['distribution'] == 'CentOS' and ansible_facts['distribution']['version'] == '8')
  or
  (ansible_facts['distribution'] == 'redhat' and ansible_facts['distribution']['version'] == '7')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值