目录
1、格式简介
playbook常用到的YMAL格式:
1、文件的第一行应该以 "---" (三个连字符)开始,表明YMAL文件的开始。
2、在同一行中,#之后的内容表示注释,类似于shell,python和ruby。
3、YMAL中的列表元素以"-"开头然后紧跟着一个空格,后面为元素内容。
4、同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。
5、play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以" : "分隔表示," : "后面还要增加一个空格。
Ansible playbook文件名称应该以 .yml
结尾,内容由三个部分组成:
host部分:使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks ,每个 playbook 都必须指定 hosts ,hosts也可以使用通配符格式。主机或主机组在 inventory 清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上 -i 选项,指定清单的位置即可。在运行清单文件的时候, –list-hosts 选项会显示那些主机将会参与执行 task 的过程中。
remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行 task 的用户,可以任意指定,也可以使用 sudo,但是用户必须要有执行相应 task 的权限。
tasks:指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks 包含 name 和 要执行的模块 ,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。
使用ansible-playbook运行playbook文件,输出内容为JSON格式;结果由不同颜色组成,便于识别:
绿色代表执行成功,系统保持原样
黄色代表系统状态发生改变
红色代表执行失败,显示错误输出
执行有三个步骤:
1、收集facts
2、执行tasks
3、报告结果
2、核心元素
Playbook的核心元素
Hosts:主机组
Tasks:任务列表
Variables:变量,设置方式有四种
Templates:包含了模板语法的文本文件
Handlers:由特定条件触发的任务
3、基本组件
Playbooks配置文件的基础组件
Hosts:运行指定任务的目标主机
remote_user:在远程主机上执行任务的用户
sudo_user:指定sudo到哪个用户
tasks:任务列表
handlers:任务,在特定条件下触发;接收到其它任务的通知时被触发模块
Playbooks配置文件的模块
格式:
action: module arguments
module: arguments
注意:shell和command模块后面直接跟命令,而非key=value类的参数列表
①某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers
②任务可以通过"tags"打标签,而后可在ansible-playbook命令上使用 -t 指定进行调用
3.1 定义playbook
[root@pc1 ansible]# vim nginx.yml
---
- hosts: web
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
- name: copy nginx.conf
copy: src=/root/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
notify: reload #当nginx.conf发生改变时,通知给相应的handlers
tags: reloadnginx #打标签
- name: start nginx service
service: name=nginx state=started
tags: startnginx #打标签
handlers: #注意,前面没有-,是两个空格
- name: reload
service: name=nginx state=restarted #为了在进程中能看出来
运行前三部曲
检查错误
ansible-playbook nginx.yml --syntax-check
列出所有任务
ansible-playbook nginx.yml --list-task
列出在那些机器执行
ansible-playbook nginx.yml --list-hosts
运行
ansible-playbook nginx.yml
3.2 测试运行结果
ansible-playbook nginx.yml
查看端口
ansible web -m shell -a 'ss -ntlp | grep nginx'
3.3 测试标签
先把服务关闭,然后运行剧本并引用标签
ansible web -m service -a 'name=nginx state=stopped'
ansible-playbook nginx.yml -t startnginx
3.4 测试notify
触发条件是配置文件被改变,所以修改配置文件中的端口,然后测试
将端口改为888
[root@pc1 ansible]# vim /root/nginx.conf
listen 888;
重新加载剧本
ansible-playbook nginx.yml -t reloadnginx
查看端口
ansible web -m shell -a 'ss -ntlp | grep nginx'
nginx 端口已经变成了888
4、variables 部分
variables 是变量,有四种定义方 法
4.1 facts(可直接调用)
variables 可以直接调用 facts 组件;facters 可以使用 setup 模块来获取,然后直接放入剧本中调用
ansible_all_ipv4_addresses:仅显示ipv4的信息 ---> [u'192.168.95.143']
ansible_eth0['ipv4']['address']:仅显示ipv4的信息 ---> eth0 的ip地址
ansible_devices:仅显示磁盘设备信息
ansible_distribution:显示是什么系统,例:centos,suse等
ansible_distribution_version:仅显示系统版本
ansible_machine:显示系统类型,例:32位,还是64位
ansible_eth0:仅显示eth0的信息
ansible_hostname:仅显示主机名
ansible_kernel:仅显示内核版本
ansible_lvm:显示lvm相关信息
ansible_memtotal_mb:显示系统总内存
ansible_memfree_mb:显示可用系统内存
ansible_memory_mb:详细显示内存情况
ansible_swaptotal_mb:显示总的swap内存
ansible_swapfree_mb:显示swap内存的可用内存
ansible_mounts:显示系统磁盘挂载情况
ansible_processor:显示cpu个数(具体显示每个cpu的型号)
ansible_processor_vcpus:显示cpu个数(只显示总的个数)
ansible_python_version:显示python版本
批量修改主机 host 文件
---
- hosts: web
vars:
IP: "{{ ansible_ens33['ipv4']['address'] }}"
tasks:
- name: #将原有的hosts文件备份
shell: mv /etc/hosts /etc/hosts_bak
- name: #将ansible端的hosts复制到各自机器上
copy: src=/root/hosts dest=/etc/ owner=root group=root mode=0644
- name: #在新的hosts文件后面追加各自机器内网ip和hostname
lineinfile: dest=/etc/hosts line="{{ IP }} {{ ansible_hostname }} "
4.2 用户自定义变量
自定义变量有两种方式
通过命令行传入
ansible-playbook 命令的命令行中的 -e VARS ,--extra-vars=VARS ,这样就可以直接把自定义的变量传入。
在playbook中定义变量
vars:
- var1: value1
- var2: value2
定义剧本
将nginx.yml中的所有nginx替换为变量{{ rpmname }}
替换后
运行剧本
ansible-playbook text.yml -e rpmname=httpd
查看端口
ansible web -m shell -a 'ss -nplt'
执行成功
修改剧本,直接定义变量
清理之前安装的httpd
ansible web -m yum -a 'name=httpd state=absent'
运行定义过变量的剧本
ansible-playbook text.yml
查看端口
ansible web -m shell -a 'ss -nplt'
4.3 Host Inventory
直接在主机清单中定义变量
修改主机清单文件
[root@pc1 ansible]# vim hosts
[web]
pc2 rpmname=httpd
pc3 rpmname=nginx
修改剧本
[root@pc1 ansible]# vim text.yml
---
- hosts: web
remote_user: root
# vars:
# - rpmname: httpd
tasks:
- name: install {{ rpmname }}
yum: name={{ rpmname }} state=present
- name: starting {{ rpmname }}
service: name={{ rpmname }} state=started
运行剧本
ansible-playbook text.yml
查看端口
Ansible Inventory 内置参数
使用内置变量把用户名密码写在Inventory中
缺点是暴露了账号密码,不安全
[web]
192.168.100.10
192.168.100.11
192.168.100.12
[web:vars] #给名为webservers的组定义一个变量,:vars是固定格式
ansible_ssh_port=22
ansible_ssh_user='root'
ansible_ssh_pass='123456'
5、模板 templates
模板是一个文本文件,嵌套有脚本(使用模板编程语言编写)
Jinja2:Jinja2是python的一种模板语言,以Django的模板语言为原本
通常来说,模板都是通过引用变量来运用的
模板支持:
字符串:使用单引号或双引号;
数字:整数,浮点数;
列表:[item1, item2, ...]
元组:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布尔型:true/false
算术运算:
+, -, *, /, //, %, **
比较操作:
==, !=, >, >=, <, <=
逻辑运算:
and, or, not
5.1 定义模板
把之前定义的 /root/nginx.conf 改个名,然后编辑一下,就可以定义成模板文件了
[root@pc1 ansible]# cd
[root@pc1 ~]# mv nginx.conf nginx.conf.j2
[root@pc1 ~]# vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};
listen {{ nginxport }};
5.2 修改剧本
修改 /etc/ansible/nginx.yml
5.3 运行剧本
被控节点已安装nginx,使用模板修改配置文件
ansible-playbook nginx.yml -t reloadnginx
查看端口
6、条件测试
when语句:在 task 中使用, jinja2 的语法格式
---
- hosts: web
remote_user: root
tasks:
- name: install conf file to centos7
template: src=/root/nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=/root/nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "6"
循环:迭代,需要重复执行的任务;对迭代项的引用,固定变量名为"item",而后,要在task中使用with_items给定要迭代的元素列表
---
- hosts: web
remote_user: root
tasks:
- name: unstall web packages
yum: name={{ item }} state=absent
with_items:
- httpd
- php
- php-mysql
7、字典
---
- hosts: web
remote_user: root
tasks:
- name: install some packages
yum: name={{ item }} state=present
with_items:
- nginx
- memcached
- php-fpm
- name: add some groups
group: name={{ item }} state=present
with_items:
- group11
- group12
- group13
- name: add some users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user11', group: 'group11' }
- { name: 'user12', group: 'group12' }
- { name: 'user13', group: 'group13' }