一: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
基本语法规则
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
YAML支持的数据结构
- 对象:键值对的集合,又称为映射(mapping)/哈希(hashes)/字典(dictionary
- 数组:一组按次序排列的值,又称为序列(sequence)/列表((list)
- 纯量:单个的、不可再分的值
三: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)
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)