目录
一.Ansible playbook简介
二.Ansible playbook使用场景
三.Ansible playbook格式
格式简介
核心元素
基本组件
variables变量
模板templates
条件测试
字典
角色定制
1.文件的第一行应该以“---”(三个连字符)开始,表明YAML文件的开始。
2.在同一行中,#之后的内容表示注释,类似于shell,python和ruby。
3.YAML中的列表元素以“-”开头并且跟着一个空格。后面为元素内容。
4.同一个列表之中的元素应该保持相同的缩进,否则会被当做错误处理。
5.play中hosts、variables、roles、tasks等对象的表示方法都是以键值中间以“:”分隔表示,并且“:”之后要加一个空格。
安装并且运行mysql服务,实例如下:
---
- hosts: node1
remote_user: root
tasks:
- name: install mysql-server package
yum: name=mysql-server state=present
- name: starting mysqld service
service: name=msyql state=started
以上面为例,文件名应该以 .yml 结尾
host部分:使用hosts指示使用哪个主机或者主机组来运行下面的tasks,每个playbooks都必须指定hosts,host也可以使用通配符格式。主机或者主机组在inventorry清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i 选项指定清单的位置。在运行清单文件的时候, --list-hosts选项会显示哪些主机将会参与执行task的过程中。
remote_user:指定远端主机的哪个用户来登录远端系统,在远端系统执行task的用户,可以任意指定,也可以使用sudo,但是用户必须要有执行相应的task权限。
tasks:指定远端主机将要执行的一系列动作。tasks的核心为ansible的模块,前面已经提到模块的用法,tasks包含name和要执行的模块,name是可选的,只是为了便于用户阅读,模块是必须的,同时也要给予模块相应的参数
使用ansible-playbook运行playbook文件,得到的输出信息中,信息内容为JSON格式,并且由不同的颜色组成,便于识别。
绿色代表执行成功,系统保持原样。黄色代表系统状态发生改变。红色代表执行失败,显示错误输出。
Hosts:运行指定任务的目标主机
remoute_user:在远程主机上执行任务的用户;
sudo_user:
tasks:任务列表
tasks的具体格式:
tasks:
- name: TASK_NAME
module: arguments
notify: HANDLER_NAME
handlers:
- name: HANDLER_NAME
module: arguments
##模块,模块参数:
格式如下:
(1)action: module arguments
(2) module: arguments
注意:shell和command模块后直接加命令,而不是key=value类的参数列表
handlers:任务,在特定条件下触发;接受到其他任务的通知时被触发;
在某个任务的状态在运行之后为changed时,可以通过“notify”通知相应的handlers;
任务可以通过“tags”打标签,而后可以在ansible-playbook命令上使用-t指定进行调用;
定义一个安装nginx的playbook
定义playbook
[root@ansible ~]# cd /etc/ansible/
[root@ansible ansible]# ls
ansible.cfg hosts nginx.yml roles
[root@ansible ansible]# cat nginx.yml
---
- hosts: web
remote_user: root
tasks:
- name: install nginx ##安装模块,需要在被控主机里加上nginx的源
yum: name=nginx state=present
- name: copy nginx.conf ##复制nginx的配置文件过去,需要在本机的/tmp目录下编辑nginx.conf
copy: src=/tmp/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
[root@ansible ansible]#
测试运行结果
[root@ansible ansible]# ansible-playbook nginx.yml
PLAY [web] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]
TASK [install nginx] ***********************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]
TASK [copy nginx.conf] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]
TASK [start nginx service] *****************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]
PLAY RECAP *********************************************************************
192.168.43.109 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.43.110 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
##查看被控主机上的nginx服务
[root@ansible ansible]# ansible web -m shell -a 'netstat -natp | grep nginx'
192.168.43.110 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2720/nginx: master
192.168.43.109 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2776/nginx: master
[root@ansible ansible]#
测试标签,我们在nginx.yml中已经打了标签,所以可以直接应用标签,但是需要先将服务关闭,在运行剧本并且引用标签
#关闭被控节点的nginx服务
[root@ansible ansible]#
[root@ansible ansible]# ansible web -m shell -a 'systemctl stop nginx'
192.168.43.110 | CHANGED | rc=0 >>
192.168.43.109 | CHANGED | rc=0 >>
#重新加载剧本并且应用标签
[root@ansible ansible]# ansible-playbook nginx.yml -t startnginx
PLAY [web] ************************************************************************
TASK [Gathering Facts] ************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]
TASK [start nginx service] ********************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]
PLAY RECAP ************************************************************************
192.168.43.109 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.43.110 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#
##使用reloadnginx标签,重新加载剧本
[root@ansible ansible]# ansible-playbook nginx.yml -t reloadnginx
PLAY [web] **************************************************************************************************
TASK [Gathering Facts] **************************************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]
TASK [copy nginx.conf] **************************************************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]
RUNNING HANDLER [reload] ************************************************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]
PLAY RECAP **************************************************************************************************
192.168.43.109 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.43.110 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]# ansible web -m shell -a 'netstat -natp | grep nginx'
192.168.43.109 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 38417/nginx: master
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 38417/nginx: master
192.168.43.110 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 38281/nginx: master
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 38281/nginx: master
[root@ansible ansible]#
facts:可以直接调用
用户自定义变量
ansible-playbook命令行中的 -e VARS,--extra-vars=VARS,这样就可以直接把自定义的变量传入
##在playbook中定义变量如下:
vars:
- var1: value1
-- var2: value2
使用playbook定义变量,实例如下
[root@ansible ansible]# ls
ansible.cfg hosts nginx.yml roles
[root@ansible ansible]# cat nginx.yml
---
- hosts: web
remote_user: root
tasks:
- name: install {{ rpmname }}
yum: name={{ rpmname }} state=present
- name: copy {{ rpmname }}.conf
copy: src=/tmp/{{ rpmname }}.conf dest=/etc/{{ rpmname }}/{{ rpmname }}.conf backup=yes
notify: reload
tags: reload{{ rpmname }}
- name: start {{ rpmname }} service
service: name={{ rpmname }} state=started
tags: start{{ rpmname }}
handlers:
- name: reload
service: name={{ rpmname }} state=restarted
[root@ansible ansible]#
#因为我们要安装keepalived服务,所以将keepalived的配置文件拷贝到/tmp目录下
#可以在本机上下载keepalived服务
[root@server ansible]# cp /etc/keepalived/keepalived.conf /tmp/keepalived.conf
[root@ansible ansible]# ls
ansible.cfg hosts nginx.yml roles
##-e表示编辑yml内部变量
[root@ansible ansible]# ansible-playbook nginx.yml -e rpmname=keepalived
PLAY [web] ************************************************************************
TASK [Gathering Facts] ************************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]
TASK [install keepalived] *********************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]
TASK [copy keepalived.conf] *******************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]
TASK [start keepalived service] ***************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]
PLAY RECAP ************************************************************************
192.168.43.109 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.43.110 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#
通过roles传递变量
Host Inventory
#向不同的主机传递不同的变量
IP/HOSTNAME varaiable=value var2=value2
#向组中的主机传递相同的变量
[groupname:vars]
variable=value
字符串:使用单引号或双引号;
数字:整数,浮点数;
列表:[item1, item2, ...]
元组:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布尔型:true/false
算术运算:
+, -, *, /, //, %, **
比较操作:
==, !=, >, >=, <, <=
逻辑运算:
and, or, not
实例如下
[root@ansible ansible]# mv /tmp/nginx.conf /tmp/nginx.conf.j2
[root@ansible ansible]# vi /tmp/nginx.conf.j2
ddworker_processes {{ ansible_processor_vcpus }};
listen {{ nginxport }};
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 8888;
}
[root@ansible ansible]# ansible-playbook nginx.yml -t reloadnginx
PLAY [web] ***********************************************************************************
TASK [Gathering Facts] ***********************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]
TASK [copy nginx.conf] ***********************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]
PLAY RECAP ***********************************************************************************
192.168.43.109 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.43.110 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#
tasks:
- name: install conf file to centos7
template: src=files/nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=files/nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"
tasks:
- name: unstall web packages
yum: name={{ item }} state=absent
with_items:
- httpd
- php
- php-mysql
- 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' }
简介
角色集合
roles/
mysql/:mysql服务的yml文件
httpd/:apached服务的yml文件
nginx/:nginx服务的yml文件
files/:存储由copy或者script等模块调用的文件或者脚本;
tasks/:此目录中至少应该有一个名为main.yml的文件,用于定义各个task;其他文件需要由main.yml进行包含调用;
handlers/:此目录中至少应该有一个名为main.yml的文件,用于定义各个handler;其他文件需要由main.yml进行包含调用;
vars/:此目录至少应该有一个名为main,yml的文件,用于定义各个variable;其他的文件需要由main.yml进行包含调用;
templates/:存储由templates模块调用的模板文件;
meta/:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定以及依赖关系,其他文件需要由main.yml进行包含调用;
default/:此目录至少应该有一个名为main.yml的文件,用于设定默认变量;
角色定制实例
[root@ansible ansible]# ls
ansible.cfg hosts nginx.yml roles
[root@ansible ansible]# cd roles/
[root@ansible roles]# ls
[root@ansible roles]# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
[root@ansible roles]# yum install tree -y &> /dev/null
[root@ansible roles]# tree
.
├── httpd
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
├── mysql
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── nginx
├── default
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
24 directories, 0 files
[root@ansible roles]#
[root@ansible nginx]# pwd
/etc/ansible/roles/nginx
[root@ansible nginx]# ls
default files handlers meta tasks templates vars
[root@ansible nginx]# ls tasks/
main.yml
[root@ansible nginx]# cat tasks/main.yml
- name: cp
copy: src=nginx-1.18.0-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm
- name: install
yum: name=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm state=latest
- name: conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: nginxconf
notify: new conf to reload
- name: start service
service: name=nginx state=started enabled=true
[root@ansible nginx]#
[root@ansible ]# cp /var/cache/yum/x86_64/7/nginx/packages/nginx-1.18.0-1.el7.ngx.x86_64.rpm /etc/ansible/roles/nginx/files/
[root@ansible ]# cp /tmp/nginx.conf.j2 /etc/ansible/roles//nginx/templates/
[root@ansible nginx]# tree
.
├── default
├── files
│ └── nginx-1.18.0-1.el7.ngx.x86_64.rpm
├── handlers
├── meta
├── tasks
│ └── main.yml
├── templates
│ └── nginx.conf.j2
└── vars
7 directories, 3 files
[root@ansible nginx]#
[root@ansible nginx]# ls
default files handlers meta tasks templates vars
[root@ansible nginx]# cat vars/main.yml
nginxport: 9999
[root@ansible nginx]#
[root@ansible nginx]# cat handlers/main.yml
- name: new conf to reload
service: name=nginx state=restarted
[root@ansible nginx]#
[root@ansible ansible]# pwd
/etc/ansible
[root@ansible ansible]# cat roles.yml
- hosts: web
remote_user: root
roles:
- nginx
[root@ansible ansible]#
[root@ansible ansible]# ansible-playbook roles.yml
PLAY [web] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]
TASK [nginx : cp] **************************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]
TASK [nginx : install] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]
TASK [nginx : conf] ************************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]
TASK [nginx : start service] ***************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]
RUNNING HANDLER [nginx : new conf to reload] ***********************************
changed: [192.168.43.110]
changed: [192.168.43.109]
PLAY RECAP *********************************************************************
192.168.43.109 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.43.110 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]# ansible web -m shell -a 'netstat -natp | grep nginx'
192.168.43.110 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 43345/nginx: master
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 43345/nginx: master
192.168.43.109 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 46442/nginx: master
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 46442/nginx: master
[root@ansible ansible]#
[root@ansible nginx]# pwd
/etc/ansible/roles/nginx
[root@ansible nginx]# tree
.
├── default
├── files
│ └── nginx-1.18.0-1.el7.ngx.x86_64.rpm
├── handlers
│ └── main.yml
├── meta
├── tasks
│ └── main.yml
├── templates
│ └── nginx.conf.j2
└── vars
└── main.yml
7 directories, 5 files
[root@ansible nginx]# cat handlers/main.yml
- name: new conf to reload
service: name=nginx state=restarted
[root@ansible nginx]# cat tasks/main.yml
- name: cp
copy: src=nginx-1.18.0-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm
- name: install
yum: name=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm state=latest
- name: conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: nginxconf
notify: new conf to reload
- name: start service
service: name=nginx state=started enabled=true
[root@ansible nginx]# cat templates/nginx.conf.j2
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen {{ nginxport }};
}
include /etc/nginx/conf.d/*.conf;
}
[root@ansible nginx]# cat vars/main.yml
nginxport: 9999
[root@ansible nginx]#