一个playbook 中由多个组件组成,其中所用到的常见组件类型如下:

Hosts    执行的远程主机列表
Tasks     任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最
    少元素需包括 name 和 task,一个name只能包括一个task
Variables     内置变量或自定义变量在playbook中调用
Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此
会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地
长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

常见选项

 

语法:ansible-playbook <filename.yml> ... [options]
常见选项:
--syntax-check      #语法检查,可缩写成--syntax, 相当于bash -n   
-C --check #模拟执行,只检测可能会发生的改变,但不真正执行操作,dry run 
--list-hosts    #列出运行任务的主机
--list-tags #列出tag
--list-tasks #列出task
--limit 主机列表 #只针对主机列表中的特定主机执行 
例:[root@node01 ansible]# ansible-playbook --syntax-check 文件名 --limit 10.0.0.150
-i INVENTORY        #指定主机清单文件,通常一个项对应一个主机清单文件
[root@node01 ansible]# ansible-playbook  hello,yml -i hosts  这会扫描 hosts 里面的主机地址,host 可以从/etc/ansible/hosts 拷贝过来,然后,里面添加删除自己想要的IP
--start-at-task START_AT_TASK #从指定task开始执行,而非从头开始,START_AT_TASK为任务的
name
-v -vv  -vvv #显示过程

执行:

用法:[root@node01 ansible]# ansible-playbook  文件名

 

范例1:安装httpd

---
#This is a playbook file
- hosts: webservers  #主机名,取的是/etc/ansible/hosts 里面,自己定义的webservers 下面的IP
  remote_user: root  #用户,指明是root 用户执行
  tasks:         #这是固定格式
    - name: install httpd  #- name 是固定格式,后面的install httpd 解释说明的意思,意思是告诉我们,我要装httpd
      yum: name=httpd     # yum: 模块,ansibles 里面的功能模块,后面跟 name=httpd 意思就是 yum install httpd
    - name: start httpd service  #- name 是固定格式,后面的start httpd servic解释说明的意思,意思是告诉我们,我要启动httpd服务
service: name=httpd state=started enabled=yes # 具体启动命令,service: ansibles 的功能模块,

解释一下,--- 是固定格式  #注释说明,这种脚本要注意空格缩进,同级别的前面的空格一样多

范例2:卸载httpd

---
#This is a playbook file,remove httpd
- hosts: webservers
  remote_user: root
  gather_facts: no  #收集机器信息,no 是不收集,yes 是收集 在用变量的时候,如果要取stetup 自带的变量,必须用yes

  tasks:
    - name: remove httpd package
      yum: name=httpd state=absent  #state=absent 代表卸载
    - name: remove apache user
      user: name=apache state=absent
    - name: remove config file
      file: name=/etc/httpd state=absent
    - name: remove web html
      file: name=/data/html/ state=absent

 具体里面这些service  yum shell ping file  都是ansible 的模块功能。

还可以扫描文件执行,比如,在/etc/ansible/hosts 文件拷贝到当前路径下

[root@node01 ansible]# ansible-playbook  hello,yml -i hosts  这会扫描 hosts 里面的主机地址,然后取执行

 

 忽略错误 ignore_errors

如果一个task出错,默认将不会继续执行后续的其它task

利用 ignore_errors: yes 可以忽略此task的错误,继续向下执行playbook其它task

 

---
- hosts: websrvs
  
 tasks:
   - name: error
     command: /bin/false
     ignore_errors: yes
   - name: continue
     command: wall continue

  

Playbook中使用handlers和notify

Handlers本质是task list ,类似于MySQL中的触发器触发的行为,其中的task与前述的task并没有本质

上的不同,主要用于当关注的资源发生变化时,才会采取一定的操作。而Notify对应的action可用于在

每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完

成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操

注意:

如果多个task通知了相同的handlers, 此handlers仅会在所有tasks结束后运行一 次。

只有notify对应的task发生改变了才会通知handlers, 没有改变则不会触发handlers

handlers 是在所有前面的tasks都成功执行才会执行,如果前面任何一个task失败,会导致handler跳

过执行,可以使用force_handlers: yes 强制执行handler

#install nginx
- hosts: webservers
  remote_user: root
  gather_facts: no
  force_handlers: yes #无论task中的任何一个task失败,仍强制调用handlers

  tasks:
    - name: add group nginx
      group: name=nginx state=present
    - name: add user nginx
      user: name=nginx state=present group=nginx
    - name: install nginx
      yum: name=nginx state=present
    - name: config file
      copy: src=files/nginx.conf dest=/etc/nginx/nginx.conf
      notify: restart nginx
    - name: web page
      copy: src=files/index.html dest=/usr/share/nginx/html/index.html
    - name: start nginx
      service: name=nginx state=started enabled=yes

  handler:
    - name: restart nginx   #名字和上面的notify一样
      service: name=nginx state=restart

  

tags组件 贴标签

在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特

定tags的task,而非整个playbook文件

可以一个task对应多个tag,也可以多个task对应一个tag

还有另外3个特殊关键字用于标签, tagged, untagged 和 all,它们分别是仅运行已标记,只有未标记和所

有任务

#install nginx
- hosts: webservers
  remote_user: root
  gather_facts: no
  force_handlers: yes #无论task中的任何一个task失败,仍强制调用handlers

  tasks:
    - name: add group nginx
      group: name=nginx state=present
    - name: add user nginx
      user: name=nginx state=present group=nginx
    - name: install nginx
      yum: name=nginx state=present
    - name: config file
      copy: src=files/nginx.conf dest=/etc/nginx/nginx.conf
      notify: restart nginx
      tags: conf #一个标签的时候这么写
      #多个标签可以成下面的格式
      tsgs: [conf,file] #写在一行
        - conf   #写成多行
        - file   #写成多行
    - name: web page
      copy: src=files/index.html dest=/usr/share/nginx/html/index.html
    - name: start nginx
      service: name=nginx state=started enabled=yes
[root@ansible ~]#ansible-playbook --list-tags httpd.yml  #列表,显示有几个标签
[root@ansible ~]#ansible-playbook -t conf,service httpd.yml
[root@ansible ~]#ansible-playbook --skip-tags conf httpd.yml # 只执行conf 这个标签
[root@ansible ~]#ansible-playbook   httpd.yml --skip-tags untagged

  

Playbook中使用变量 

变量名:仅能由字母、数字和下划线组成,且只能以字母开头

变量定义

variable=value
variable: value
范例
http_port=80
http_port: 80

变量调用方法

通过 {{ variable_name }} 调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效

变量来源有多种:

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

2. 通过命令行指定变量,优先级最高

ansible-playbook -e varname=value test.yml

3. 在playbook文件中定义

vars:
 var1: value1
 var2: value2

4. 在独立的变量YAML文件中定义

- hosts: all
 vars_files:
   - vars.yml

5. 在主机清单文件中定义

主机(普通)变量:主机组中主机单独定义,优先级高于公共变量

组(公共)变量:针对主机组中所有主机定义统一变量

6. 在项目中针对主机和主机组定义

在项目目录中创建 host_vars和group_vars目录

7. 在role中定义

变量的优先级从高到低如下

-e 选项定义变量 -->playbook中vars_files --> playbook中vars变量定义 -->host_vars/主机名
文件 -->主机清单中主机变量--> group_vars/主机组名文件-->group_vars/all文件--> 主机清单组
变量

  

使用 setup 模块中变量

本模块自动在playbook调用,不要用ansible命令调用,生成的系统状态信息, 并存放在facts变量中

facts 包括的信息很多,如: 主机名,IP,CPU,内存,网卡等

facts 变量的实际使用场景案例

通过facts变量获取被控端CPU的个数信息,从而生成不同的Nginx配置文件

通过facts变量获取被控端内存大小信息,从而生成不同的memcached的配置文件

通过facts变量获取被控端主机名称信息,从而生成不同的Zabbix配置文件

.范例:

---
#var.yml
- hosts: webservers
  remote_user: root
  gather_facts: yes

  tasks:
    - name: create log file
      file: name=/data/{{ ansible_nodename }}.log state=touch
~

  

在playbook 命令行中定义变量

vim var2.yml
---
- hosts: websrvs
 remote_user: root
 tasks:
   - name: install package
     yum: name={{ pkname }} state=present
[root@ansible ~]#ansible-playbook -e pkname=httpd var2.yml

 

#也可以将多个变量放在一个文件中
[root@ansible ~]#cat vars
pkname1: memcached
pkname2: vsftpd 
[root@ansible ~]#vim var2.yml
---
- hosts: websrvs
 remote_user: root
 tasks:
    - name: install package {{ pkname1 }
     yum: name={{ pkname1 }} state=present
    - name: install package {{ pkname2 }
     yum: name={{ pkname2 }} state=present

[root@ansible ~]#ansible-playbook -e pkname1=memcached -e pkname2=httpd 
var5.yml
[root@ansible ~]#ansible-playbook -e '@vars' var2.yml

 

#在文件中创建并引用
cat vars2.yml
---
var1: httpd
var2: nginx
         
cat var6.yml
---         
- hosts: web
 remote_user: root
 vars_files:
    - vars2.yml
   tasks:
     - name: create httpd log
       file: name=/app/{{ var1 }}.log state=touch
     - name: create nginx log
       file: name=/app/{{ var2 }}.log state=touch