ansbile-playbook是一系列ansible命令的集合,利用yaml 语言编写。playbook命令根据自上而下的顺序依次执行。同时,playbook开创了很多特性,它可以允许你传输某个命令的状态到后面的指令,如你可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得你可以实现一些复杂的部署机制,这是ansible命令无法实现的。
playbook通过ansible-playbook命令使用,它的参数和ansible命令类似,如参数-k(–ask-pass) 和 -K (–ask-sudo) 来询问ssh密码和sudo密码,-u指定用户,这些指令也可以通过规定的单元写在playbook 。
一. ansible核心功能:
pyYAML-----用于ansible编写剧本所使用的语言格式(saltstack---python)
rsync-ini语法 sersync-xml语法 ansible-pyYAML语法
paramiko---远程连接与数据传输
Jinja2-----用于编写ansible的模板信息
二. ansible剧本编写规则说明
pyYAML语法规则:
规则一:缩进
yaml使用一个固定的缩进风格表示数据层结构关系,Saltstack需要每个缩进级别由两个空格组成。一定不能使用tab键
注意:编写yaml文件,就忘记键盘有tab
规则二:冒号
CMD="echo"
yaml:
mykey:
每个冒号后面一定要有一个空格(以冒号结尾不需要空格,表示文件路径的模版可以不需要空格)
规则三:短横线
想要表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一个列表的一部分
核心规则:有效的利用空格进行剧本的编写,剧本编写是不支持tab的
三. 剧本书写格式
下面给出一个简单的ansible-playbook示例,了解下其构成。
# cat user.yml
- name: create user
hosts: all
user: root
gather_facts: false
vars:
- user: "test"
tasks:
- name: create user
user: name="{{ user }}"
-----------------------------------------------------------------------------------------------------------------------------------------
上面的playbook 实现的功能是新增一个用户:
name参数对该playbook实现的功能做一个概述,后面执行过程中,会打印 name变量的值 ;
hosts:用于指定要执行指定任务的主机其可以是一个或多个由冒号分隔主机组。
remote_user :用于指定远程主机上的执行任务的用户。不过remote_user也可用于各task中。也可以通过指定其通过sudo的方式在远程主机上执行任务其可用于play全局或某任务。此外甚至可以在sudo时使用sudo_user指定sudo时切换的用户。
user :指定了使用什么用户登录远程主机操作;
sudo:如果设置为yes,执行该任务组的用户在执行任务的时候,获取root权限
sudo_user:如果设置user为breeze,sudo为yes,sudo_user为bernie时,则breeze用户在执行任务时会获得bernie用户的权限
connection:通过什么方式连接到远程主机,默认为ssh
gather_facts:指定了在以下任务部分执行前,是否先执行setup模块获取主机相关信息,这在后面的task会使用到setup获取的信息时用到。默认自动执行,如果不需要setup模块传递过来的变量,则可以将该选项设置为False;
vars参数,指定了变量,这里指字一个user变量,其值为test ,需要注意的是,变量值一定要用引号引住;
task指定了一个任务,其下面的name参数同样是对任务的描述,在执行过程中会打印出来。user提定了调用user模块,name是user模块里的一个参数,而增加的用户名字调用了上面user变量的值。
四. playbook的构成
playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中即可以让它们联同起来按事先编排的机制同唱一台大戏。其主要有以下四部分构成
playbooks组成
Target section: 定义将要执行 playbook 的远程主机组
Variable section: 定义 playbook 运行时需要使用的变量
Task section: 定义将要在远程主机上执行的任务列表
Handler section: 定义 task 执行完成以后需要调用的任务
细化一点的话playbook的结构为:
Inventory:操作的主机 *
Modules:使用的模块 *
Ad Hoc Commands:在主机上指定的命令
Playbooks
Tasks:任务,即调用模块完成的某操作 *
Variables:变量
Templates:模板
Handlers:处理器,由某事件触发完成的操作
Roles:角色
target 配置项目
- hosts:定义远程的主机组
- user:执行该任务的用户
- remote_user: 远端运行该play的用户,可以细分到每一个task
- *sudo:如果设置为yes,执行该任务组的用户在执行任务的时候,获取root权限
- *sudo_user: 如果你设置user为tom,速度设置为yes,sudo_user为jerry,则tom用户则会获取jerry用户的权限
- connection:通过什么方式连接到远程主机,默认为ssh
- become:是否提权
- become_method: 提权得方式(sudo)
- become-user=root - 以用户“root”运行以下命令(例如,使用命令使用“sudo”)。我们可以在此定义任何现有的用户
- notify:当任务执行完毕后,通知handler section 中的任务模块(出发执行)
- set_fact: 模块可以自定义facts,这些自定义的facts可以通过template或者变量的方式在playbook中使用。如果你想要获取一个进程使用的内存的百分比,则必须通过set_fact来进行计算之后得出其值,并将其值在playbook中引用。set_fact: innodb_buffer_pool_size_mb="{{ ansible_memtotal_mb / 2 }}"
- gather_facts:除非你明确说明不需要在远程主机上执行setup模块,否则会默认自动执行。如果你的确不需要setup模块所传递过来的变量,你可以启用该选项
# 可以使用setup获取到的字典中的key,来渲染对应的值
# 当值的类型为字典嵌套时,可以使用点来进行深入查找 {{ansible_eth0.ipv4.address}}
# 当值的类型为列表时,{{ansible[0].xxx}}
variable 可用的配置项目
- vars:定义一个变量。key:value,多个变量,可以使用{key:value,key2:value2}
- vars_files:定义一个变量文件。这里列出变量文件的绝对路径即可。 变量文件中的直接使用key:value定义即可。
- vars_prompt: 通过交互的方式输入的值
- name:变量的值
- prompt:提示信息
- private:是否为私有变量,yes | no, yes时输入的变量不在屏幕上显示,否则会显示在屏幕上
task 配置项目
play的主体部分是task list,task list中的各任务被按次序诸葛在hosts中 指定的所有主机上运行,即在所有主机上完成第一个任务后再开始第二个.在运行自上而下某个playbook时,如果中途发生错误,所有已执行任务都可以能回滚,因此,在更正playbook后重新执行一次即可.
task的目的是使用指定的参数运行模块,而在模块参数中可以使用变量,模块执行是幂等的,这意味着多次执行是安全的,因为其结果一致.
每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰的描述任务执行步骤。如果未提供name,则action的结果将用于输出。
定义任务的三种方式:
# 方式1(action)
- name: task的名称
action:要做的操作
# 例如: action: yum name= httpd state=×××talled
# 方式2(直接写模块名)
- name: task的名称
copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf
# 方式3(模块名时,模块的参数也可以用下列方式使用)
- name: task的名称
service:
name:httpd
state:restarted
五. 剧本编写后检查/运行方法
#进行剧本配置信息语法检查
ansible-playbook --syntax-check 01.yml
#模拟剧本执行(测试运行)
ansible-playbook -C 01.yml
–list-hosts
–list-tasks
–list-tags
#运行
ansible-playbook 01.yml
-t TAGS, –tags=TAGS
–skip-tags=SKIP_TAGS
–start-at-task=START_AT
六. 实例
1、场景一
- hosts: nginx
remote_user: root
gather_facts: false
tasks:
- name: push nginx file
synchronize:
src: /data/nginx-config/
dest: /etc/nginx/
archive: no
mode: push
delete: yes
recursive: yes
rsync_timeout: 300
rsync_opts:
- "--exclude=.git"
tags:
- push_files
- name: Configuring directory permissions
file:
path: /etc/nginx
owner: nginx
group: nginx
mode: 0644
recurse: yes
tags:
- config_permission
- name: nginx service reload
shell: /opt/openresty/nginx/sbin/nginx -s reload
tags:
- nginx_reload
2、场景二
ansible-playbook -i $nginx_bench --extra-vars "CTIME=2019-06-11-11-11-11" update_nginx_bench.yml
- hosts: all
gather_facts: no
gather_facts: F
remote_user: root
vars: {down_url: "http://10.10.10.1:88/bench/NGINX_{{ CTIME }}.tar.gz", down_file: "NGINX_{{ CTIME }}.tar.gz"}
tasks:
- shell: mkdir /data/deploy/nginx -p ; cd /data/deploy/nginx && rm -rf NGINX_*.tar.gz ; wget -q {{down_url}}
- shell: echo "NGINX_"$(stat --printf="%y" /data/deploy/nginx/{{down_file}} |sed "s/ /-/" |sed "s/:/-/g" |cut -b 1-19)
register: dirname
- shell: ls {{dirname.stdout}} >/dev/null 2>&1 && echo "true" || echo "false" executable=/bin/bash chdir=/data/deploy/nginx/
register: already_update
- fail: msg="当前service链接版本和最新git包版本一致,无需更新! 请检查有无打包,或登录ECS检查!"
when: already_update.stdout == "true"
- shell: source $HOME/.bashrc && source $HOME/.bash_profile && mkdir {{dirname.stdout}} && cd {{dirname.stdout}} && wget -q {{down_url}} && tar zxvf {{down_file}} executable=/bin/bash chdir=/data/deploy/nginx
- file : path=/etc/nginx state=link src=/data/deploy/nginx/{{dirname.stdout}}
- shell: ls -l nginx executable=/bin/bash chdir=/etc
register: ls
- shell: nginx -t && echo "true" || echo "false"
register: nginx_check
- fail: msg="Nginx 配置文件有误,请检查!!!"
when: nginx_check.stdout == "false"
- name: check_nginx
debug: var=nginx_check.stdout verbosity=0
- pause: seconds=10 prompt="10秒后重新加载配置:"
- shell: systemctl reload nginx
when: nginx_check.stdout == "true"
- shell: systemctl status nginx
register: nginx_status
- name: show_status
debug: var=nginx_status.stdout verbosity=0
- shell: find . -type d -name "NGINX_*" -mtime +30 -exec rm {} \; executable=/bin/bash chdir=/data/deploy/nginx/