杨梅冲
每天在想什么呢?

一、流程控制

handler 触发器
when  流程判断控制
loop/with_items

1.1 handler 触发器

  配置变更后需要触发后续操作

  应用场景:一般用于分发配置文件的时候.

  如果配置文件发生变化则重启服务,如果没有变化则不重启.

  例如:

    1.服务重启:当配置文件(如 Nginx、Apache、SSHd 的配置)被修改后,只有当文件内容确实发生改变时,才重启相关服务以加载新配置。如果配置文件未变,则不重启,避免不必要的服务中断。

    2.系统重启‌:在安装内核更新或某些关键软件包后,只有在确实安装了新版本(状态为 Changed)时才触发系统重启。

    3.资源清理或刷新‌:例如在更改防火墙规则后重载防火墙服务,或在更改数据库配置后刷新权限。

# 案例: 没有使用触发器handlers,不管exports配置文件是否有更新,都会重启
- hosts: all 
  tasks:
    - name: 分发配置文件
      copy:
        src: exports
        dest: /etc/exports
        backup: yes
    - name: 重启服务
      systemd:
        name: nfs
        state: reloaded

#使用handler后,如果配置文件没有变化,就不重启服务
- hosts: backup
  gather_facts: no
  tasks:
    - name: 分发配置文件
      copy:
        src: files/exports
        dest: /etc/exports
        backup: yes
      notify:
        - 重启服务
  handler:
  - name: 重启服务
    systemd:
      name: nfs
      state: reloaded


小结:
 handlers触发器,应用场景:配置文件发生变化,然后重启服务(或做其他).
 格式: 埋雷:设置绊雷(notify: 写个名字) , handlers设置名字和模块
 注意事项: handlers放在剧本的最后,否则都会被识别为handlers .

1.2 when 判断

  用于给ans运行的task(模块)设置条件,满足或不满足条件在运行对应的模块.

  应用建议: when进行判断,一般与变量一起使用.

  when条件一般与facts变量或register变量一起使用.

# 举例:只想给gw组的服务器安装软件
[ywmonitor]
172.31.0.1

# 只让主机名为ywmonitor的主机输出信息
- hosts: all
  tasks:
    - name: 只给ywmonitor输出信息
      debug:
        msg: "this is ywmonitor, installing..."
      when:
        ansible_hostname == "ywmonitor"

# ansible-playbook when.yml执行结果
PLAY [all] *******************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************
ok: [172.31.0.1]
ok: [172.31.0.2]
ok: [172.31.0.3]

TASK [只给ywmonitor输出信息] *************************************************************************************************************
ok: [172.31.0.1] => {
    "msg": "this is ywmonitor, installing..."
}
skipping: [172.31.0.2]
skipping: [172.31.0.3]
PLAY RECAP *******************************************************************************************************************************
172.31.0.2               : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
172.31.0.1              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0        
172.31.0.3               : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
小结:
 when用于进行判断,满足/不满足条件就执行对应的模块(不满足条件的主机提示skip).
 when一般与变量一起使用.
 符号  is match   is not match
 (条件1)  and  (条件2)
 (条件1)   or  (条件2)
举例:
not(非)条件取反
  when: not ansible_hostname == "db01"
  # 或者 when: ansible_hostname != "db01"

- hosts: all
  tasks:
    - name: CentOS系统安装sl,cowsay,tree
      yum:
        name: sl,cowsay,tree
        state: present
      when: #条件1 条件2 同时成立相当于使用and .
        - ansible_distribution  "CentOS"
        - ansible_hostname is match("gw|ywmonitor")
- hosts: all 
  tasks:
    - name: CentOS系统安装sl,cowsay,tree 
      yum:
        name: sl,cowsay,tree
        state: present
      when: ansible_distribution  "CentOS"  or ansible_hostname is match("web|backup")

1.3 循环

  2类循环:

    with_items

    loop

    一般应用场景:批量创建文件,批量添加用户,批量启动或重启服务.

- hosts: nfs
  gather_facts: no
  tasks:
    - name: 分发文件
      copy:
        src: exports
        dest: /etc/exports
        backup: yes
    - name: 重启rpcbind,nfs
      systemd:
        name: "{{ item }}"
        state: restarted
      with_items:
        - rpcbind
        - nfs
# 案例: 批量启动服务 rpcbind 然后nfs服务
- hosts: www
  gather_facts: false 
  tasks:
    - name: 重启服务
      systemd:
        name: "{{ item }}"
        state: restarted
      loops:
        - rpcbind
        - nfs

loop和with_items用法一致

# 循环多个变量例子
批量添加多个用户
xc1 2020
xc2 2021
xc3 2022

# loop.yml
- hosts: all
  gather_facts: false
  tasks:
    - name: add user
      user:
        name: "{{ item .name }}"
        uid:  "{{ item .uid  }}"
        state: present
      loop:
        - { name: 'xc1', uid: 2020  }
        - { name: 'xc2', uid: 2021  }
        - { name: 'xc3', uid: 2022  }

小结
 with_items和loop .
 大部分使用单个变量即可.
 官方传送门

优化nfs安装:

- hosts: nfs
  gather_facts: no
  tasks:
    - name: 分发文件
      copy:
        src: exports
        dest: /etc/exports
        backup: yes
    - name: 重启rpcbind,nfs
      systemd:
        name: "{{ item }}"
        state: restarted
      with_items:
        - rpcbind
        - nfs
[ec2-user@ywmonitor other]$ vim nfs2.yaml
[ec2-user@ywmonitor other]$ vim nfs2.yaml
[ec2-user@ywmonitor other]$ cat nfs2.yaml 
- hosts: backup
  tasks:
  - name: 01 . 部署nfs-utils,rpcbind
    yum:
      name: {{ item }}
      state: present
    loops:
      - nfs-utils
      - rpcbind
  - name: 02 . 修改配置文件
    lineinfile:
      path: /etc/exports
      line: "/backup-nfs 172.16.1.0/24(rw,all_squash)"
      create: true
  - name: 03 . 创建共享目录并改所有者
    file:
      path: /backup-nfs
      owner: ec2-user
      group: ec2-user
      state: directory
  - name: 04. 启动服务rpcbind,nfs(注意顺序)
    systemd:
      name:{{ item }}
      enabled: yes
      state: started
    loops:
      - rpcbind
      - nfs
#nfs客户端部署
- hosts: web
  tasks:
    - name: 01 . 部署nfs-utils
      yum:
        name: nfs-utils
        state: present
    - name: 02 . 挂载nfs
      mount:
        src: 172.16.1.41:/backup-nfs
        path: /ans-upload
        fstype: nfs
        state: mounted
nfs_loops安装

小结:

handler触发器:xxx配置变化,要做xxxx事情.

when判断: 给模块/剧本执行的时候加个条件. 判断系统版本,判断主机名.

循环:loop,with_items 进行 批量 的操作,用户,目录,复制

二、剧本调试

  剧本单步执行

  tag标签

  忽略错误

2.1 检查语法与单步执行

-c   check 模拟运行,不作出改变,一些变量可能会提示报错,因为-C没有真正运行剧本
--syntax-check 只做语法检查,不运行.
高级:step 单步运行. y执行这个task,n忽略这个task,c自动运行

2.2 tag标签

  tag标签类似于超市物品的分类,只不过tag标签是给ansible中的task进行:分类、加上标记

  运行剧本的时候运行指定的tag标签或排除某些tag .

- hosts: ywmonitor
  tasks:
  - name: 01 . 部署nfs-utils,rpcbind
    yum:
      name: nfs-utils,rpcbind
      state: present
    tags:
      - 01.install
  - name: 02 . 修改配置文件
    lineinfile:
      path: /etc/exports
      line: "/backup-nfs 172.16.1.0/24(rw,all_squash)"
      create: true
    tags:
      - 02.conf
  - name: 03 . 创建共享目录并改所有者
    file:
      path: /backup-nfs
      owner: ec2-user
      group: ec2-user
      state: directory
    tags:
      - 03.dir
  - name: 04. 启动服务rpcbind,nfs(注意顺序)
    systemd:
      name: "{{ item }}"
      enabled: yes
      state: started
    loop:
      - rpcbind
      - nfs
    tags:
      - 04.start_srv
#nfs客户端部署
- hosts: www
  tasks:
    - name: 01 . 部署nfs-utils
      yum:
        name: nfs-utils
        state: present
    - name: 02 . 挂载nfs
      mount:
        src: 172.16.1.41:/backup-nfs
        path: /ans-upload
        fstype: nfs
        state: mounted
nfs-tag.yaml
运行剧本的时候
-t 运行的标签,如果多个标签通过","分割
--skip-tags 排除指定的tags,如果多个标签通过","分割

ansible-playbook --help
#list-tags显示剧本中所有的tags标签
ansible-playbook -i hosts list-tags   -C nfs-tag.yml

#通过-t运行指定的tag标签,多个标签通过,分割
# 查看有那些tag
ansible-playbook --list-tags  -C nfs-tag.yml
playbook: nfs-tag.yml

  play #1 (ywmonitor): ywmonitor        TAGS: []
      TASK TAGS: [01.install, 02.conf, 03.dir, 04.start_srv]

  play #2 (www): www    TAGS: []
      TASK TAGS: []
# 例如只运行第4步
ansible-playbook -t 04.start_srv  -C nfs-tag.yml

 2.3 忽略错误

  运行剧本的时候,因为重复运行导致的错误提示,并发是真的错误.

  比如:目录已经存在,用户已经存在.

  在这种情况下,我们可以通过ignore_errors忽略错误,让剧本可以继续运行.

ignore_errors: true
true /false
yes/no
  - name: 01 . 部署nfs-utils,rpcbind
    yum:
      name: nfs-utils,rpcbind
      state: present
    tags:
      - 01.install
    ignore_errors: True

剧本调试小结:

常见: 一般有密钥认证问题.
 常见问题:剧本本身
 检查语法-C
 tag标签
 单行执行:step
 忽略错误

 

posted on 2026-05-16 22:53  杨梅冲  阅读(13)  评论(0)    收藏  举报