一、什么是playbook

playbooks是一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。 简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。 Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。 值得注意的是playbook是通过YAML格式来进行描述定义的。 playbook是由一个或多个模块组成的,使用多个不同的模块,完成一件事情。 playbook通过yaml语法识别描述的状态文件。扩展名是yaml

二、YAML语法

缩进:

YAML使用一个固定的缩进风格表示层级结构,每个缩进由两个空格组成, 不能使用tab

冒号:

以冒号结尾的除外,其他所有冒号后面所有必须有空格。

短横线:

表示列表项,使用一个短横杠加一个空格。 多个项使用同样的缩进级别作为同一列表。

 三、核心元素

Tasks:任务,由模板定义的操作列表

Variables:变量

Templates:模板,即使用模板语法的文件

Handlers:处理器 ,当某条件满足时,触发执行的操作

Roles:角色

四、hosts和users介绍

--- - hosts: all          #可以是一个主机组、主机、多个主机,中间以冒号分隔,也可以用all参数表示所有主机

remote_user: root              #表示执行的用户账号

become: yes                      #2.6版本以后的参数,之前是sudo,意思为切换用户运行

become_user: mysql         #指定sudo用户为mysql

become 和become_user    #作为指定远程主机sudo切换用

五、常用命令

ansible-playbook first.yml --syntax-check      #检查yaml文件的语法是否正确

ansible-playbook test.yml --list-task               #检查tasks任务

ansible-playbook test.yml --list-hosts             #检查生效的主机

ansible-playbook test.yml --start-at-task='Copy Nginx.conf'   #指定从某个task开始运行

ansible-playbook test.yml -k     #用来交互输入ssh密码

ansible-playbook test.yml -K    #用来交互输入sudo密码

ansible-playbook test.yml -u    #指定用户

六、playbook变量

变量定义有三种方式

(1) --extra-vars执行参数赋给变量,优先级最高;

[root@LB02 ansible]# vim test1.yml 

---
  - hosts: web
    remote_user: root
    tasks:
      - name: #create new file
        file: path=/tmp/{{ file }} state=touch
[root@LB02 ansible]# ansible-playbook test1.yml --extra-vars "file=abc" #在/tmp目录下创建abc的文件;注意此处的--extra-vars可直接用-e进行代替;

(2) playbook的yaml文件中定义变量赋值,优先级其次;

[root@LB02 ansible]# vim test2.yml 

---
  - hosts: web
    vars:   #此处进行变量赋值
     file: hello
    remote_user: root
    tasks:
      - name:
        file: path=/tmp/{{ file }} state=touch
#执行ansible命令,在客户端主机上面/tmp目录中创建hello这个文件。

(3) 在/etc/ansible/hosts主机组中定义变量,优先级最低;

[root@LB02 ansible]# vim hosts
[web01]
192.168.11.206

[web02]
192.168.11.207

[web]
192.168.11.206
192.168.11.207

[web:vars]
file=fileone    #此处定义变量名称
[root@LB02 ansible]# vim test3.yml 

---
  - hosts: web
    tasks:
    - name: create file
      file: path=/tmp/{{ file }} state=touch
#执行ansible命令后,在/tmp目录下创建fileone的文件;

注册变量: register关键字可以存储指定命令的输出结果到一个自定义的变量中

[root@LB02 ansible]# vim test4.yml 

---
  - hosts: web
    tasks:
    - name:
      shell: netstat -tunlp
      register: system_status
    - name: Get System Status
      debug: msg={{ system_status.stdout_lines }}

七、条件判断(when)

[root@LB02 ansible]# vim whenone.yml 

---
  - hosts: web
    remote_user: root
    tasks:
    - name: create file #如果系统中存在主机名为web01或者server的主机,则创建文件
      file: path=/tmp/this_is_{{ ansible_hostname }}_file state=touch
      when: (ansible_hostname == "web01") or (ansible_hostname == "server")

    - name: centos install httpd  #系统为centos的主机才会执行
      yum: name=httpd state=present
      when: (ansible_distribution == "CentOS")

    - name: ubuntu install tree #系统为ubuntu的主机才会执行
      yum: name=tree state=present
      when: (ansible_distribution == "Ubuntu")
[root@LB02 ansible]# vim whentest.yml 
---
- hosts: web
  remote_user: root
  tasks:
   - name: install httpd
     yum: name=httpd state=present
     when: ansible_ens33.ipv4.address == "192.168.11.206"
#给IP:192.168.11.206的主机安装httpd服务;

八、循环语句(item)

(1)标准循环使用场景,批量安装软件;

[root@LB02 ansible]# vim item.yml 

---
 - hosts: web
   remote_user: root
   tasks:
   - name: installed pkg
     yum: name={{ item }} state=present
     with_items:
        - wget
        - vsftpd
        - tree
#客户主机会安装以上三种软件;

(2)标准循环使用场景,批量创建用户;

[root@LB02 ansible]# vim itemcreate.yml 

---
  - hosts: web
    remote_user: root
    tasks:
     - name: add users
       user: name={{ item.name }} groups={{ item.group }} state=present
       with_items:
         - { name: 'user1',group: 'root'}
         - { name: 'user2',group: 'root'}

(3)标准循环使用场景,拷贝多个目录;

[root@LB02 ansible]# vim itemcopy.yml 

---
 - hosts: web
   remote_user: root
   tasks:
     - name: configure rsync server
       copy: src={{ item.src }} dest=/tmp/{{ item.dest }} mode={{ item.mode }}
       with_items:
       - { src: "item.yml",dest: "item.yml",mode: "0644"}
       - { src: "itemcreate.yml",dest: "itemcreate.yml",mode: "0600"}
#把本地(管理端)文件复制到远程客户端主机/tmp目录下;路径可为绝对或相对路径;

异常处理,加入参数: ignore_errors: yes 忽略错误 

[root@LB02 ansible]# vim errorignore.yml 

---
 - hosts: web
   remote_user: root
   tasks:
    - name: ignore error
      command: /bin/false
      ignore_errors: yes

    - name: touch new file
      file: path=/tmp/errortest state=touch
#执行ansible后,在提示中有...ignoring 的显示;

九、tags标签

标签使用,通过tags和任务对象进行捆绑,控制部分或者指定的task执行

-t: 执行指定的tag标签任务

--skip-tags: 执行--skip-tags之外的标签任务

[root@LB02 ansible]# vim tag.yml

---
- hosts: web
  remote_user: root

  tasks:
    - name: install httpd
      yum: name=httpd state=installed
      tags: install_httpd

    - name: start httpd
      service: name=httpd state=started
      tags: start_httpd

    - name: restart httpd
      service: name=httpd state=restarted
      tags: restart_httpd

[root@LB02 ansible]# ansible-playbook -t install_httpd #只执行安装程序的操作;-t 参数只执行指定的标签运行;
[root@LB02 ansible]# ansible-playbook --skip-tags install_httpd #执行启动httpd程序后,再重启httpd; --skip-tags 参数是忽略此标签操作,执行其它操作。

十、通过template安装httpd

很多时候当我们某一个配置发生改变,我们需要重启服务,(比如httpd配置文件文件发生改变了)这时候就可以用到handlers和notify了; (当发生改动时)notify actions会在playbook的每一个task结束时被触发,而且即使有多个不同task通知改动的发生,notify actions知会被触发一次;比如多个resources指出因为一个配置文件被改动,所以apache需要重启,但是重新启动的操作知会被执行一次。

编辑playbook代码

[root@LB02 ansible]# vim httpd.yml 

---
- hosts: web
  remote_user: root
  vars:
    - listen_port: 9000

  tasks:
    - name: Install Httpd
      yum: name=httpd state=installed
    - name: Config Httpd
      template: src=./httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #路径根据自己的实际情况进行设置
      notify: Restart Httpd   #此处名称必须与handlers中的描述一致
    - name: Start Httpd
      service: name=httpd state=started

  handlers:
    - name: Restart Httpd     #此处描述必须与notify中的内容一致
      service: name=httpd state=restarted

  模版准备:手动复制一份http.conf文件并更名http.conf.j2,修改端口信息;

[root@LB02 ansible]# cat httpd.conf.j2 |grep ^Listen
Listen {{ listen_port }}
[root@LB02 ansible]# ansible-playbook httpd.yml #执行结果正常,可以到客户端主机进行查看httpd服务是否启动,端口为9000