【运维知识进阶篇】Ansible流程控制详解

简介: 【运维知识进阶篇】Ansible流程控制详解

大家好,今天给大家讲解Ansible的流程控制,Ansible作为可以批量管理客户机的工具,自然是功能齐全,其条件语句、判断语句类似于shell脚本,所以我们要熟练掌握,在实际运用中灵活使用。

playbook条件语句

例如:我们在使用不同的系统的时候,可以通过判断系统来对软件包进行安装;在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,用条件语句可以减少剧本的编写;在安装源码时,可以判断是否执行成功。执行成功就启动等等。

1、根据不同操作系统安装apache

1. [root@Ansible test]# vim test.yml 
2. - hosts: web01
3.   tasks:
4.  - name: install centos httpd
5.       yum:
6.         name: httpd
7.         state: present
8. when: ansible_facts['os_family'] == "CentOS"    #官方写法
9.       #when: ansible_distribution == "CentOS"    非官方写法
10. 
11.  - name: install ubuntu httpd
12.       yum:
13.         name: apache2
14.         state: present
15. when: ansible_facts['os_family'] == "Ubuntu"
16. 
17. #还可以使用括号对条件进行分组
18. tasks:
19.  - name: "shut down CentOS 6 and Debian 7 systems"
20.     command: /sbin/shutdown -t now
21. when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")    #如果当前管理机为CentOS6或者是Debin7就关机
22. 
23. #也可以以列表形式指定多个条件
24. tasks:
25.  - name: "shut down CentOS 6 systems"
26.     command: /sbin/shutdown -t now
27. when:
28.  - ansible_facts['distribution'] == "CentOS"
29.  - ansible_facts['distribution_major_version'] == "6"
30. 
31. #也可以进行条件运算
32. tasks:
33.  - shell: echo "only on Red Hat 6, derivatives, and later"
34. when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6    #当系统为RedHat并且版本大于等于6时进行输出
35. 
36. #过滤匹配返回值包含successful
37. tasks:
38.  - name: Check Nginx Configure
39.     command: /usr/sbin/nginx -t
40.     register: result
41.  - name: Restart web02
42.     command: /usr/sbin/reboot
43. when:  result.stderr_lines is match ".*successful.*"    精准匹配,通常配合正则使用
44.     或者    
45. when:  result.stderr_lines is search "successful"       模糊匹配

2、rsync服务端推送配置文件

1. [root@Ansible test]# cat /ansible/rsyncd/rsyncd.yml
2. - hosts: all
3.   tasks:
4.  - name: Install Rsyncd Server
5.       yum: 
6.         name: rsync
7.         state: present
8.  - name: Create www Group
9. group:
10.         name: www
11.         gid: 666
12.  - name: Create www User
13.       user:
14.         name: www
15.         uid: 666
16. group: www
17.         shell: /sbin/nologin
18.         create_home: false
19.  - name: Scp Rsync Config
20. copy: 
21.         src: /ansible/rsyncd/rsyncd.conf
22.         dest: /etc/rsyncd.conf
23.         owner: root
24. group: root
25. mode: 0644
26. when: ansible_hostname == "Backup"
27.  - name: create passwd file
28. copy:
29. content: 'rsync_backup:123'
30.         dest: /etc/rsync.passwd
31.         owner: root
32. group: root
33. mode: 0600
34. when: ansible_hostname == "Backup"
35.  - name: Create backup Directory
36. file:
37.         path: /backup
38.         state: directory
39. mode: 0755
40.         owner: www
41. group: www
42.         recurse: yes
43. when: ansible_hostname == "Backup"
44.  - name: Start Rsyncd Server
45.       systemd:
46.         name: rsyncd 
47.         state: started
48. when: ansible_hostname == "Backup"

3、rsync客户端推送脚本

1. [root@Ansible rsyncd]# cat rsyncd_kehu.yml
2. - hosts: all
3.   tasks:
4.  - name: SCP Backup Shell
5. copy:
6.         src: backup.sh
7.         dest: /root/backup.sh
8. when: ansible_hostname is match "web*"
9. [root@Ansible rsyncd]# ansible-playbook rsyncd_kehu.yml
10. 
11. PLAY [all] *********************************************************************
12. 
13. TASK [Gathering Facts] *********************************************************
14. ok: [nfs]
15. ok: [mysql]
16. ok: [lb01]
17. ok: [rsync]
18. ok: [lb00]
19. ok: [web02]
20. ok: [web01]
21. ok: [lb02]
22. 
23. TASK [SCP Backup Shell] ********************************************************
24. skipping: [rsync]
25. skipping: [nfs]
26. skipping: [lb01]
27. skipping: [lb02]
28. skipping: [mysql]
29. skipping: [lb00]
30. skipping: [web01]
31. skipping: [web02]
32. 
33. PLAY RECAP *********************************************************************
34. lb00                       : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
35. lb01                       : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
36. lb02                       : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
37. mysql                      : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
38. nfs                        : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
39. rsync                      : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
40. web01                      : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
41. web02                      : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
42. 
43. [root@Ansible rsyncd]#

4、变量注册后进行判断

1. [root@Ansible ~]# vim /ansible/test/test.yml 
2. - hosts: web_group
3.   tasks:
4.  - name: check httpd server
5.       command: systemctl is-active httpd
6.       ignore_errors: yes        #忽视报错继续执行
7.       register: check_httpd
8.     -name: print check_httpd    #调试完后可以取消debug
9.       debug:
10.         msg: "{{ check_httpd }}"
11.  - name: httpd restart
12.       service:
13.         name: httpd
14.         state: restated
15. when: check_httpd.rc == 0
16. 
17. [root@Ansible test]# ansible-playbook test.yml 
18. 
19. PLAY [web_group] ***************************************************************
20. 
21. TASK [Gathering Facts] *********************************************************
22. ok: [web02]
23. ok: [web01]
24. 
25. TASK [check httpd server] ******************************************************
26. fatal: [web01]: FAILED! => {"changed": true, "cmd": ["systemctl", "is-active", "httpd"], "delta": "0:00:00.072816", "end": "2023-04-19 21:10:07.733494", "msg": "non-zero return code", "rc": 3, "start": "2023-04-19 21:10:07.660678", "stderr": "", "stderr_lines": [], "stdout": "unknown", "stdout_lines": ["unknown"]}
27. ...ignoring
28. fatal: [web02]: FAILED! => {"changed": true, "cmd": ["systemctl", "is-active", "httpd"], "delta": "0:00:00.073889", "end": "2023-04-19 21:10:07.735992", "msg": "non-zero return code", "rc": 3, "start": "2023-04-19 21:10:07.662103", "stderr": "", "stderr_lines": [], "stdout": "unknown", "stdout_lines": ["unknown"]}
29. ...ignoring
30. 
31. TASK [print check_httpd] *******************************************************
32. ok: [web01] => {
33. "msg": {
34. "changed": true, 
35. "cmd": [
36. "systemctl", 
37. "is-active", 
38. "httpd"
39.         ], 
40. "delta": "0:00:00.072816", 
41. "end": "2023-04-19 21:10:07.733494", 
42. "failed": true, 
43. "msg": "non-zero return code", 
44. "rc": 3, 
45. "start": "2023-04-19 21:10:07.660678", 
46. "stderr": "", 
47. "stderr_lines": [], 
48. "stdout": "unknown", 
49. "stdout_lines": [
50. "unknown"
51.         ]
52.     }
53. }
54. ok: [web02] => {
55. "msg": {
56. "changed": true, 
57. "cmd": [
58. "systemctl", 
59. "is-active", 
60. "httpd"
61.         ], 
62. "delta": "0:00:00.073889", 
63. "end": "2023-04-19 21:10:07.735992", 
64. "failed": true, 
65. "msg": "non-zero return code", 
66. "rc": 3, 
67. "start": "2023-04-19 21:10:07.662103", 
68. "stderr": "", 
69. "stderr_lines": [], 
70. "stdout": "unknown", 
71. "stdout_lines": [
72. "unknown"
73.         ]
74.     }
75. }
76. 
77. TASK [httpd restart] ***********************************************************
78. skipping: [web01]
79. skipping: [web02]
80. 
81. PLAY RECAP *********************************************************************
82. web01                      : ok=3    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=1
83. web02                      : ok=3    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=1

playbook循环语句

写循环语句可以减少剧本的编写,提高工作效率

1、启动多个服务

1. [root@Ansible test]# cat test.yml
2. - hosts: web_group
3.   tasks:
4.  - name: start service
5.       systemd:
6.         name: "{{ item }}"
7.         state: started
8. with_items:                    #或者是用loop
9.  - httpd
10.  - php-fpm
11.  - mariadb

2、循环定义变量(以列表形式)

1. [root@Ansible test]# cat test.yml
2. - hosts: web_group
3.   tasks:
4.  - name: ensure a list of packages instaled
5.       yum: 
6.         name: "{{ packages }}"
7.       vars:
8.         packages:
9.  - httpd
10.  - httpd-tools
11. 
12. [root@Ansible test]# cat test.yml
13. - hosts: web_group
14.   tasks:
15.  - name: ensure a list of packages instaled
16.       yum: name = "{{ item }}" state=present
17. with_items:
18.  - httpd
19.  - httpd-tools

3、字典循环

1. #创建用户
2. [root@Ansible test]# cat test.yml 
3. - hosts: web_group
4.   tasks:
5.  - name: Add Users    #记得提前创建组
6.       user:
7.         name: "{{ item.name }}"
8.         groups: "{{ item.groups }}"
9.         state: present
10. with_items:
11.  - { name: 'www',groups: 'www'}
12.  - { name: 'koten',groups: 'koten'}
13. 
14. #拷贝文件
15. [root@Ansible test]# cat test.yml 
16. - hosts: web_group
17.   tasks:
18.  - name: copy conf and code
19. copy:
20.         src: "{{ item.src }}"
21.         dest: "{{ item.dest }}"
22. mode: "{{ item.mode }}"
23. with_items:
24.  - { src: "./httpd.conf", dest: "/etc/httpd/conf/", mode: "0644" }
25.  - { src: "./upload_file.php", dest: "/var/www/html/", mode: "0600" }

playbookhandlers

handler是用来执行某些条件下的任务,比如配置文件发生变化时,通过notify触发handler去重启服务。(在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可)

handlers案例

1. [root@Ansible test]# cat test.yml
2. - hosts: web_group
3.   vars:
4.  - http_port: 8080                #定义http端口变量
5.   tasks:    
6.  - name: Install Http Server      #安装http服务
7.       yum:
8.         name: httpd
9.         state: present
10. 
11.  - name: config httpd server      #配置http服务
12.       template:                      #将管理机变量内容导入至客户机的这个文件
13.         src: ./httpd.conf
14.         dest: /etc/httpd/conf
15.       notify:                        #检测到配置文件发生变化后,执行handler中的变量
16.  - Restart Httpd Server       #名字要与handlers中-name保持一致
17.  - Restart PHP Server
18. 
19.  - name: start httpd server       
20.       service:
21.         name: httpd
22.         state: started    
23.         enabled: yes
24. 
25.   handlers:                          #handler中内置的变量
26.  - name: Restart Httpd Server
27.       systemd:
28.         name: httpd
29.         state: restarted 
30. 
31.  - name: Restart PHP Server
32.       systemd:
33.         name: php-fpm
34.         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在执行一个剧本时,会执行剧本里的所有任务,Ansible的tag功能,可以实现给剧本中的一个或多个任务(整个剧本也可以)打上标签,利用标签来指定这些要运行剧本中的个别任务,或不执行个别任务。

1、打标签方式

对一个task打一个标签;对一个task打多个标签;对多个task打一个标签

2、标签的使用

-t                      执行指定搞定tag标签任务

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

1. [root@Ansible test]# cat test.yml 
2. - hosts: web_group
3.   vars:
4.  - http_port: 8080
5.   tasks:
6.  - name: Install Http Server
7.       yum:
8.         name: httpd
9.         state: present
10.       tags: 
11.  - install_httpd
12.  - httpd_server
13. 
14.  - name: configure httpd server
15.       template:
16.         src: ./httpd.conf
17.         dest: /etc/httpd/conf/httpd.conf
18.       notify: Restart Httpd Server
19.       tags: 
20.  - config_httpd
21.  - httpd_server
22. 
23.  - name: start httpd server
24.       service:
25.         name: httpd
26.         state: started
27.         enabled: yes
28.       tags: service_httpd
29. 
30.   handlers:
31.  - name: Restart Httpd Server
32.       systemd:
33.         name: httpd
34.         state: restarted 
35. 
36. [root@Ansible test]# ansible-playbook test.yml --list-tags    #显示当前剧本的所有标签
37. 
38. playbook: test.yml
39. 
40.   play #1 (web_group): web_group  TAGS: []
41.       TASK TAGS: [config_httpd, httpd_server, install_httpd, service_httpd]
42. 
43. [root@Ansible test]# ansible-playbook test.yml -t httpd_server    #执行httpd_server标签的命令
44. [root@Ansible test]# ansible-playbook test.yml -t install_httpd,confiure_httpd    #执行install_httpd,confiure_httpd的命令
45. [root@Ansible test]# ansible-playbook test.yml --skip-tags httpd_server    #执行除了带httpd_server的命令

playbook文件复用

先前我们写的剧本都是一个一个去执行,我们能否通过写剧本的方法让剧本一键执行,ansible中准备了include的命令,用来动态调用task任务列表

1、只调用task:include_tasks,小剧本中只留tasks,变量需要写在单独的剧本中

1. [root@Ansible test]# cat task.yml
2. - hosts: web_group
3. vars:
4. - http_port: 8080
5. 
6. tasks:
7. - include_tasks: task_install.yml            #下面可以加when判断
8.     - include_tasks: task_configure.yml
9.     - include_tasks: task_start.yml
10. 
11. handlers:
12.     - name: Restart Httpd Server
13. systemd:
14. name: httpd
15. state: restarted
16. 
17. [root@Ansible test]# cat task_install.yml 
18. - name: Install Http Server
19. yum:
20. name: httpd
21. state: present
22. 
23. [root@Ansible test]# cat task_configure.yml 
24. - name: configure httpd server
25. template:
26. src: ./httpd.conf
27. dest: /etc/httpd/conf/httpd.conf
28. notify: Restart Httpd Server
29. 
30. [root@Ansible test]# cat task_start.yml 
31. - name: start httpd server
32. service:
33. name: httpd
34. state: started
35. enabled: yes

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

1. - include: httpd.yml
2. - include: nfs.yml
3. - include: rsync.yml
4. 
5. - import_playbook: httpd.yml
6. - import_playbook: nfs.yml
7. - import_playbook: rsync.yml

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

 

playbook忽略错误

剧本在执行中会检测任务执行的返回状态,遇到错误就会终止剧本,但是有些时候,即使执行错误,我们也需要它继续执行。

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

1. [root@Ansible test]# 
2. - hosts: web_group
3.   tasks:
4.  - name: Ignore False
5.       command: /bin/false
6.       ignore_errors: yes
7. 
8.  - name: touch new file
9. file:
10.         path: /tmp/oldboy.txt
11.         state: touch

playbook错误处理

当剧本执行失败时,如果在task中设置了handler也不会被执行。但是我们可以通过参数强制调用handler

1、强制调用handler

1. [root@Ansible test]# cat test.yml
2. - hosts: web_group
3.   vars:
4.  - http_port: 8080
5.   force_handlers: yes                    #错误后强制也会调用handler
6.   tasks:
7.  - name: Install Http Server
8.       yum:
9.         name: htttpd
10.         state: present
11. 
12.  - name: config httpd server
13.       template:
14.         src: ./httpd.conf
15.         dest: /etc/httpd/conf
16.       notify:                            #检测当配置文件变化时,执行变量里的内容
17.  - Restart Httpd Server
18.  - Restart PHP Server
19. 
20.  - name: start httpd server
21.       service:
22.         name: httpd
23.         state: started
24.         enabled: yes
25. 
26.   handlers:
27.  - name: Restart Httpd Server
28.       systemd:
29.         name: httpd
30.         state: restarted 
31. 
32.  - name: Restart PHP Server
33.       systemd:
34.         name: php-fpm
35.         state: restarted

2、抑制changed

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

1. [root@Ansible test]# cat handler.yml
2. - hosts: web_group
3.   vars:
4.  - http_port: 8080
5.   force_handlers: yes
6.   tasks:
7.  - name: shell
8.       shell: netstat -lntup|grep httpd
9.       register: check_httpd
10.       changed_when: false                        #将客户机状态设置为false,这样当管理机执行剧本时候,就不会因为这条命令执行handler中的内容,不必再去重启服务
11. 
12.  - name: debug
13.       debug: msg={{ check_httpd.stdout.lines }}
14. 
15. [root@Ansible test]# cat test.yml
16. - hosts: webservers
17.   vars:
18.  - http_port: 8080
19.   tasks:
20.  - name: configure httpd server
21.       template:
22.         src: ./httpd.conf
23.         dest: /etc/httpd/conf/httpd.conf
24.       notify: Restart Httpd Server    
25. 
26.  - name: Check HTTPD
27.       shell: /usr/sbin/httpd -t
28.       register: httpd_check
29.       changed_when: 
30.  - httpd_check.stdout.find('OK')
31.  - false
32. 
33.  - name: start httpd server
34.       service:
35.         name: httpd
36.         state: started
37.         enabled: yes
38. 
39.   handlers:
40.  - name: Restart Httpd Server
41.       systemd:
42.         name: httpd
43.         state: restarted

我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
6月前
|
运维 应用服务中间件 Linux
自动化运维的利器:Ansible在配置管理中的应用
【10月更文挑战第39天】本文旨在通过深入浅出的方式,向读者展示如何利用Ansible这一强大的自动化工具来优化日常的运维工作。我们将从基础概念讲起,逐步深入到实战操作,不仅涵盖Ansible的核心功能,还会分享一些高级技巧和最佳实践。无论你是初学者还是有经验的运维人员,这篇文章都会为你提供有价值的信息,帮助你提升工作效率。
|
2月前
|
运维 监控 持续交付
Websoft9 运维面板:GitOps 助力简化持续部署流程
传统部署中手动配置、脚本管理及版本回滚等问题一直困扰开发者。GitOps 通过基础设施代码化与版本化,成为持续部署新标准。Websoft9 深度融合 GitOps 理念,实现从代码提交到生产发布的自动化闭环。其核心功能包括:Git 仓库驱动配置管理(支持多分支隔离)、Argo CD 集成自动同步(灰度发布与全量更新)以及可视化监控审计(部署历史与资源变化分析)。本文结合实际操作解析其低门槛企业级部署方案。
54 0
|
4月前
|
人工智能 运维 监控
AI辅助的运维流程自动化:实现智能化管理的新篇章
AI辅助的运维流程自动化:实现智能化管理的新篇章
1007 22
|
4月前
|
弹性计算 运维 Ubuntu
使用阿里云服务器自动搭建WordPress网站流程,超简单by系统运维管理OOS
本教程介绍如何使用阿里云服务器(ECS)和系统运维管理OOS自动搭建WordPress网站,支持Ubuntu、CentOS及Alibaba Cloud Linux等操作系统。前提条件包括ECS实例处于运行中、有公网IP且安全组已开启80端口。安装步骤简单:进入ECS快速购买控制台选择预装WordPress,确认下单后通过管理控制台查看实例详情并开放安全组端口。最后,通过实例公网IP访问,出现WordPress登录页即表示安装成功。
|
5月前
|
运维 Ubuntu 应用服务中间件
自动化运维之路:使用Ansible进行服务器管理
在现代IT基础设施中,自动化运维已成为提高效率和可靠性的关键。本文将引导您通过使用Ansible这一强大的自动化工具来简化日常的服务器管理任务。我们将一起探索如何配置Ansible、编写Playbook以及执行自动化任务,旨在为读者提供一条清晰的路径,从而步入自动化运维的世界。
112 11
|
5月前
|
运维 网络安全 Python
自动化运维:使用Ansible实现批量服务器配置
在快速迭代的IT环境中,高效、可靠的服务器管理变得至关重要。本文将介绍如何使用Ansible这一强大的自动化工具,来简化和加速批量服务器配置过程。我们将从基础开始,逐步深入到更复杂的应用场景,确保即使是新手也能跟上节奏。文章将不包含代码示例,而是通过清晰的步骤和逻辑结构,引导读者理解自动化运维的核心概念及其在实际操作中的应用。
|
5月前
|
运维 Ubuntu 网络协议
自动化运维:使用Ansible进行服务器配置管理
在现代IT架构中,自动化运维已成为提升效率、减少人为错误的关键。本文将介绍如何使用Ansible这一强大的自动化工具来简化和标准化服务器的配置管理过程。通过具体的代码示例和操作步骤,我们将展示如何快速部署应用、管理配置以及自动化日常任务,从而确保环境的一致性和可靠性。
|
6月前
|
运维 监控 安全
自动化运维的利剑:Ansible在现代IT架构中的应用
在数字化浪潮中,企业对IT系统的敏捷性和可靠性要求日益提高。Ansible,一种简单但强大的自动化运维工具,正成为现代IT架构中不可或缺的一部分。它通过声明式编程语言YAM,简化了系统配置、应用部署和任务自动化的过程,显著提升了运维效率和准确性。本文将深入探讨Ansible的核心特性、应用场景以及如何有效整合进现有IT环境,为读者揭示其在自动化运维中的实用价值和未来发展潜力。
|
6月前
|
运维 安全 Ubuntu
自动化运维:使用Ansible进行服务器配置管理
在现代IT基础设施中,自动化运维是确保高效、稳定和安全服务的关键。本文将深入介绍如何使用Ansible这一开源工具来简化服务器配置管理工作,从基础安装到高级应用,我们将一步步展示如何通过Ansible Playbooks实现自动化部署和维护,旨在帮助读者构建更加灵活和可扩展的运维体系。
106 7
|
6月前
|
运维 Ubuntu Linux
自动化运维:使用Ansible简化日常任务
在快节奏的IT世界中,时间就是一切。本文将揭示如何通过Ansible这一强大的自动化工具来节省宝贵的时间,从而提高效率和减少人为错误。我们将深入探讨Ansible的核心概念、安装过程以及如何编写简单的playbook来自动执行常见运维任务。无论你是新手还是有经验的系统管理员,这篇文章都将为你提供实用的知识和技能,让你能够更好地控制你的服务器环境。

热门文章

最新文章