07.Ansible 自动化配置进阶
- Playbook剧本初识
- Playbook变量使用
- Playbook变量注册
- Playbook条件语句
- Playbook循环语句
- Playbook异常处理
- Playbook tabs标签
- Playbook Handlers
- Playbook Include
- Playbook项目实践
1.Playbook, playbook 翻译过来就是“剧本”,那 playbook组成如下
play:定义的是主机的角色
task:定义的是具体执行的任务
playbook:由一个或多个play组成,一个play可以包含多个任务
简单理解为:使用不同的模块完成一件事情

Playbook组成
--- -hosts:all remote_user:root vars: file_name:username tasks: -name:touch new files shell:touch /tmp/{{file_name}}
2.playbook的优势
- 功能比ad-hoc更全
- 能很好的控制先后顺序,以及依赖关系
- 语法展现更加的直观
- ad-hoc 无法持久使用,playbook 可以持久使用
3.paaybook的配置语法是由yaml语法描述的,扩展名是yaml
缩进:YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用 tabs。
冒号:以冒号结尾的除外,其他所有冒号后面所有必须有空格。
短横线:表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表。
- host: nfs tsaks: - name: Installed NFS yum: name=nfs-utils state=present - name: Copy File exports copy: src=./exports.template dest=/etc/exports - name: Start NFS Server service: name=nfs-server state=started enabled=yes
4.playbook示例
在一个playbook里面写一个play, 一个task任务
[root@manager ~]#cat f1.yml --- - hosts: all remote_user: root vars: file_name: yuyu tasks: - name: Create New File file: name=/tmp/{{ file_name }} state=touch #playbook执行方式 [root@manager ~]#ansible-playbook f1.yml
5.Playbook 执行结果返回
红色:表示有task执行失败或者提醒的信息
黄色:表示执行了且改变了远程主机状态
绿色:表示执行成功
[root@manager ~]# cat 1.yml --- #play - hosts: nfs tasks: - name: Create New File file: path=/tmp/test.txt state=touch owner=root group=root mode=400
[root@manager ~]# ansible-playbook --syntax-check 1.yml 检查ansible-playbook 语法
playbook: 1.yml
[root@manager ~]ansible-playbook -C 1.yml 模拟执行playbook
[root@manager ~]# ansible-playbook 1.yml PLAY [nfs] ******************************************************************************************************************************* TASK [Gathering Facts] ******************************************************************************************************************* ok: [172.26.73.197] TASK [Create New File] ******************************************************************************************************************* changed: [172.26.73.197] PLAY RECAP ******************************************************************************************************************************* 172.26.73.197 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
用ansible 命令检查结果
[root@manager ~]# ansible nfs -m shell -a "ls /tmp/test.txt" 172.26.73.197 | CHANGED | rc=0 >> /tmp/test.txt [root@manager ~]# ansible nfs -m shell -a "ls /tmp/" 172.26.73.197 | CHANGED | rc=0 >> ansible_command_payload_iDPoma systemd-private-1d90ff6fe63b499d848ce28248137b36-chronyd.service-tbXpdx test.txt this_is_nfs_file
在一个playbook里面写一个play,多个task任务
[root@manager ~]# cat 1.yml --- #play - hosts: all tasks: - name: Create New File file: path=/tmp/test.txt state=touch owner=root group=root mode=400 - name: Creat New Directory file: path=/tmp/exam_dir state=dirctory owner=root grout=root mode=700
在一个playbook里面写多个play, 多个task 任务【不建议】
[root@manager ~]# cat 1.yml --- #play - hosts: all tasks: - name: Create New File file: path=/tmp/test.txt state=touch owner=root group=root mode=400 - name: Creat New Directory file: path=/tmp/exam_dir state=dirctory owner=root grout=root mode=700 - hosts: nfs tasks: - name: Create NFS New File file: path=/opt/test.txt state=touch owner=root group=root mode=400 [root@manager ~]# ansible-playbook --syntax-check 1.yml playbook: 1.yml [root@manager ~]#
2.Playbook变量使用
Playbook定义变量有三种方式
1)playbook的yaml文件中定义亦是赋值
2)--extra-vars执行参数赋给变量
3)在文件中定义变量 vars_files
4)在主机清单中定义
1. playbook的yaml文件中定义变量赋值
[root@manager ~]# cat f2.yml --- - hosts: nfs vars: #定义变量 file_name:bgx_yaml_vars tasks: - name: #{{ file_name }}引用上面定义的变量 file: path=/tmp/{{ file_name }} state=touch #playbook执行,在/tmp 目录创建bgx_yaml_vars文件
2、 --extra-vars执行参数赋给变量
[root@manager ~]# ansible-playbook --syntax-check f3.yml playbook: f3.yml [root@manager ~]# cat f3.yml --- - hosts: nfs tasks: - name: Create New File file: path=/tmp/{{ file_name }} state=touch #playbook 执行时传入file_name变量的参数,在/tmp目录创建bgx_extra-avrs文件
[root@manager ~] ansible-playbook f3.yml --extra-vars "file_name=temp_extra"
3、在文件中定义变量:可以在 /etc/ansible/hosts 主机组中定义,然后使用 playbook进行调度该变量
在文件中定义变量
[root@manager ~]# cat /etc/ansible/hosts [backup] 172.26.73.200 [nfs] 172.26.73.197 [nfs:vars] file_name=bgx_filename [web] 172.26.73.198
在playbook中使用变量
[root@manager ~]# cat f4.yml --- - hosts: all tasks: - name: Create New File file: path=/tmp/{{ file_name }} state=touch
如果定义的变量出现重复,且造成冲突,优先级如下:
1. extra-vars 外置传参的优先级最高【所有执行的主机都生效】
2.定义在yml文件中的优先级其次【所有执行的主机都生效】
3.hosts文件中定义的变量优先级最低【当前主机组定义会生效】
3.Playbook变量注册
1)注册变量:register关键字可以存储指定命令的输出结果到一个自定义的变量中
[root@manager ~]# cat f5.yml --- - hosts: all tasks: - name: Network Status shell: netstat -lntp|grep sshd register: Net_Status - name: Output Status debug: msg={{ Net_Status.stdout_lines }} [root@manager ~]# ansible-playbook f5.yml PLAY [all] ******************************************************************************************************************************* TASK [Gathering Facts] ******************************************************************************************************************* ok: [172.26.73.197] TASK [Network Status] ******************************************************************************************************************** changed: [172.26.73.197] TASK [Output Status] ********************************************************************************************************************* ok: [172.26.73.197] => { "msg": [ "tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1208/sshd " ] } PLAY RECAP ******************************************************************************************************************************* 172.26.73.197 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

4.Playbook条件语句
playbook中的条件判断语句使用when
[root@manager ~]# cat f6.yml --- - hosts: all remote_user: root tasks: - name: Create File file: path=/tmp/this_is_{{ ansible_hostname }}_file state=touch when: (ansible_hostname == "nfs") or (ansible_hostname == "backup") #系统为centos的主机才会执行 - name: Centos Install httpd yum: name=httpd state=present when: (ansible_distribution == "CentOS") #系统为ubuntu的主机才会执行 - name: Ubuntu Install httpd yum: name=httpd2 state=present when: (ansible_distribution == "Ubuntu") [root@manager ~]# ansible-playbook f6.yml PLAY [all] ******************************************************************************************************************************* TASK [Gathering Facts] ******************************************************************************************************************* ok: [172.26.73.197] fatal: [172.26.73.200]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.200 port 22: Connection timed out", "unreachable": true} fatal: [172.26.73.198]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.198 port 22: Connection timed out", "unreachable": true} TASK [Create File] *********************************************************************************************************************** changed: [172.26.73.197] TASK [Centos Install httpd] ************************************************************************************************************** changed: [172.26.73.197] TASK [Ubuntu Install httpd] ************************************************************************************************************** skipping: [172.26.73.197] PLAY RECAP ******************************************************************************************************************************* 172.26.73.197 : ok=3 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 172.26.73.198 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0 172.26.73.200 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
使用when来实现判断
[root@manager ~]# ansible nfs -m shell -a 'ls /tmp/this*' 172.26.73.197 | CHANGED | rc=0 >> /tmp/this_is_nfs_file [root@manager ~]# vim 4.yml [root@manager ~]# ansible-playbook --syntax-check 4.yml playbook: 4.yml [root@manager ~]# cat 4.yml --- - hosts: all tasks: - name: Create New File {{ ansible_hostname }} file: path=/tmp/this_is _{{ ansible_hostname }}_when state=touch when: (ansible_hostname == "nfs") or (ansible_hostname == "backup")
获取主机名
[root@manager ~]# ansible nfs -m setup |grep hostname "ansible_hostname": "nfs", [root@manager ~]# ansible nfs -m setup -a 'filter=ansible_hostname' 172.26.73.197 | SUCCESS => { "ansible_facts": { "ansible_hostname": "nfs", "discovered_interpreter_python": "/usr/bin/python" }, "changed": false } [root@manager ~]# ansible nfs -m shell -a 'ls /tmp/this*' 172.26.73.197 | CHANGED | rc=0 >> /tmp/this_is_nfs_file

5.Playbook循环语句
1、标准循环使用场景-批量安装软件
[root@manager ~]# cat f7.yml --- - hosts: all remote_user: root tasks: - name: Installed Pkg yum: name={{ item }} state=present with_items: - wget - tree - lrzsz
- hosts: backup
tasks:
- name: Copy
copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }}
with_items:
- {src: "./rsyncd.conf.template",dest: "/etc/rsyncd.conf",mode: "0644"}
- {src: "./rsync.pass.template",dest: "/etc/rsync.pass",mode:"0600"}
[root@manager ~]# ansible-playbook f7.yml

2、标准循环使用场景-批量创建用户
[root@manager ~]# cat f7.yml --- - hosts: nfs remote_user: root tasks: - name: Add Users user: name={{ item.name }} groups={{ item.groups }} state=present with_items: - { name: 'testuser1', groups: 'bin' } - { name: 'testuser2', groups: 'root' }
[root@manager ~]# ansible-playbook f7.yml PLAY [all] ******************************************************************************************************************************* TASK [Gathering Facts] ******************************************************************************************************************* ok: [172.26.73.197] fatal: [172.26.73.200]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.200 port 22: Connection timed out", "unreachable": true} fatal: [172.26.73.198]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.198 port 22: Connection timed out", "unreachable": true} TASK [Add Users] ************************************************************************************************************************* changed: [172.26.73.197] => (item={u'name': u'testuser1', u'groups': u'bin'}) changed: [172.26.73.197] => (item={u'name': u'testuser2', u'groups': u'root'}) PLAY RECAP ******************************************************************************************************************************* 172.26.73.197 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 172.26.73.198 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0 172.26.73.200 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
3、标准循环使用场景-拷贝多个目录
- hosts: backup remote_user: root tasks: - name: Configure Rsync Server copy: src={{ item.src }} dest=/etc/{{ item.dest }} mode={{ item.mode }} with_items: - {src: "./rsyncd.conf",dest: "rsyncd.conf",mode: "0644"} - {src: "./rsync.passwd",dest: "rsync.passwd",mode:"0600"}
6.Playbook异常处理
默认Playbook会检查命令和模块的返回状态,如遇到错误就中断playbook的执行加入参数:ignore_errors: yes 忽略错误
[root@manager ~]# cat f9.yml --- - hosts: all remote_user: root tasks: - name: Ignore False command: /bin/false ignore_errors: yes - name: touch new file file: path=/tmp/bgx_ignore state=touch
playbook过程中会跳过错误
[root@manager ~]# ansible-playbook f9.yml PLAY [all] ******************************************************************************************************************************* TASK [Gathering Facts] ******************************************************************************************************************* ok: [172.26.73.197] fatal: [172.26.73.200]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.200 port 22: Connection timed out", "unreachable": true} fatal: [172.26.73.198]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.198 port 22: Connection timed out", "unreachable": true} TASK [Ignore False] ********************************************************************************************************************** fatal: [172.26.73.197]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.020915", "end": "2020-04-25 23:24:22.610287", "msg": "non-zero return code", "rc": 1, "start": "2020-04-25 23:24:22.589372", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} ...ignoring TASK [touch new file] ******************************************************************************************************************** changed: [172.26.73.197] PLAY RECAP ******************************************************************************************************************************* 172.26.73.197 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1 172.26.73.198 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0 172.26.73.200 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0


7.Playbook tags标签
1.打标签
对一个对象打一个标签,最常用
对一个对象打多个标签
对多个对象打一个标签
2. 标签使用,通过tags和任务对象进行捆绑,控制部分或者指定的task 执行
-t: 执行指定的 tag 标签任务
--skip-tags: 执行--skip-tags之外的标签任务
[root@manager ~]# cat f10.yml --- - hosts: all remote_user: root tasks: - name: Install NFS Server yum: name=nfs-utils state=present tags: - install_nfs - install_nfs-server - name: Service NFS Server service: name=nfs-server state=started enabled=yes tags: start_nfs-server [root@manager ~]# [root@manager ~]# ansible-playbook --syntax-check 8.yml playbook: f10-1.yml [root@manager ~]# cat 8.yml --- - hosts: all tasks: - name: Installed Package yum: name={{ item }} state=present with_items: - httpd - httpd-tools tags: - install - install_httpd - name: Service Start service: name=httpd state=started enabled=yes tags: start_httpd [root@manager ~]#
执行8.yml的playbook,仅执行install_httpd标签的任务
[root@manager ~]# ansible-playbook 8.yml -t install_httpd
执行8.yml的playbook,除了install_httpd标签外的任务都执行
[root@manager ~]# ansible-playbook 8.yml --skip-tags install_httpd
8.Playbook Handlers
playbook 安装 Apache 示例
[root@manager ~]# cat webserver.yml --- - hosts: web remote_user: root #1.定义变量,在配置文件中调用 vars: http_port: 80 #2.安装httpd服务 tasks: - name: Install Httpd Server yum: name=httpd state=present #3.使用template模板,引用上面vars定义的变量至配置文件中 - name: Configure Httpd Server template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf notify: Restart Httpd Server #4.启动Httpd服务 - name: Start Httpd Server service: name=httpd state=started enabled=yes #5.检查Httpd服务当前的运行端口状态 - name: Out Httpd Server Status debug: msg={{ Httpd_Port.stdout_lines }} ignore_errors: yes #6.如果配置文件发生变化会调用该handlers下面的模块 handlers: - name: Restart Httpd Server service: name=httpd state=restarted [root@manager ~]#
playbook中的handlers, 当copy的配置文件发生变化时,会触发notify后面的名称,名称对应的是handlers中定义的
[root@manager ~]# cat 9.yml --- - hosts: web tasks: - name: Install Httpd Server yum: name=httpd state=present - name: Configure Httpd Server copy: src=./httpd.conf.template dest=/etc/httpd/conf/httpd.conf backup=yes notify: Restart Httpd Server - Restart Httpd - Restart Rsyncd - name: Start Httpd Server service: name=httpd state=started enabled=yes handlers: - name: Restart Httpd Server service: name=httpd state=restarted - name: Restart Rsyncd service: name=httpd state=restarted [root@manager ~]#
9.Playbook Include
include 用来动态的包含 tasks任务列表, include_tasks 新版/include老版
include 调用任务方式
#主入口文件
[root@manager ~]# ansible-playbook --syntax-check main.yml playbook: main.yml [root@manager ~]# vim f20.yml [root@manager ~]# [root@manager ~]# cat f20.yml - name: create file1 command: touch file1 [root@manager ~]# vim f21.yml [root@manager ~]# cat f21.yml - name: create file2 command: touch file2 [root@manager ~]# cat main.yml - hosts: all remote_user: root tasks: - include_tasks: f20.yml - include_tasks: f21.yml [root@manager ~]#
include包含文件,包含的文件必须都是一个完整的playbook
[root@manager ~]# vim site.yml [root@manager ~]# [root@manager ~]# cat site.yml - include: 1.yml 2.yml 3.yml [root@manager ~]#

浙公网安备 33010602011771号