当前位置:网站首页>Ansible 学习总结(9)—— Ansible 循环、条件判断、触发器、处理失败等任务控制使用总结

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

2022-07-07 15:40:00 科技D人生

一、简单循环

使用 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 模块

 

原网站

版权声明
本文为[科技D人生]所创,转载请带上原文链接,感谢
https://zhanghaiyang.blog.csdn.net/article/details/125654136