Ansible-playbook高级用法
Ansible Playbook是基于Yaml语法的ansible命令文件,简单来说,可以理解为linux的普通命令和shell脚本的区别,通过playbook,可以实现更复杂的操作。
下面是一个部署nfs远程挂载的ansible playbook
---- name: setup nfs server hosts: nfs tasks: - name: 01 - install nfs-utils yum: name: nfs-utils state: installed - name: 02 - install rpcbind yum: name: rpcbind state: installed - name: 03 - start and enable nfs-utils systemd: name: nfs-utils state: started enabled: true - name: 04 - start and enable rpcbind systemd: name: rpcbind state: started enabled: true - name: 05 - setup nfs configuration shell: cmd: "echo '/data 172.16.1.0/24(rw,sync,all_squash)' >> /etc/exports" - name: 06 - change wordpress file user and group file: path: /data state: directory owner: nfsnobody group: nfsnobody recurse: true - name: 09 - start and enable nfs systemd: name: nfs state: started enabled: true
- name: mount wordpress files to web server hosts: web tasks: - name: 01 - install rpcbind yum: name: rpcbind state: installed - name: 02 - install nfs-utils yum: name: nfs-utils state: installed - name: 03 - start and enable nfs-utils systemd: name: nfs-utils state: started enabled: true - name: 04 - create mount directory file: path: /www state: directory - name: 05 - restart rpcbind systemd: name: rpcbind state: restarted enabled: true - name: 06 - mount mount: src: 172.16.1.31:/wordpress path: /www fstype: nfs state: mounted从这个playbook可以看出,部分内容是重复的,但是通过playbook的高级用法可以更简单的实现相同的功能。
Loop循环
- 使用loop关键字定义循环变量
- 使用item关键字提取loop每次循环出来的值
以nfs服务器中安装nfs-utils和rpcbind为例,使用loop可以让我们在一个模块中安装两个应用。
---- name: install nfs-utils and rpcbind hosts: nfs tasks: - name: installation yum: name: "{{ item }}" state: installed loop: - nfs-utils - rpcbind如此一来,我们就实现了通过循环安装多个软件。
但是,可以发现我们后面一样要通过systemd模块来运行并为这两个应用设置开机自启;目前loop循环是置于name: installation下面,没办法在其他的模块中使用,因此,引入下一个概念:vars
使用vars定义循环列表
通过vars关键字我们可以为循环配置一个变量名,让这个循环可以被同级的任何一个模块使用。
---- name: setup nfs applications hosts: nfs vars: app: - nfs-utils - rpcbind tasks: - name: installation yum: name: "{{ item }}" state: installed loop: "{{ app }}" - name: start and set enabled systemd: name: "{{ item }}" state: started enabled: true loop: "{{ app }}"循环处理字典数据
假如我要创建三个文件,他们的属主各不相同,应该如果实现呢?
---- name: create files for three different users hosts: web tasks: - name: create files file: path: "{{ item.path }}" state: touch owner: "{{ item.owner }}" loop: - {path: '/opt/mike.txt', owner: mike} - {path: '/opt/sarah.txt', owner: sarah} - {path: '/opt/john.txt', owner: john}当然,字典循环也可以被声明成一个变量,和之前的差不多,就不加赘述了。
Register将模块的输出结果注册为变量
Register可以将模块的执行结果注册为一个变量,并通过debug模块中的.stdout_lines输出到ansible管理终端。
例如,我想要知道一个文本文件中有多少行:
---- name: how many lines for the text file hosts: 172.16.1.105 tasks: - name: count lines shell: cmd: "cat /opt/testfile.txt | wc -l" register: lines
- name: output the value debug: msg: "{{ lines.stdout_lines }}"注册多个变量并和loop结合使用
在之前的基础上再查看一下目标主机名
---- name: register and loop hosts: 172.16.1.105 tasks: - name: count lines shell: cmd: "cat /opt/testfile.txt | wc -l" register: lines - name: show hostname shell: cmd: "cat /etc/hostname" register: hostname
- name: output the value debug: msg: "{{ item }}" loop: - lines.stdout_lines - hostname.stdout_linesWhen条件判断
when通常和register组合使用,以实现通过判断执行结果来指定后续操作。
以查看文件为例:
---- name: how many lines for the text file hosts: 172.16.1.105 tasks: - name: count lines shell: cmd: "cat /opt/testfile.txt" ignore_errors: true register: result
- name: output the value debug: msg: "FATAL: File does not exists" when: result is failedignore_errors: 忽略报错继续向后执行
与ansible的内置变量相结合,还可以实现更多的有趣的功能;比如我想为web主机组下的所有主机创建一个文件,但其中一台主机不包括在内,这就可以用内置变量加条件判断的方法来实现:
---- name: how many lines for the text file hosts: web tasks: - name: count lines file: path: /opt/file.txt state: touch when: inventory_hostname != "172.16.1.7"inventory_hostname: 目标主机名 - 取决于你在hosts文件中是如何配置的(ip或者别名)
Notify和Handler
当调用某个任务确实执行了,且状态changed为true,notify就会执行指定的handler事件
还是以创建文件为例:
---- hosts: web tasks: - name: create file file: path: /opt/testfile.txt state: touch mode: 600 notify: - output message
handlers: - name: output message debug: msg: "File created"使用Tags为不同的task打标签,实现剧本的部分执行
- name: deploy nfs hosts: nfs tasks: - name: 01 - install nfs-utils yum: name=nfs-utils state=installed tags: 01_install_nfs_service
- name: 02 - install rpcbind yum: name=rpcbind state=installed tags: 02_install_rpcbind_service
- name: 03 - create group group: name=www gid=666 tags: 03_add_group
- name: 04 - create user user: name=www uid=666 group=www create_home=no shell=/sbin/nologin tags: 04_add_user显示剧本的所有tag标签:
ansible-playbook --list-tags playbook.yml使用-t参数根据tag执行部分剧本:
ansible-playbook -t tag名 playbook.yml对一开始的部署nfs挂载剧本进行改造
---- name: setup nfs server hosts: nfs vars: app: - nfs-utils - rpcbind tasks: - name: 01 - install apps yum: name: "{{ item }}" state: installed loop: "{{ app }}" - name: 02 - start and enable apps systemd: name: "{{ item }}" state: started enabled: true loop: "{{ app }}" - name: 03 - setup nfs configuration shell: cmd: "echo '/data 172.16.1.0/24(rw,sync,all_squash)' >> /etc/exports" notify: - start NFS
handlers: - name: start NFS systemd: name: nfs state: started enabled: true - name: 04 - change wordpress file user and group file: path: /data state: directory owner: nfsnobody group: nfsnobody recurse: true
- name: mount directory to web server hosts: web vars: app: - nfs-utils - rpcbind tasks: - name: 01 - install apps yum: name: "{{ item }}" state: installed loop: "{{ app }}" - name: 02 - start and enable apps systemd: name: "{{ item }}" state: started enabled: true loop: "{{ app }}" - name: 03 - create mount directory file: path: /www state: directory - name: 04 - mount mount: src: 172.16.1.31:/data path: /www fstype: nfs state: mounted支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
部分内容可能已过时