PlayBook即”剧本”
play: 定义的是主机的角色。(主角还是配角,找哪个明星)
task: 定义的是具体执行的任务。(角色的台词和动作)
playbook: 由一个或多个play(角色)组成,一个play(角色)可以包含多个task(台词,动作,大腕每集拍什么)。
简单理解为: 使用不同的模块完成一件事情
在Ansible中”剧本文件”是以yml结尾的文件。
在SaltStack中”剧本文件”是以sls结尾的文件。
但是语法,使用的都是yaml语法
1.PlayBook功能比ad-hoc更全,是对ad-hoc的一种编排.
2.PlayBook能很好的控制先后执行顺序, 以及依赖关系.
3.PlayBook语法展现更加的直观.
4.playbook可以持久使用,ad-hoc无法持久使用.
YUML语法:
语法 描述
缩进 YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成, 不能使用TAB
冒号 以冒号结尾的除外,其他所有冒号后面所有必须有空格
短横线 表示列表项,使用一个短横杠加一个空格,多个项使用同样的缩进级别作为同一列表
yum:
name: vsftpd
state: present
yum:
name:
- httpd
- nginx
- php-fpm
state: present
检查语法:
ansible-playbook --syntax-check p1
执行演练:
ansible-playbook -C p1.yml
真实执行:
ansible-playbook p1.yml
有些时候在做模拟执行得时候会失败,但是在做真正执行得时候是成功得
(1)host清单:
[root@m01 ~]# vim /etc/ansible/hosts
[web_group]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
(2)剧本如下:
- hosts: web_group
#安装httpd
tasks:
- name: Install httpd Server
yum:
name: httpd
state: present
#配置网站
- name: Config Httpd Server
copy:
content: oldboy_web_page
dest: /var/www/html/index.html
#启动httpd
- name: Start Httpd Server
systemd:
name: httpd
state: started
enabled: yes
#启动防火墙
- name: Start Firewalld Server
systemd:
name: firewalld
state: started
enabled: yes
#开启防火墙的80端口
- name: Config Firewalld Server
firewalld:
service: http
immediate: yes
permanent: yes
state: enabled
实战一:
清单hosts如下:
[server]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
[client]
backup ansible_ssh_host=10.0.0.41
具体剧本为:
- hosts: all
tasks:
- name: Install rsync
yum:
name: rsync
state: present
- hosts: server
tasks:
- name: create group www
group:
name: www
gid: 666
- name: create user www
user:
name: www
uid: 666
group: www
create_home: false
shell: /sbin/nologin
- name: Create Directory
file:
path: /backup
owner: www
group: www
recurse: yes
- name: configure rsync
copy:
src: ./rsyncd.conf
dest: /etc/
- name: configure passwd
copy:
src: rsync.passwd
dest: /etc/
mode: 0600
- name: start rsyncd
systemd:
name: rsyncd
state: restarted
enabled: yes
- hosts: client
tasks:
- name: passwd file
copy:
content: '123456'
dest: /etc/rsync.pass
mode: 0600
注释:客户端需要的密码文件和服务端所需的配置文件和密码文件,提前在/root/project1准备好
实战二:
所需要的hosts清单如下:
[server]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
[client]
backup ansible_ssh_host=10.0.0.41
具体的剧本如下:
- hosts: all
tasks:
- name: Install Nfs
yum:
name: nfs-utils
state: present
- name: Create group
group:
name: www
gid: 666
- name: Create user
user:
name: www
uid: 666
group: www
create_home: false
shell: /sbin/nologin
- hosts: server
tasks:
- name: Configure nfs
copy:
src: ./exports.j2
dest: /etc/exports
- name: Create Directory
file:
path: /data
state: directory
owner: www
group: www
recurse: yes
- name: Restart Nfs
systemd:
name: nfs
state: started
enabled: yes
- hosts: web01
tasks:
- name: web01 mount server
mount:
src: 172.16.1.31:/data
path: /mnt
fstype: nfs
opts: defaults
state: mounted
- hosts: web02
tasks:
- name: web01 mount server
mount:
src: 172.16.1.31:/data
path: /mnt
fstype: nfs
opts: defaults
state: mounted
检查语法:
[root@m01 projects]# ansible-playbook --syntax-check nfs.yml -i hosts
执行:
[root@m01 projects]# ansible-playbook nfs.yml -i hosts
注意:所需的配置文件自行准备
实战三:
实战需求:
使用playbook实现一套LAMP架构。
部署需求:
1.使用yum安装httpd、php、php-mysql、php-pdo、mariadb
2.启动httpd、mariadb服务
3.下载wordpress代码
4.部署到httpd站点目录
(1)清单hosts如下
[web]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
(2)具体的剧本如下
- hosts: web
vars:
packages:
- httpd
- mariadb-server
- php
- php-mysql
- php-pdo
tasks:
- name: Install httpd mariadb php Server
yum:
name: "{{ packages }}"
state: present
- name: start httpd server
systemd:
name: httpd
state: started
enabled: yes
- name: start mariadb Server
systemd:
name: mariadb
state: started
enabled: yes
- name: Unarchive wordpress Package
unarchive:
src: wordpress-5.0.3-zh_CN.tar.gz
dest: /var/www/html
copy: yes
(3)执行脚本并且测试
检查语法:
[root@m01 projects]# ansible-playbook --syntax-check wp.yml -i hosts
执行:
[root@m01 projects]# ansible-playbook wp.yml -i hosts
打开浏览器访问:
http://10.0.0.7/wordpress/wp-admin/setup-config.php
http://10.0.0.8/wordpress/wp-admin/setup-config.php
亚哥写的:可以使用数据库了
[root@m01 lamp]# cat lamp.yml
- hosts: web01
tasks:
- name: Install LAMP
yum:
name: "{{ servers }}"
vars:
servers:
- httpd
- mariadb-server
- php
- php-mysql
- php-pdo
- MySQL-python
- name: Configure Html wordpress
copy:
src: wordpress-5.0.3.tar.gz
dest: /var/www/html/
- name: unarchive wordpress
unarchive:
src: /var/www/html/wordpress-5.0.3.tar.gz
dest: /var/www/html/
copy: no
- name: Change Mode Wordpress
file:
path: /var/www/html/wordpress
owner: apache
group: apache
recurse: yes
- name: Start HTTPD Server
systemd:
name: httpd
state: started
enabled: yes
- name: Start Mariadb Server
systemd:
name: mariadb
state: started
enabled: yes
- name: Removes all anonymous user accounts
mysql_user:
name: ''
host_all: yes
state: absent
- name: Create database user
mysql_user:
name: lzy
password: lzy123.com
priv: '*.*:ALL'
state: present
host: localhost
- name: Create Database wordpress
mysql_db:
login_user: lzy
login_password: lzy123.com
login_host: localhost
login_port: 3306
name: wordpress
state: present
变量提供了便捷的方式来管理Ansible playbook的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其它地方或许会反复使用,那么如果讲此值设置为变量,然后再在其他的playbook中调用,会方便许多。
(1)playbook变量可以通过多种方式进行定义,最简单的方式就是在playbook的开头通过vars进行定义
#方法一:
#安装两个软件包使用变量方式
[root@m01 project1]# cat p2.yml
- hosts: webservers
vars:
- web_package: httpd
- ftp_package: vsftpd
tasks:
- name: Installed Packages
yum:
name:
- "{{ web_package }}"
- "{{ ftp_package }}"
state: present
#方法二:
- hosts: web_group
vars:
packages:
- httpd
- mariadb-server
- php
- php-mysql
- php-pdo
tasks:
- name: Install httpd mariadb php Server
yum:
name: "{{ packages }}"
(2)也可以在playbook中使用vars_files指定文件作为变量文件,好处就是其他的playbook也可以调用
[root@m01 project1]# cat vars.yml
web_package: httpd
ftp_package: vsftpd
[root@m01 project1]# cat p2.yml
- hosts: webservers
vars_files: ./vars.yml
tasks:
- name: Installed Packages
yum:
name:
- "{{ web_package }}"
- "{{ ftp_package }}"
state: present
(3)在inventory中定义变量,主机变量优先级高于主机组变量(不推荐,容易将环境弄的特别乱)
[root@m01 project1]# vim /etc/ansible/hosts
[webservers]
web01 ansible_ssh_host=172.16.1.7
web02 ansible_ssh_host=172.16.1.8
[webservers:vars]
filename=group_vars
[root@m01 project1]# cat p3.yml
- hosts: webservers
tasks:
- name: Create File
file: path=/tmp/{{ filename }} state=touch
(4)更好的方式是在ansible的项目目录中创建额外的两个变量目录,分别是host_vars和group_vars (切记,目录名字一定要一致,不能做任何修改)
主机组定义变量
group_vars目录下必须存放和inventory清单文件中定义的组名一致,如下
[root@m01 project1]# cat /etc/ansible/hosts
[webservers]
web01 ansible_ssh_host=172.16.1.7
web02 ansible_ssh_host=172.16.1.8
[root@m01 project1]# cat group_vars/webservers
web_package: httpd
ftp_package: vsftpd
注意:系统提供了特殊的组,all,也就说在group_vars目录下创建一个all文件,定义变量对所有的主机都生效
主机定义变量
[root@m01 project1]# cat host_vars/web01
web_package: zlib-static
ftp_package: zmap
[root@m01 project1]# cat group_vars/webservers
web_package: httpd
ftp_package: vsftpd
[root@m01 project1]# cat p4.yml
- hosts: webservers
#- hosts: otherservers
tasks:
- name: Installed Packages
yum:
name:
- "{{ web_package }}"
- "{{ ftp_package }}"
state: present
主机的优先级大于组的优先级
(5)通过命令行覆盖变量,inventory的变量会被playbook文件中覆盖,这两种方式的变量都会被命
令行直接指定变量所覆盖。使用–extra-vars或-e设定变量。
[root@m01 project1]# ansible-playbook p4.yml -e "web_package=zarafa-devel" -e "ftp_package=zarafa-utils"
(6)变量优先级测试
命令行变量--->play中的vars_files--->play中的vars变量-->host_vars中定义的变量--->group_vars/组--->group_vars/all
[root@m01 project1]# cat p5.yml
- hosts: webservers
# vars:
# filename: play_vars
# vars_files:
# - ./vars.yml
tasks:
- name: Create
shell: mkdir -pv /tmp/{{ filename }}
register: mk_test
- name: debug
debug: msg={{ mk_test }}
当absible的模块在运行之后,其实都会返回一些result结果,就像是执行脚本,我们有的时候需要脚本给我们一些return返回值,我们才知道,上一步是否可以执行成功,但是…默认情况下,ansible的result并不会显示出来,所以,我们可以把这些返回值’存储’到变量中,这样我们就能通过’调用’对应的变量名,从而获取到这些result,这种将模块的返回值,写入到变量中的方法被称为变量注册
- hosts: webservers
tasks:
- name: Get Network Port Status
shell: "ls -l /"
register: list_dir
- name: OutPut Network Port Status
debug:
msg: "{{ list_dir.stdout_lines }}"
要调用这里面的内容:stdout_lines
"stdout_lines": [
"总用量 24",
"lrwxrwxrwx. 1 root root 7 3月 9 2019 bin -> usr/bin",
"dr-xr-xr-x. 5 root root 4096 3月 9 2019 boot",
"drwxr-xr-x. 20 root root 3260 9月 10 09:47 dev",
]
(1)变量也支持层级定义,使用".“可能会有问题,建议使用”[]"代替。
[root@m01 project1]# cat vars1.yml
rainbow:
web:
web_package: httpd
db_package: mariadb
code:
web:
filename: code_web_filename
[root@m01 project1]# cat p8.yml
- hosts: webservers
vars_files: ./vars1.yml
tasks:
- name: Install Package
yum: name= "{{ rainbow['web']['web_package'] }}"
- name: create filename
file:
path: /tmp/{{ code.web.filename }}
state: touch
Ansible facts是在被管理机上通过Ansible自动采集发现的变量
facts(setup模块)包含每台特定的主机信息。比如:被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。
facts使用场景:
1.通过facts缓存检查CPU,来生成对应的nginx配置文件
2.通过facts缓存检查主机名,生成不同的zabbix配置文件
3.通过facts缓存检索物理机的内存大小来生成不通的mysql配置文件
#编辑
[root@m01 ~]# vim facts.yml
- hosts: web_group
tasks:
- name: Get Host Info
debug:
msg: >
Hostname "{{ ansible_fqdn }}" and IP "{{ ansible_default_ipv4.address }}"
#执行
[root@m01 ~]# ansible-playbook facts.yml
[root@m01 ~]# ansible-playbook facts.yml
ok: [web01] => {
"msg": "Hostname \"web01\" and IP \"10.0.0.7\"\n"
}
ok: [web02] => {
"msg": "Hostname \"web02\" and IP \"10.0.0.8\"\n"
}
关闭facts(setup模块)
[root@m01 ~]# vim facts.yml
- hosts: web_group
gather_facts: no #关闭信息采集
tasks:
facts生成zabbix配置文件
- hosts: web_group
vars:
- zabbix_server: 172.16.1.71
tasks:
- name: copy zabbix agent conf
template:
src: ./zabbix_agentd.conf
dest: /tmp/zabbix_agentd.conf
facts生成mysqld配置文件
- hosts: db_group
tasks:
- name: Install mysql server
yum:
name: mariadb-server
state: present
- name: copy mysql conf
template:
src: ./my.cnf
dest: /etc/my.cnf
[root@m01 ~]# vim /etc/my.cnf
[mysqld]
basedir=/usr
datadir=/var/lib/mysql/
socket=/var/lib/mysql/mysql.sock
log_error=/var/log/mariadb/mariadb.log
innodb_buffer_pool_size={{ ansible_memtotal_mb * 0.8 }}
playbook安装一个memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ ansible_memtotal_mb //2 }}" # //2 这样除不带小数点
OPTIONS=""
[root@m01 project1]# cat p11.yml
- hosts: webservers
tasks:
- name: Installed Memcached
yum: name=memcached state=present
- name: Configure Memcached
template: src=./memcached.j2 dest=/etc/sysconfig/memcached
- name: Start Memcached
service: name=memcached state=started enabled=yes
常用的facts变量:
ansible_all_ipv4_addresses:仅显示ipv4的信息。
ansible_devices:仅显示磁盘设备信息。
ansible_distribution:显示是什么系统,例:centos,suse等。
ansible_distribution_major_version:显示是系统主版本。
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-playbook -C 2.yml -C 模拟演练
ansible web01 -m setup | grep mb 过滤想要的值
ansible web01 -m setup > test 到文件里面去找
setup 看被控端主机信息,根据这里的变量去获取信息
AnsibleFacts就是手机被控端的变量,playbook中template模块才能使用,copy模块不支持文件携带变量
facts也可以自定义(高级),没有太大的必要
jinjia不能在playbook中使用if else这样的判断,jinjia模板借助facts变量或者自定义变量。