Ansible Playbook 介绍

由于安装openstack使用了kolla,而kolla使用了ansible,里面使用了ansible playbook。所以对playbook进行了介绍。可以理解为把需要用到的 ansible 模块写入到配置文件里面,然后执行配置文件就可以完成分复杂的工作。类比在 Linux 系统下的 shell 脚本,比如 shell 安装 LANMP。


编写playbook 一


# vim /etc/ansible/test.yml
---
- hosts: testhosts
  remote_user: root
  tasks:
        - name: test_playbook
          shell: touch /tmp/lishiming.txt

playbook 文件以 yml 结尾
--- 为固定格式,不能省略(测试了一下,并且看到有点文章省略了。好像可以省略),包括 host 前面的 -
hosts      指定主机的组或者ip
remote_user 指定远程执行命令的用户,也可以只写 user
tasks      指定任务,先对任务进行命名,再写要执行的命令
     name  对任务进行一个描述,执行过程中会打印出来
     shell 具体要执行的命令。
格式要求很严格,hosts 和 remote_user 一定要首字母对其,下面的 name 和 shell 也要整齐,减号是对下面所有的参数起作用,如果没有整齐,那么语法会有错误。

执行 playbook
# ansible-playbook test.yml

编写playbook 二
# vim /etc/ansible/creat_users.yml
---
- name: create_user
  hosts: testhosts
  user: root
  gather_facts: false
  vars:
       - user: "test"
  tasks:
       - name: creat user
         user: name="{{ user }}"

gater_facts     参数指定了在以下任务部分执行前,是否先执行setup模块获取主机相关信息,ansible testhosts -m setup 在命令行执行 setup 模块可查看相关信息。这些信息可以作为一个判断条件,在后面的task会使用到setup获取的信息。比如判断系统是 ubuntu 还是 centos,然后选择是执行 apt-get 还是 yum。
var     指定变量,定义 user 用户变量,值为test ,需要注意的是,变量值一定要用引号引住。在 playbook 里面用两个花括号来引用变量,需要有空格 {{ 变量 }}。
tasks     指定任务,
     - name 定义任务的描述,
       user 调用 user 模块
            用ansible-doc user 查看命令帮助选项。= name  Name of the user to create, remove or modify.
同样,如果想实现把这个新增的用户删除,只需将该playbook文件的最后一行替换为如下行再执行相应的playbook即可:
user: name="{{ user }}" state=absent remove=yes

playbook 中的循环
playbook 类似 shell ,支持循环以及判断等特殊格式。
需求针对 file 文件,修改 /tmp 目录下 1.txt 2.txt 的权限,owner 以及 group。做个遍历循环,核心是 item 以及下面的 with_item 选项,为 ansible 的固定结构。
# vim /etc/ansible/loop.yml
---
- hosts: testhosts
  user: root
  tasks:
    - name: change mod for file
      file: path=/tmp/{{ item }} mode=600 owner=test group=root
      with_items:
        - 1.txt
        - 2.txt

file 后面的 user 和 group 可以不用写,上面已经定义了 user
with_item 下面的 1.txt 和 2.txt 后面千万不能跟空格,空格也会被识别为文件的一部分。
核心部分就是 {{ item }} 以及下面的 with_items:

playbook 中的判断
playbook 类似 shell ,支持循环以及判断等特殊格式。
判断的关键选项 when
# vim /etc/ansible/when.yml
---
- hosts: testhosts
  remote_user: root
  gather_facts: True
  tasks:
    - name: use when
      shell: touch /tmp/when.txt
      when: facter_ipaddress == "192.168.32.150"

gather_facts  这里用到的信息是来判断 ip 地址是不是 192.168.32.150
when 就是执行条件,facter_ipaddress 就是通过 gather_facts 得到的信息,ansible testhosts -m setup 命令行执行可查看信息。facter_ipaddress 已经不再支持,需要更改为 ansible_eth0.ipv4.address 


playbook 的特性 handlers
handlers 的目的是在执行完成 tasks 之后,还需要进行其他的操作时,使用 handlers。但是这里需要保证只有在 tasks 执行成功之后,handlers 才会生效。 这种比较适合配置文件发生更改后,自动重启服务的操作。
# vim /etc/ansible/handlers.yml
---
- hosts: testhosts
  remote_user: root
  tasks:
    - name: test copy
      copy: src=/tmp/1.txt dest=/tmp/2.txt
      notify: test handlers
  handlers:
    - name: test handlers
      shell: echo "121212" >> /tmp/2.txt
请注意: src=/tmp/1.txt 文件是指本机的文件, dest=/tmp/2.txt文件是拷贝到testhosts文件中
关键点在于 notify,在 copy 成功之后,执行 handlers,notify 后面的名字,对应的是 handlers 选项中的 - name 选项,如果没有写 notify,就不会执行 handlers 里面的命令。
NOTE: copy 有个特性,和 rsync 类似,如果拷贝的两个文件内容一模一样,那就就不会进行拷贝的操作,在这个 handlers 的文件中,也就不会去执行 handlers 的操作。
一键修补bash shellcode示例
再给出一个稍微复杂的示例,通过ansible-playbook实现对N台主机同时修补bash shellcode 漏洞。需要注意的是,可能现网主机分布着不同的系统版本。这里假设现网同时存在centos5和6版本,具体playbook内容如下:
# cat update_bash.yml
- hosts: all
remote_user: root
gather_facts: True
tasks:
- name: update bash in redhat 6 version
yum: name=http://mirrors.aliyun.com/centos/6.6/os/x86_64/Packages/bash-4.1.2-29.el6.x86_64.rpm.rpm state=present
when: ansible_os_family == "RedHat" and ansible_distribution_version|int >=6
- name: update bash in redhat 5 version
yum: name=http://mirrors.hustunique.com/centos/5/updates/x86_64/RPMS/bash-3.2-33.el5.1.x86_64.rpm state=present
when: ansible_os_family == "RedHat" and ansible_distribution_version|int <=5

 

上面使用了when语句,同时也开启了gather_facts setup模块,这里的ansible_os_family变量和ansible_distribution_version变量就是直接使用的setup模块获取的信息。

如果有大量主机,就在运行的时候加上-f然后选择一个合适的并发主机数量即可,我这里使用了这个,很快的就升级完成bash了