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了