Ansible剧本playbook

Posted Linux日记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ansible剧本playbook相关的知识,希望对你有一定的参考价值。

Ansible的指令可以完成许多零碎的工作,但是在一写比较复杂的场景下,单单使用ansible指令来完成工具并不可行,更复杂的工作就得交给playbook来完成了

playbookj简介

playbook是一种简单的配置管理系统与多机部署系统的基础,与现有的其他系统有不同之处,并且很适合用于复杂的用于部署。
Playbooks 的格式是YAML,YAML参考了其他多种语言,包括:XML、C语言、 Python、 Perl等语言;语法做到最小化,意在避免 playbooks 成为一种编程语言或是脚本,但它也并不是一个配置模型或过程的模型

YAML语法格式

  • 在单一档案中,可用连续三个连字号(—)区分多个档案。另外,还有选择性的连续三个点号

  • ( … )用来表示档案结尾,也可省略

  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能

  • 使用#号注释代码

  • 缩进必须是统一的,不能空格和tab混用

  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结
    合换行来实现的

  • YAML文件内容和Linux系统大小写判断方式保持一致,是区别大小写的,k/v的值均需大小写敏

  • k/v的值可同行写也可换行写。同行使用:分隔

  • v可是个字符串,也可是另一个列表

  • 一个完整的代码块功能需最少元素需包括 name: task

  • 一个name只能包括一个task

  • YAML文件扩展名通常为yml或yaml

一个语法示列:

---
- hosts: webservers
 vars:
   http_port: 80
   max_clients: 200
 remote_user: root
 tasks:
 - name: ensure apache is at the latest version
   yum: pkg=httpd state=latest
 - name: write the apache config file
   template: src=/srv/httpd.j2 dest=/etc/httpd.conf
   notify:
   - restart apache
 - name: ensure apache is running
   service: name=httpd state=started
 handlers:
   - name: restart apache
     service: name=httpd state=restarted

playbook语法解释

---            #固定格式
- hosts: webservers    #定义主机或主机组
 vars:                #定义变量
   http_port: 80      #变量
   max_clients: 200   #变量
 remote_user: root    #远程用户
tasks:     #定义一个任务的开始
 - name: ensure apache is at the latest version   #定义任务的名称
   yum: pkg=httpd state=latest                   #调用模块,具体要做的事
 - name: write the apache config file           # 定义任务的名称
   template: src=/srv/httpd.j2 dest=/etc/httpd.conf
   notify:                         #定义执行一个动作(action)让handlers来引用执行,与handlers配合使用
   - restart apache                #notify要执行的动作,这里必须handlers中的name定义内容相同
 - name: ensure apache is running
   service: name=httpd state=started
handlers:              #处理器:根据tasks中notify定义的action触发执行相应的处理动作
   - name: restart apache  #要与notify定义的内容相同
     service: name=httpd state=restarted  #触发要执行的动作

playbook中的元素属性

主机与用户

在一个playbook开始时,最先定义的是要操作的主机与用户

---
- host:test
 remote_user: root

除此外,还可以在某一个tasks中定要执行该任务的远程用户

---
- hosts:test
 remote_user: root
 tasks:
   - name: run df -h
   remote_user: yufu    #在tasks定义要执行df -h 指令的用户
   shell:df -h

tasks任务列表

每一个 task 必须有一个名称 name,这样在运行 playbook 时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个 task 的. 如果没有定义 name,‘action’ 的值将会用作输出信息中标记特定的 task.
每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的一件事,(任务模块)比如创建一个用户或者安装一个软件等,在hosts中定义的主机或者主机组都将会执行这个被定义的tasks

 tasks:
 - name: new a file
   file: path=/tmp/feng.txt state=touch
 - name: add user
   user: name=user23 state=present

ansible的模块具有冥等性,意思是如果你再一次地执行moud,moudle 只会执行必要的改动,只会改变需要改变的地方.所以重复多次执行 playbook 也很安全.

Handlers与Notify

当远程主机系统被改动时需要执行一些特定操作, 此时使用handlers和notify结合起来去做一些特定的工作。
(当系统或设置发生改动时)’notify’ actions 会在 playbook 的每一个 task 结束时被触发,而且即使有多个不同的 task 通知改动的发生, ‘notify’ actions 只会被触发一次。
‘notify’ 下列出的即是 handlers,handlers 也是一些 task 的列表,通过名字来引用,它们和一般的 task 并没有什么区别.Handlers 是由通知者进行 notify, 如果没有被 notify,handlers 不会执行.不管有多少个通知者进行了 notify,等到 play 中的所有 task 执行完成之后,handlers 也只会被执行一次。

一个示列:

tasks:
 - name: template configuration file
   template: src=template.j2 dest=/etc/foo.conf
   notify:
      - restart memcached
      - restart httpd
handlers:
 - nmae: restart memcached
   service:name=memcached state=restarted
 - name: restart httpd
   service: name=httpd state=restarted

上面的示列中对服务的配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart memcached,restart httpd这两个action,然后在handlers中引用上面tasks中定义的notify。

playbook安装nginx实例

结合上面的内容,编写一个playbook文件,实现批量自动安装nginx,并且把本地配置好的文件复制到远程各主机,最后将各主机重启;

---
- hosts: test
 remote_user: root
 tasks:
   - name: install nginx
     yum: name=nginx state=present
   - name: cp config file
     copy: src=/etc/nginx/nginx.conf dest=/etc/nginx backup=yes
     notify:
       - restart nginx
 handlers:
   - name: restart nginx
     service: name=nginx state=restarted

执行playbook前,最好先检查一下剧本内容有没有问题,执行ansible-playbook -C inst-nginx.yml, 加-C会将剧本空执行一遍,但不会产生实际的内容修改操作,检查没有问题后执行剧本
执行结果:

[root@Ansible opt]# ansible-playbook  inst-nginx.yml 
PLAY [test] **********************************************************************************************
TASK [Gathering Facts]    ***********************************************************************************
ok: [192.168.214.141]
ok: [192.168.214.140]
ok: [192.168.214.139]
ok: [192.168.214.138]
TASK [install nginx] *************************************************************************************
changed: [192.168.214.141]
changed: [192.168.214.140]
changed: [192.168.214.138]
changed: [192.168.214.139]
TASK [cp config file] ************************************************************************************
changed: [192.168.214.139]
changed: [192.168.214.140]
changed: [192.168.214.141]
changed: [192.168.214.138]
RUNNING HANDLER [restart nginx] **************************************************************************
changed: [192.168.214.140]
changed: [192.168.214.139]
changed: [192.168.214.141]
changed: [192.168.214.138]
PLAY RECAP ***********************************************************************************************
192.168.214.138            : ok=4    changed=3    unreachable=0    failed=0  
192.168.214.139            : ok=4    changed=3    unreachable=0    failed=0  
192.168.214.140            : ok=4    changed=3    unreachable=0    failed=0  
192.168.214.141            : ok=4    changed=3    unreachable=0    failed=0  

查看开启情况:

[root@Ansible opt]# ansible test -m shell -a 'ss -tnl | grep :80'
192.168.214.139 | SUCCESS | rc=0 >>
LISTEN     0      128                      :::80                      :::*    
LISTEN     0      128                       *:80                       *:*    
192.168.214.140 | SUCCESS | rc=0 >>
LISTEN     0      128                      :::80                      :::*    
LISTEN     0      128                       *:80                       *:*    
192.168.214.138 | SUCCESS | rc=0 >>
LISTEN     0      128                      :::80                      :::*    
LISTEN     0      128                       *:80                       *:*    
192.168.214.141 | SUCCESS | rc=0 >>
LISTEN     0      128                      :::80                      :::*    
LISTEN     0      128                       *:80                       *:*    

playbook中的变量

上面的playbook使用中都没有使用到变量,如果涉及到一些差异性的设置的话,那么就需要使用到变量来让不同主机进行调用。playbook中的变量可以是字母,数字以及下划线作为变量名;
定义变量的方式:

  1. 在/etc/ansible/hosts(inventory:清单)中定义,playbook中引用
    普通变量:主机组中主机单独定义,优先级高于公共变量
    公共(组)变量:针对主机组中所有主机定义统一变量

  2. 通过命令行指定变量,(要在playbook中定义好变量)优先级最高

ansible-playbook –e varname=value

  1. 在playbook中定义
    在playbook使用变量,可以设置全局变量,也可以使tasks的变量

  1. ansible setup facts:远程主机的所有变量都可以直接调用

  2. 在role中定义
    第4,5两种变量定义方式比较复杂,这里暂时不做研究,以后会单独研究相关内容

在hosts文件中定义变量

[one]
192.168.214.138  host_user=feng host_address=192.168.214.138 dir=/opt/
[test]
192.168.214.138
192.168.214.139
192.168.214.140
192.168.214.141
[test:vars]
http_port=80
hostname=web
admin_user=root

示列:

[root@Ansible opt]# vim hosts-var.yml 
---
- hosts: one
 remote_user: root
 tasks:
   - name: show host info
     shell: ls {{ dir }} >> /tmp/one.txt
   - name: show ip
     shell: echo "host IP:{{ host_address }}" >> /tmp/one.txt
   - name: show user
     shell: echo "host user:{{ host_user }}" >> /tmp/one.txt

通过命令指定变量在tasks之外定义,这样的变量在整个playbook中都可以被调用,属于全局变量

---
- hosts: test
 remote_user: root
 tasks:
   - name: install nginx
     yum: name={{ pkg1 }}
     yum: name={{ pkg2 }}

测试:

[root@Ansible opt]# ansible-playbook -C -e 'pkg1=nginx pkg2=mysql' inst-server.yml

如果在tasks任务列表中定义了不同的变量,可以在执行时给变量名赋值进程传递参数执行

在playbook中定义变量

---
- hosts: test
 remote_user: root
 vars:          #定义变量
   pkg1: nginx  #变量1
   pkg2: mysql  #变量2
 tasks:
   - name: install nginx
     yum: name={{ pkg1 }}   #引用变量
     yum: name={{ pkg2 }}


以上是关于Ansible剧本playbook的主要内容,如果未能解决你的问题,请参考以下文章

Ansible的脚本——playbook 剧本

Ansible的脚本—playbook剧本

2.Ansible Playbook剧本

ansible——playbook剧本

ansible playbook剧本

ansible playbook剧本