当前位置:网站首页>自动化运维工具Ansible(5)流程控制
自动化运维工具Ansible(5)流程控制
2022-08-04 05:27:00 【AHui_CSDN】
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 Httpd
yum:
name: httpd
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
过滤匹配返回值包含successful
- name: Check Nginx Configure
command: /usr/sbin/nginx -t
register: result
- name: Restart web02
command: /usr/sbin/reboot
when: result.stderr_lines is match "successful"
或者
when: result.stderr_lines is search "successful"
rsync服务端推送配置文件
[[email protected] ~]# 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
group: www
recurse: yes
when: ansible_hostname == "backup"
- name: Start Rsyncd Server
systemd:
name: rsyncd
state: started
when: ansible_hostname == "backup"
rsync客户端推送脚本
[[email protected] ~]# 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
playbook循环语句
在之前的学习过程中,我们经常会有传送文件,创建目录之类的操作,创建2个目录就要写两个file模块来创建,如果要创建100个目录,我们需要写100个file模块???妈耶~~~~ 当然不是,只要有循环即可,减少重复性代码。
启动多个服务
- hosts: web_group
tasks:
- name: start service
systemd:
name: "{
{ item }}"
state: started
with_items:
- httpd
- php-fpm
- mariadb
定义变量循环
- 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
字典循环
1.创建用户
[[email protected] ~]# cat loop.yml
- hosts: web_group
tasks:
- name: Add Users
user:
name: "{
{ item.name }}"
groups: "{
{ item.groups }}"
state: present
with_items:
- {
name: 'ahui', groups: 'linux' }
- {
name: 'go', groups: 'python' }
2.拷贝文件
- 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" }
playbook handlers
什么是handlers?
handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。
在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。
实践案例
[[email protected] ~]# cat handler.yml
- hosts: web_group
vars:
- http_port: 8080
tasks:
- name: Install Http Server
yum:
name: httpd
state: present
- name: config httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf
notify:
- Restart Httpd Server
- Restart PHP Server
- 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
注意:
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
[[email protected] 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
[[email protected] m01]# ansible-playbook tag.yml --list-tags
[[email protected] m01]# ansible-playbook tag.yml -t httpd_server
[[email protected] m01]# ansible-playbook tag.yml -t install_httpd,confiure_httpd
[[email protected] m01]# ansible-playbook tag.yml --skip-tags httpd_server
playbook文件复用
在之前写playbook的过程中,我们发现,写多个playbook没有办法,一键执行,这样我们还要单个playbook挨个去执行,很鸡肋。所以在playbook中有一个功能,叫做include用来动态调用task任务列表。
只调用task:include_tasks
调用整个task文件:include (新版本:import_playbook)
在saltstack中,叫做top file入口文件。
示例一:
[[email protected] m01]# cat task.yml
- hosts: web_group
vars:
- http_port: 8080
tasks:
- include_tasks: task_install.yml
- include_tasks: task_configure.yml
- include_tasks: task_start.yml
handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted
[[email protected] m01]# cat task_install.yml
- name: Install Http Server
yum:
name: httpd
state: present
[[email protected] m01]# cat task_configure.yml
- name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
[[email protected] m01]# cat task_start.yml
- name: start httpd server
service:
name: httpd
state: started
enabled: yes
示例二
- include: httpd.yml
- include: nfs.yml
- include: rsync.yml
示例三
- import_playbook: httpd.yml
- import_playbook: nfs.yml
- import_playbook: rsync.yml
playbook忽略错误
默认playbook会检测task执行的返回状态,如果遇到错误则会立即终止playbook的后续task执行,然鹅有些时候playbook即使执行错误了也要让其继续执行。
加入参数:ignore_errors:yes 忽略错误
[[email protected] ~]# cat ignore.yml
- hosts: web_group
tasks:
- name: Ignore False
command: /bin/false
ignore_errors: yes
- name: touch new file
file:
path: /tmp/ahui.txt
state: touch
playbook错误处理
如上所述,当task执行失败时,playbook将不再继续执行,包括如果在task中设置了handler也不会被执行。
但是我们可以采取强制措施…
强制调用handler
[[email protected] ~]# 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
[[email protected] ~]# 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 }}
[[email protected] 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
边栏推荐
- 实现登录密码混合动态因子,且动态因子隐式
- 多个gcc/glibc版本的共存及指定gcc版本的编译
- 将自定义类型作为关联容器的key
- (Kettle) pdi-ce-8.2 连接MySQL8.x数据库时驱动问题之终极探讨及解决方法分析
- FFmpeg源码分析:avformat_open_input
- 通过&修改数组中的值
- 4.3 基于注解的声明式事务和基于XML的声明式事务
- 使用express-jwt第三方包报错TypeError: expressJWT is not a function
- 7.18 Day23 - the markup language
- 4.1 JdbcTemplate for declarative transactions
猜你喜欢
解决安装nbextensions后使用Jupyter Notebook时出现template_paths相关错误的问题
代码重构:面向单元测试
Unity行为树AI分享
8.03 Day34---BaseMapper query statement usage
部署LVS-DR群集【实验】
实际开发中,如何实现复选框的全选和不选
The cost of automated testing is high and the effect is poor, so what is the significance of automated testing?
Canal mysql data synchronization
Programming hodgepodge (3)
Unity动画生成工具
随机推荐
The string class introduction
JS深复制对象方法(深拷贝)
跳转页面实时调用后台接口,更新页面数据
程序、进程、线程、协程的概念及区别
想好了吗?
嵌入式系统驱动初级【3】——字符设备驱动基础中_IO模型
自动化测试的成本高效果差,那么自动化测试的意义在哪呢?
Embedded system driver primary [4] - under the basis of character device driver _ concurrency control
跨域问题的解决
音视频相关基础知识与FFmpeg介绍
Unity DOTS学习教程汇总
Web Basics and Exercises for C1 Certification - My Study Notes
4.1 JdbcTemplate for declarative transactions
npm init [email protected] 构建项目报错SyntaxError: Unexpected token ‘.‘解决办法
登录页面js手写
Several ways to heavy
自己学习爬虫写的基础小函数
8.03 Day34---BaseMapper查询语句用法
Set集合与Map集合
使用express-jwt第三方包报错TypeError: expressJWT is not a function