一:playbooks 简介

  • 剧本是Ansible的配置、部署语言,由它对描述你想要远程机器执行的策略或步骤
  • 使用剧本不仅可以简单的对远程机器进行管理,还有很多更强大的功能

playbooks 组成部分

  • Tasks:任务,即调用模块完成的某操作
  • Variables:变量
  • Templates:模板
  • Handlers:处理器,当某条件满足时,触发执行的操作
  • Roles:角色

playbooks 核心组成

  • hosts:主机信息
  • tasks:任务信息
  • remote_user: root:指定远程主机执行的用户名

playbooks 的补充命令

ansible-playbook nginx.yaml --syntax-check  # 检查 yaml 文件的语法是否正确
ansible-playbook nginx.yaml --list-task     # 检查 tasks 任务
ansible-playbook nginx.yaml --list-hosts    # 检查生效的主机
ansible-playbook nginx.yaml --start-at-task='Copy Nginx.conf’ # 指定从某个task开始运行

二:关于 YAML

  • YAML是一种非标记语言。是用来写配置文件的语言,非常简洁和强大
  • YAML语法和其他语言类似,也可以表达散列表、标量等数据结构
  • 结构通过空格来展示;序列里配置项通过 - 来代表;Map里键值用:来分隔;YAML的扩展名为yaml

基本语法规则

  1. 大小写敏感
  2. 使用缩进表示层级关系
  3. 缩进时不允许使用Tab键,只允许使用空格
  4. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

YAML支持的数据结构

  1. 对象:键值对的集合,又称为映射(mapping)/哈希(hashes)/字典(dictionary
  2. 数组:一组按次序排列的值,又称为序列(sequence)/列表((list)
  3. 纯量:单个的、不可再分的值

三:playbooks 的示例操作

1:指定远程主机sudo切换用户

  • 首先 node1 节点上需要有一个普通用户
[root@node1 ~]# useradd wangwu
[root@node1 ~]# passwd wangwu
更改用户 wangwu 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
  • 编写执行任务
[root@master ~]# vi a1.yaml
 - hosts: server1
  remote_user: root
  become: yes
  become_user: wangwu
  tasks:
 - name: copy text
    copy: src=/etc/fstab dest=/home/wangwu/fstab.bak
[root@master ~]# ansible-playbook a1.yaml                   # 执行任务
  • 验证
[root@node1 ~]# cd /home/wangwu/
[root@node1 wangwu]# ll
总用量 4
-rw-r--r--. 1 wangwu wangwu 617 1月  10 06:06 fstab.bak

2:安装 apache 服务并开启服务,创建测试网页,关闭防火墙

  • 编写任务
[root@master ~]# vi aaa.yaml 
 - hosts: server1
  remote_user: root
  tasks:
 - name: install httpd
     yum: name=httpd
 - name: start httpd
     service: name=httpd state=started
 - name: stop firewalld
     service: name=firewalld state=stopped
 - name: touch index
     copy: content="this is my apache server" dest=/var/www/html/index.html
[root@master ~]# ansible-playbook aaa.yaml        # 执行任务
  • 验证
[root@node1 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64

[root@node1 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 日 2021-01-10 00:41:17 CST; 5h 30min ago
     Docs: man:httpd(8)

ansible 剧本查看ssh 版本信息 ansible执行剧本_tomcat

3:回滚操作

  • tasks列表和action

Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任多在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook中的错误,然后重新执行即可

  • 编写任务,里面带有错误任务
[root@master ~]# vi aaa.yaml
 - hosts: server2
  remote_user: root
  tasks:
 - name: install httpd
     yum: name=httpd
 - name: start httpd
     service: name=httpd state=sterted              # 开启服务写错
 - name: stop firewalld
     service: name=firewalld state=stopped
  • 执行任务中会报错
[root@master ~]# ansible-playbook aaa.yaml 

PLAY [server2] **********************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************
ok: [20.0.0.13]


TASK [install httpd] ****************************************************************************************************************************
ok: [20.0.0.13]

TASK [start httpd] ******************************************************************************************************************************
fatal: [20.0.0.13]: FAILED! => {"changed": false, "msg": "value of state must be one of: reloaded, restarted, started, stopped, got: sterted"}

PLAY RECAP **************************************************************************************************************************************
20.0.0.13                  : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
  • 查看任务执行的结果

(1)安装服务已安装

[root@node2 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64

(2)服务未开启

[root@node2 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:httpd(8)
           man:apachectl(8)

(3)防火墙未关闭

[root@node2 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: active (running) since 三 2021-01-13 22:37:18 CST; 11s ago
     Docs: man:firewalld(1)

总结:当任务正确执行change完后,任务已经执行完成,当执行错误任务的时候,执行的任务会进行回滚,后面的任务也不再执行,执行的任务和后面的任务都不在执行

忽略当前执行的错误任务并继续执行后面的任务

修改文件

[root@master ~]# vi aaa.yaml
 - hosts: server2
  remote_user: root
  tasks:
   - name: install httpd
     yum: name=httpd
   - name: start httpd
     service: name=httpd state=sterted 
     ignore_errors: True    # 添加:忽略错误,强制返回成功
   - name: stop firewalld
     service: name=firewalld state=stopped
  • 重新执行任务
[root@master ~]# ansible-playbook aaa.yaml
  • 验证防火墙是否关闭
[root@node2 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

4:Handlers介绍

  • Handlers也是一些task的列表,和一般的task并没有什么区别
  • 是由通知者进行的notify,如果没有被notify,则Handlers不会执行,假如被notify了,则Handlers被执行
  • 不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,handlers也只会被执行一次

例子

- hosts: server1
  remote_user: root
  tasks:        
  - name: install httpd package        # 安装服务
    yum: name=httpd state=latest   
  - name: install configuration file for httpd      
    copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf   # 拷贝文件
    notify:
    - restart httpd 
  - name: start httpd service
    service: enabled=true name=httpd state=started
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted

拷贝完后文件需要重启服务,notify 用了 restart httpd, handlers 搜索到了 restart httpd 就会自动去执行,然后再执行 start httpd service;若是没有搜索到 restart httpd,则不会执行 start httpd service

引入变量

[root@master ~]# vi aaa.yaml
 - hosts: server1
   remote_user: root
   vars:                         # 引用变量
 - aaa: tomcat                # tomcat 引用变量为 aaa             
   tasks:
 - name: install httpd
   yum: name={{aaa}}
 - name: start httpd
   service: name={{aaa}} state=started
[root@master ~]# ansible-playbook aaa.yaml
  • 验证
[root@node1 ~]# rpm -q tomcat
tomcat-7.0.76-2.el7.noarch
[root@node1 ~]# systemctl status tomcat
● tomcat.service - Apache Tomcat Web Application Container
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; disabled; vendor preset: disabled)
   Active: active (running) since 日 2021-01-10 06:56:22 CST; 34s ago
 Main PID: 69323 (java)

playbooks 使用变量的方法

1:通过 ansible 命令传递

[root@master ~]# vi k.yaml
- hosts: server1
  remote_user: root
  vars:
  - user:                      # 引用变量为空
  tasks:
  - name: add new user
    user: name={{user}}
  • 执行任务的时候加上变量名
[root@master ~]# ansible-playbook k.yaml -e "user=lisi"
  • 验证
[root@node1 ~]# id lisi
uid=1113(lisi) gid=1113(lisi) 组=1113(lisi)

2:直接引用一些变量

[root@master ~]# vi o.yaml
 - hosts: all
   remote_user: root
   tasks:
 - name: copy file
   copy: content="{{ansible_all_ipv4_addresses}}" dest=/opt/addr.txt
[root@master ~]# ansible-playbook o.yaml
  • 验证
[root@node1 ~]# cat /opt/addr.txt 
["192.168.122.1", "20.0.0.12"]
[root@node2 ~]# cat /opt/addr.txt 
["192.168.122.1", "20.0.0.13"]

引用主机变量

[root@master ~]# vi /etc/ansible/hosts
[server1]
20.0.0.12 number="66666"      # number 的值为 66666
[root@master ~]# vi o.yaml
 - hosts: server1
   remote_user: root
   tasks:
 - name: copy file
   copy: content="{{ansible_all_ipv4_addresses}},{{number}}" dest=/opt/o.txt
[root@master ~]# ansible-playbook o.yaml
  • 验证
[root@node1 ~]# cat /opt/o.txt 
([u'192.168.122.1', u'20.0.0.12'], 66666)