Ansible 学习总结—— Ansible 循环条件判断触发器处理失败等任务控制使用总结

Posted 科技D人生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ansible 学习总结—— Ansible 循环条件判断触发器处理失败等任务控制使用总结相关的知识,希望对你有一定的参考价值。

一、简单循环

使用 loop 赋值列表的格式:

loop:  ##赋值列表
- value1
- value2
- ...
item  ##迭代变量名称

在 playbook 中使用

vim user.yml

---
- name: create user
  hosts: server2
  tasks:
    - name: create user
      user:
        name: "item"  ##迭代变量名称
        state: present
      loop:  ##赋值列表
        - user1
        - user2
        - user3

建立用户成功 

 定义变量

vim user_list.yml

---
USERS:  ##定义变量
  - user1
  - user2
  - user3

编写 yaml 文件

vim user.yml

---
- name: create user
  hosts: server2
  vars_files: ./user_list.yml
  tasks:
    - name: create user
      user:
        name: "item"
        state: absent
        remove: yes
      loop:
        "USERS"  ##此处赋值时不用加-

删除用户成功

二、循环散列或字典列表

赋予不同的服务不同的状态

示例:为 server3 主机建立用户,并赋予密码(此处的密码必须是加密过后的,使用 rhel8 的 openssl passwd -6 将密码加密)。

vim user.yml

---
- name: create user
  hosts: server3
  tasks:
    - name: create user
      user:
        name: " item.user "
        password: " item.passwd "
        state: present
      loop:
        - user: user1
          passwd: "$6$P2MmG.dGe59uEe0R$SVmq6oojHWvYVK.BZhmL7pWjb7zVKRkUM.Rp2kFbLtl7jS570ZClaVPRZkX9BtfkqlLLCbTrlG7a04YRi/wz3."
        - user: user2
          passwd: "$6$YZcSU4GwSVBnw.ro$wQ0fAO9lB2M1Nwu9tVyBoGiEV/qOzQGBY.UHw2pQiq0GEjYpNW3c2FtG/wWZ0iVpqZi.iCo1x18LjpJg9tGTK/"
        - user: user3
          passwd: "$6$lqv/hz7ynndCR9NR$BmhKzFUsW4XzP9x9eAXv782gYBnxWUGFnh1qYExYwof5PSPk36GnlDKjjeygCSohM0cpncmk.1mkljEAgX3FQ1"

测试连接: 

三、条件判断

两种条件同时满足

when:
- 条件1
- 条件2

满足其中一个条件

when:
- 条件1 or 条件2

# 也可以表示为
when:
- 条件1
  or
  条件2

 示例:检测文件是否存在(ignore_errors: yes:当文件不存在时,系统会判定失败,没有返回值,加此参数可以忽略错误)。

vim exist.yml

---
- name: test
  hosts: demo
  tasks:
    - name: test
      shell: test -e /mnt/file  ##使用shell模块检测文件是否存在
      ignore_errors: yes
      register: OUTPUT  ##将得到的结果注册给OUTPUT变量
      
    - name: show message
      debug:
        msg: /mnt/file is exist
      when: OUTPUT.rc == 0  ##输出的结果rc部分为0,文件存在
      
    - name: show message
      debug:
        msg: /mnt/file is not exist
      when: OUTPUT.rc == 1  ##输出的结果rc部分为1,文件不存在

在 server4 主机上创建 /mnt/file,在 server2 和 server3 上不创建,执行 yaml 文件

条件判断定义

 示例:添加磁盘,利用条件语句对磁盘进行检测(为 server2 主机添加磁盘

通过 ansible 语句可以检测到

ansible server2 -m shell -a "fdisk -l /dev/vdb"

编写 yaml 文件,检测是否存在 vdb 磁盘

vim vdb.yml

---
- name: test
  hosts: demo
  tasks:
    - name: show message
      debug:
        msg: /dev/vdb is exist
      when:
        - ansible_facts['devices']['vdb'] is defined  ##vdb存在时
        - inventory_hostname in "server2"  ##hostname为server2时,与上面条件须同时满足
        
    - name: show message
      debug:
        msg: /dev/vdb is not find
      when:
        - ansible_facts['devices']['vdb'] is not defined
          or
          inventory_hostname not in "server2"  ##vdb不存在或hostname不为server2时,也可以写到一行

执行 yaml 文件,得到结果

三、触发器

  • notify:触发器当遇到更改时触发 handlers
  • handlers:触发器触发后执行的动作

示例:安装下载 vsftpd 并修改访问家目录(编写 yaml 文件

vim vsftpd.yml

---
- name: vsftpd
  hosts: server4
  tasks:
    - name: install vsftpd
      yum:
        name: vsftpd
        state: present
    - name: start vsftpd
      service:
        name: vsftpd
        state: started
        enabled: yes
      notify:
        - firewalld  ##当vsftpd服务被设定开机自启后,触发firewalld模块

    - name: vsftpd.conf
      lineinfile:
        path: /etc/vsftpd/vsftpd.conf
        line: "anon_root=/mnt"  ##修改访问家目录
        regexp: "^anon_root"  ##替换的行
        backrefs: no  ##匹配到时替换,没匹配到时,文件结尾添加一行
      notify:
        - restart vsftpd  ##当文件替换后,触发模块重启服务

  handlers:  ##被触发后的模块,注意此处与tasks对齐
   - name: firewalld
     firewalld:
       service: ftp
       state: enabled
       permanent: yes
       immediate: yes
   - name: restart vsftpd
     service:
       name: vsftpd
       state: restarted

执行 yaml 文件

在 server4 的 /mnt/file 中添加内容,匿名访问测试 

四、 处理失败任务

ignore_errors

作用:当 play 遇到任务失败时会终止(ignore_errors: yes 将会忽略任务失败使下面的任务继续运行)

示例:安装一个不存在的服务

vim ignore.yml

---
- name: ignore_errors
  hosts: server3
  tasks:
    - name: install haha
      yum:
        name: haha
        state: present
      ignore_errors: yes  ##忽略错误
        
    - name: debug
      debug:
        msg: heloo lll

force_handlers

作用:当任务失败后 play 被终止也会调用触发器进程

示例:安装一个不存在的服务,任务失败 play 终止后仍会有触发(注意去除 ignore_errors: yes 的干扰

vim force.yml

---
- name: force_handlers
  hosts: server3
  force_handlers: yes  ##任务失败后仍触发
  tasks:
    - name: hostname
      shell:
        hostname
      register: info  ##使用注册变量
      notify:
        - debug

    - name: install haha
      yum:
        name: haha
        state: present

  handlers:
    - name: debug
      debug:
        msg: " info['stdout'] "  ##展示变量info的输出变量

changed_when

作用:控制任务在何时报告它已进行更改,抑制更改

示例:测试 changed_when: true

vim changed.yml

---
- name: test
  hosts: server4
  tasks:
    - name: install vsftpd
      yum:
        name: vsftpd
        state: present
      changed_when: true  ##当检测到vsftpd安装后(无论是刚安装还是之前已安装),报告发生改变

server4 的 vsftpd 之前已经安装,应该显示为绿色,但此处显示为黄色

示例:测试 changed_when: false

vim changed.yml

---
- name: test
  hosts: server4
  tasks:
    - name: remove vsftpd
      yum:
        name: vsftpd
        state: absent
      changed_when: false  ##当检测到vsftpd被卸载时,报告不改变

此处卸载了 vsftpd,应该有改变为黄色,但这里为绿色

failed_when

作用:当符合条件时强制任务失败,但不会更改任务本身的行为

示例:建立文件,报错,但实质已经建立

vim failed.yml

---
- name: test
  hosts: server2
  tasks:
    - name: touch file
      file:
        path: /mnt/failedfile
        state: touch
      failed_when: true  ##当文件创建后报错

但实际文件创建成功

例:在不存在的目录下创建文件,却报告成功 

vim failed.yml

---
- name: test
  hosts: server2
  tasks:
    - name: touch file
      file:
        path: /mnt/haha/linuxfile
        state: touch
      failed_when: false  ##当文件未创建时不报错

文件自然没有创建

block

  • block:定义要运行的任务
  • rescue:定义当block句子中出现失败任务后运行的任务
  • always:定义最终独立运行的任务

示例 1:此时 /mnt/file 存在

vim block.yml

---
- name: test
  hosts: server4
  tasks:
    - name: check file
      block:
        - name: test
          shell: test -e /mnt/file
        - name: debug
          debug:
            msg: /mnt/file is exist
            
      rescue:
        - name: debug
          debug:
            msg: /mnt/file is not exist
            
      always:
        - name:
          debug:
            msg: good night!

所以 block 句子中没有失败,所以不会执行 rescue 模块 

示例 2:此时 /mnt/file 不存在,再次执行 block.yml,因为 block 句子中有失败,所以执行 rescue 模块

 

以上是关于Ansible 学习总结—— Ansible 循环条件判断触发器处理失败等任务控制使用总结的主要内容,如果未能解决你的问题,请参考以下文章

Ansible 学习总结—— Ansible 控制提权相关知识总结

Ansible 学习总结—— Ansible 控制提权相关知识总结

Ansible 学习总结—— Ansible 入门详解

Ansible 学习总结—— Ansible 入门详解

Ansible 学习总结—— Ansible 状态管理相关知识总结

Ansible 学习总结—— Ansible 状态管理相关知识总结