ansible 流程控制

playbook 条件语句

不管是 shell 还是各大编程预言中,流程控制,条件判断都是必不可少的,在我们使用 Ansible 的过程中,条件判断的使用频率都非常高。


例如:

1. 我们使用不同的系统的时候,可以通过判断系统 来对软件包进行安装。

2. 在 nfs rsync 安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play,会影响效率。

3. 我们在源码安装nginx 的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。

根据不同的操作系统安装apache

官方示例:

tasks:
- name: "shut down Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_facts['os_family'] == "Debian"
# note that all variables can be used directly in conditionals without double curly braces

示例: 根据不同的 系统安装不同的服务

- hosts: web_group
tasks:
- name: Install CentOS Htt
state: present
#官方
when: ansible_facts['os_family'] == "CentOS"
#非官方
when: ansible_distribution == "CentOS" - name: Install Ubuntu Httpd
yum:
name: apache2
state: present
when: ansible_facts['os_family'] == "Ubuntu"

可以使用括号对条件进行分组

tasks:
- name: "shut down CentOS 6 and Debian 7 systems"
command: /sbin/shutdown -t now
when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or
(ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")

可以指定多条件为列表

tasks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == "6"

条件运算

tasks:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6

rsync服务端推送配置文件

[root@m01 ~]# cat rsyncd/rsyncd.yml
- hosts: rsync_server
tasks:
- name: Install Rsyncd Server
yum:
name: rsync
state: present - name: Create www Group
group:
name: www gid: 666
- name: Create www User
user:
name: www
group: www
uid: 666
create_home: false
shell: /sbin/nologin - name: Scp Rsync Config
copy:
src: ./rsyncd.j2
dest: /etc/rsyncd.conf
owner: root
group: root
mode: 0644
when: ansible_hostname == "backup" - name: Create Passwd File
copy:
content: 'rsync_backup:123'
dest: /etc/rsync.passwd
owner: root
group: root
mode: 0600
when: ansible_hostname == "backup" - name: Create backup Directory
file:
path: /backup
state: directory
mode: 0755
owner: www
name: rsyncd
state: started
when: ansible_hostname == "backup"

rsync客户端推送脚本

[root@m01 ~]# vim rsync.yml
- hosts: rsync_server
tasks:
- name: SCP Backup Shell
copy:
src: ./backup.sh
dest: /root/backup.sh
when: ansible_hostname is match "web*" #执行结果
PLAY [rsync_server] ************************************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [web02]
ok: [backup]
ok: [web01] TASK [SCP Backup Shell] **********************************************************************************************************************************************************************************************************************
skipping: [backup]
changed: [web01]
changed: [web02] PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
backup : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
web01 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

通过register将命令执行结果保存至变量,然后通过when 语句进行判断

- hosts: web_group
tasks:
- name: Check Httpd Server
command: systemctl is-active httpd
ignore_errors: yes
register: check_httpd - name: debug outprint
debug: var=check_httpd - name: Httpd Restart
service:
name: httpd
state: restarted
when: check_httpd.rc == 0

使用when判断主机名

- hosts: rsync_server
tasks: - name: Install rsyncd Server
yum:
name: rsync
state: present - name: Config rsyncd Conf
copy:
src: ./rsyncd.j2
dest: /etc/rsyncd.conf
owner: root
group: root
mode: 0644
when: ansible_fqdn == 'backup' - name: Create dir
file:
path: /backup
state: directory
owner: www
group: www
mode: 0755
recurse: yes
when: ansible_fqdn == 'backup' - name: Create passwd file
copy:
content: "rsync_backup:123"
dest: /etc/rsync.passwd
owner: root
group: root
mode: 0600
when: ansible_fqdn == 'backup' #单条件判断
- name: Start rsyncd
systemd:
name: rsyncd
state: started
enabled: yes
when: ansible_fqdn == 'backup' #多条件判断,使用小括号分组
- name: copy shell
template:
src: ./backup.sh
dest: /root
when: (ansible_fqdn == 'web01') or (ansible_fqdn == 'web02') #多条件判断,使用list列表形式
- name: copy shell
template:
src: ./backup.sh
dest: /root
when:
- ansible_fqdn == 'web01'
- ansible_fqdn == 'web02' #多条件判断,使用is match 支持通配符
- name: Add Crontab
cron:
name: "backup"
minute: "00"
hour: "01"
job: "/bin/sh /root/backup.sh &>/dev/null"
when: ansible_fqdn is match 'web*'

2.使用when判断系统

- hosts: webs
tasks:
- name: Install CentOS Apache
yum:
name: httpd
state: present
when: ansible_distribution == 'CentOS' - name: Install Ubuntu Apache
apt:
name: apache2
state: present
when: ansible_distribution == 'Ubuntu'

3.使用when判断系统版本

- hosts: webs
tasks:
- name: Start CentOS6 Httpd
shell: "/etc/init.d/httpd start"
when: ansible_distribution_major_version == '6' - name: Start CentOS7 Httpd
shell: "systemctl start httpd"
when: ansible_distribution_major_version == '7'

4.使用注册变量对返回值进行判断

    - name: pan duan rpm bao
shell: "rpm -qa|grep php"
register: check_php - name: Install php
shell: "cd /usr/local/src && rpm -Uvh *rpm"
when: check_php.rc != 0

playbook 循环语句

创建目录之类的操作,2个目录就要写两个file 模块来创建,如果有循环,可以减少重复性代码。

1.启动多个服务

- hosts: web_group
tasks:
- name: start service
systemd:
name: "{{ item }}"
state: started
with_items:
- httpd
- php-fpm
- mariadb

2.定义变量循环

- name: ensure a list of packages installed
yum:
name: "{{ packages }}"
vars:
packages:
- httpd
- httpd-tools
- hosts: web_group
tasks:
- name: ensure a list of packages installed
yum: name= "{{ item }}" state=present
with_items:
- httpd
- httpd-tools

3.字典循环

拷贝文件

- hosts: web_group
tasks:
- name: copy conf and code
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- { src: "./httpd.conf", dest: "/etc/httpd/conf/", mode: "0644" }
- { src: "./upload_file.php", dest: "/var/www/html/", mode: "0600" }
    - name: tar php and nginx and wordpress
unarchive:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ item.user }}"
group: "{{ item.user }}"
copy: yes
with_items:
- { src: "./php.tgz", dest: "/usr/local/src", user: "root" }
- { src: "./nginx-1.16.0.tar.gz", dest: "/root", user: "root" }
- { src: "./wordpress.tgz", dest: "/code", user: "www" }

ansible handlers(触发器)

handler 用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify 触发 handler去重启服务。

在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。

实践案例:

    - name: scp nginx shell conf
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
with_items:
- { src: "./nginx.service", dest: "/usr/lib/systemd/system" }
- { src: "./nginx.conf", dest: "/usr/local/nginx/conf/" }
- { src: "./www.drz.com.conf", dest: "/usr/local/nginx/conf/conf.d" }
#添加触发器
notify: reload nginx handlers:
- name: reload nginx
systemd:
name: nginx
state: reloaded

注意:

1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。

2.Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。

3.Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers。

4.如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的--force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。

5.不能使用handlers替代tasks

playbook任务标签

默认情 况下,Ansible 在执行一个playbook 时,会执行playbook中定义的所有任务,Ansible的标签 (tag)功能可以给单独任务甚至整个playbook 打上标签,然后利用这些标签来指定要运行playbook中的个别任务,或不执行制定的任务。

打标签的方式

  1. 对一个task打一个标签
  2. 对一个task打多个标签
  3. 对多个task打一个标签

打完标签如何使用

-t : 指定的tag标签任务

--skip-tags : 执行--skip-tags之外的标签任务

使用 - t 指定 tag

[root@m01 m01]# cat tag.yml
- hosts: web_group
vars:
- http_port: 8080
tasks:
- name: Install Http Server
yum:
name: httpd
state: present
tags:
- install_httpd
- httpd_server - name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
tags:
- config_httpd
- httpd_server - name: start httpd server
service:
name: httpd
state: started
enabled: yes
tags: service_httpd handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted [root@m01 m01]# ansible-playbook tag.yml --list-tags
[root@m01 m01]# ansible-playbook tag.yml -t httpd_server
[root@m01 m01]# ansible-playbook tag.yml -t install_httpd,confiure_httpd
[root@m01 m01]# ansible-playbook tag.yml --skip-tags httpd_server

playbo ok复用include

在之前写playbook的过程中,写多个playbook没有办法一键执行,所以playbook 中有一个功能,叫做 include 用来动态调用task任务列表。

只调用task include_tasks

调用整个task 文件: include (新版本: import_playbook)

在saltstack中,叫做 top file入口文件。

示例:

[root@m01 web]# vim install_nginx.yml 

- name: Install nginx
yum:
name: nginx
state: present [root@m01 web]# vim conf_nginx.yml
- name: conf nginx
copy:
src: ./www.drz.com.conf
dest: /etc/nginx/conf.d
notify: reload nginx [root@m01 web]# vim main.yml
- hosts:
tasks:
- include_tasks: ./install_nginx.yml
- include_tasks: ./conf_nginx.yml
handlers:
- name: reload nginx
systemd:
name: nginx
state: reloaded

2.直接复用写好的yml文件

  • 旧版:include
  • 新版:import_playbook
- import_playbook: ./lnmp.yml
- import_playbook: ../mariadb/mysql.yml

playbook 忽略错误

默认playbook会监测task 执行的返回状态,如果遇到错误则会立即中止playbook 的后续task执行,然而有些时候playbook 即使执行错误了也要让其继续执行。

加入参数: ignore_errors:yes 忽略错误

[root@m01 ~]# cat ignore.yml
---
- hosts: web_group
tasks:
- name: Ignore False
command: /bin/false
ignore_errors: yes - name: touch new file
file:
path: /tmp/zls.txt
state: touch

playbook 错误处理

如上所述,当 task 执行失败时,playbook 将不再继续执行,包括如果在task中设置了handler 也不会被执行。

但是我们可以采取强制措施..


强制调用handler

[root@m01 ~]# cat handler.yml
- hosts: web_group
vars:
- http_port: 8080
force_handlers: yes
tasks: - name: config httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf
notify:
- Restart Httpd Server
- Restart PHP Server - name: Install Http Server
yum:
name: htttpd
state: present - name: start httpd server
service:
name:httpd
state: started
enabled: yes handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted - name: Restart PHP Server
systemd:
name: php-fpm
state: restarted

抑制changed

被管理主机没有发生变化,可以使用参数将change状态改为ok

[root@m01 ~]# cat handler.yml
- hosts: web_group
vars:
- http_port: 8080
force_handlers: yes
tasks:
- name: shell
shell: netstat -lntup|grep httpd
register: check_httpd
changed_when: false - name: debug
debug: msg={{ check_httpd.stdout.lines }}
[root@m01 project2]# cat changed_when.yml
- hosts: webservers
vars:
- http_port: 8080
tasks:
- name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server - name: Check HTTPD
shell: /usr/sbin/httpd -t
register: httpd_check
changed_when:
- httpd_check.stdout.find('OK')
- false - name: start httpd server
service:
name: httpd
state: started
enabled: yes handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted

Ansible--04 ansible 流程控制的更多相关文章

  1. 038 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 05 案例演示switch结构-星期的表示案例以及总结

    038 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 05 案例演示switch结构-星期的表示案例以及总结 本文知识点:案例演示switch结构并对sw ...

  2. 037 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 04 switch结构

    037 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 04 switch结构 本文知识点:Java中的switch结构 选择结构分类 选择结构只有如下2种 ...

  3. 036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构

    036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构 本文知识点:Java中的嵌套if结构 什么是嵌套if结构? 概念: 嵌套if结构 ...

  4. 035 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 02 多重if结构

    035 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 02 多重if结构 本文知识点:Java中的多重if结构 选择结构回顾 if选择结构 注意: 1.条 ...

  5. 034 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 01 流程控制概述

    034 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 01 流程控制概述 本文知识点:Java中的流程控制相关概念的认识 三大流程控制语句结构的简介 顺序 ...

  6. 周一04.3流程控制while循环

    #循环就是重复做某件事 1.条件循环:while,语法如下 while 条件: # 循环体 # 如果条件为真,那么循环体则执行,执行完毕后再次循环,重新判断条件... # 如果条件为假,那么循环体不执 ...

  7. 周一04.2流程控制if……else

    语法一:  if 条件1: 代码1 代码2 例题:如果年龄>20岁,那么:叫阿姨 age=22if age>20: print('阿姨') 语法二: if 条件1: 代码1 代码2else ...

  8. ansible 流程控制

    ansible 流程控制 使用when判断主机名 - hosts: rsync_server tasks: - name: Install rsyncd Server yum: name: rsync ...

  9. Ansible流程控制

    Ansible流程控制 数据库操作问题: 数据库的操作问题,python需要依耐的模块MySQL-python . 数据库的操作 # 设置root的密码在,root的密码设置之后,创建用户和创建数据库 ...

随机推荐

  1. Vue--按键修饰符(逐个学习按键修饰符)

    在监听键盘事件时,我们经常需要检查常见的键值.Vue 允许为 v-on 在监听键盘事件时添加按键修饰符: <!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -- ...

  2. orcad原理图与PSPICE模型库名称

    Vendor PSpice Model Description Advanced Linear Devices adv_lin.lib Library of op-amps Advanced Line ...

  3. Thymeleaf 基本用法总结

    Thymeleaf 基本用法总结 一.引用命名空间 <html xmlns:th="http://www.thymeleaf.org"> 在html中引入此命名空间,可 ...

  4. git 配置(实用)

    将公钥添加进入即可  码云是添加私钥(注意!!!!) 这个时候Git就配置好了 git clone ssh协议的仓库 就可以直接拉代码了

  5. sqlserver2008锁表语句详解(锁定数据库一个表)

    锁定数据库的一个表 复制代码代码如下: SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 复制代码代码如下: SELECT * FROM tab ...

  6. APICloud框架——总结一下最近开发APP遇到的一些问题 (三)

    ajax报错 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 需要在服务器环境下 ...

  7. ThinkPHP整合datatables实现服务端分页

    最近做东西有一个需求,因为数据量很大,在这里我决定使用datatables的服务端分页,同时还需要传递查询条件到服务端.在网上搜索的大部分文章都感觉有些误差,于是自己封装了一下,主要配置/工具为: 服 ...

  8. C#正则表达式将html代码中的所有img标签提取

    /// <summary> /// 取得HTML中所有图片的 URL. /// </summary> /// <param name="sHtmlText&qu ...

  9. 韩老师CCNA学习笔记

    1.MSCONFIG服务里面可以选择隐藏Windows服务,就能看出程序安装的服务.即使显示已停止,仍可能在运行 2.命令行输入netstat -anbo ,显示当前连接和端口,数字显示,以及程序的路 ...

  10. 【已转移】【Java架构:基础技术】一篇文章搞掂:SVN

    一个例子: 公司的SVN代码中,含有target等文件夹,每次生成运行后,有很多文件打扰签入 处理方案: 1.CheckOut时,点击ChooseItems选项,不要选择这些target文件夹(有点麻 ...