如何使用Ansible Playbook编写并执行长尾词的自动化任务?

2026-04-12 16:421阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2876个文字,预计阅读时间需要12分钟。

如何使用Ansible Playbook编写并执行长尾词的自动化任务?

一、Playbook的基本语法和常用命令+Ansible的Playbook文件格式为YAML语法,菜鸟教程:YAML入门介绍。

二、案例展示:添加定时服务配置,重启crond服务。

第一行:表示YAML文件开始。

第二行:定义一个变量,名为cron,值为一个字典,包含以下内容:- 定义一个任务,名为重启crond,使用shell模块执行重启命令。- 定义定时任务,每小时执行一次。

第三行:表示YAML文件结束。


一、playbook的基本语法和常用命令

ansible的playbook文件格式为yaml语法,菜鸟教程:YAML入门介绍。
展示一个案例,加了定时服务配置,重启crond服务。

第一行:表示YAML文件;
第二行:定义该playbook针对的目标主机,all表示针对所有主机,这个此参数支持Ansible Ad-doc模式的所有参数;
第三行:定义该playbook所有tasks的集合,样例中是两个task;
第四行:定义一个task的名称,非必须,但建议 根据task实际任务命名;
第五行:使用template模板去管理crontab文件,定义属主和组,文件权限;
第七行:notify是触发handlers,如果同步后,文件的MD5值发生变化会触发Restart Crond Service这个handler;
第九行至十一行:定义一个handler状态让nginx服务重启,handler的名称:Restart Crond Service。

[root@hadoop1010 nginx_v1]# cat crond.yaml --- - hosts: all tasks: - name: Copy /etc/crontab template: src=crontab.j2 dest=/etc/crontab owner=root group=root mode=0644 #notify 检测到源文件和目标文件的MD值发生变化时触发handlers notify: - Restart Crond Service handlers: - name: Restart Crond Service service: name=crond state=restarted

修改模板:crontab.j2 之后,执行playbook的测试效果:


在编写yaml文件时,建议用编译器,比如idea或是pycharm。

  • 执行playbook,后面带参数:–syntax-check ,检测语法是否正确:
  • 根据报错提示进行修正。
  • 执行playbook,后面带参数:–list-task,查看playbook下所有task;
  • 执行playbook,后面带参数:–list-hosts,查看playbook的目标主机;
  • 执行playbook,后面带参数:–start-at-task=‘task名称’,针对某个任务执行;
  • 执行playbook,后面带参数:–step,进行交互式执行task;

二、playbook变量与引用

2.1 通过Inventory文件定义主机及主机组变量

[root@hadoop1010 nginx]# cat variable.yaml --- - hosts: all gather_facts: False tasks: - name: display Host Variable from hostfile debug: msg="The {{inventory_hostname}} Value is {{key}}" [root@hadoop1010 nginx]# cat hosts [nginx] 192.168.10.1[0:2] [nginx:vars] ansible_python_interpreter=/usr/bin/python2.7 key=nginx [root@hadoop1010 nginx]# cat hosts1 192.168.10.10 key=100 192.168.10.11 key=110 192.168.10.12 key=120 [root@hadoop1010 nginx]# ansible-playbook -i hosts1 variable.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [display Host Variable from hostfile] ****************************************************************************************************************************************************** ok: [192.168.10.10] => { "msg": "The 192.168.10.10 Value is 100" } ok: [192.168.10.11] => { "msg": "The 192.168.10.11 Value is 110" } ok: [192.168.10.12] => { "msg": "The 192.168.10.12 Value is 120" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=1 changed=0 unreachable=0 failed=0 [root@hadoop1010 nginx]# ansible-playbook -i hosts variable.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [display Host Variable from hostfile] ****************************************************************************************************************************************************** ok: [192.168.10.10] => { "msg": "The 192.168.10.10 Value is nginx" } ok: [192.168.10.11] => { "msg": "The 192.168.10.11 Value is nginx" } ok: [192.168.10.12] => { "msg": "The 192.168.10.12 Value is nginx" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=1 changed=0 unreachable=0 failed=0

2.2 通过/etc/ansible下的文件定义主机以及主机组变量

默认使用yum安装ansible的配置文件时在 /etc/ansible目录下,可以使用该目录下新建host_vars和group_vars目录来针对主机和主机组定义变量。若是用其他方式安装ansible,只需要在playbook文件当前目录下新建这两个目录。

2.3 通过ansile-playbook命令行传入

通过ansible-playbook命令行传参的方式定义变量,默认传进去时全局变量。

如何使用Ansible Playbook编写并执行长尾词的自动化任务?


目前ansible-playbook还支持指定文件的方式传入变量,变量的文件内容支持YAML和JSON两种格式:

2.4 在playbook文件内使用vars

在文件内通过vars字段定义变量:

2.5 在playbook文件内使用var_files

在playbook文件内通过var_files字段引用变量,首先把所有的变量定义到某个文件内,然后playbook文件内使用var_files参数引用这个变量文件。

注意:变量文件路径实在playbook下的。

2.6 使用register内的变量

ansible playbook内的task之间还可以相互传递数据,比如我们总共有两个task是,其中第2个task执行与否要判断第1个task运行后的结果,这个时候我们就得在task之间传递数据,需要把第1个task执行的结果传递给第2个task。ansible task之间传递数据使用register方式。


执行效果:

指定标准输出的stdout的信息输出

2.7 使用vars_prompt传入

ansible还支持在运行playbook的时候童话刚刚交互式的方式给定义好的参数传入变量值,只需要在playbook中定义var_prompt的变量名和交互式提示内容即可。

ansible还可以对输入变量值进行加密处理,比如采用SHA512和MD5算法加密。加密方式在可参照之前博客ansible组件介绍和简单playbook测试。


已经介绍了7种比较常用的定义变量以及如何引用的方式。ansible的变量引用方式相对比较少,都是比较固定的{{key}}或{{key[‘key’]}}或{{key[0][‘key’]}},根据变量的值定义了不同的数据结构,因而变量引用方法稍微有区别。

三、playbook循环

在编写playbook的过程中,发现有很多的task都是重复引用某个模块,比如一次想同步10个文件,如果按照以前写playbook的思路需要写10个task,这样的话playbook会显得臃肿。采用loops方式区编写playbook减少重复使用某个模块。

下面介绍几种常见的loops

3.1 标准循环

标准loops是我们在编写playbook过程中使用最多的一种loops,它能直接减少编写task的次数。


with_items的值时python list数据结构,可以理解为每个task会循环读取list里面的值,然后key的名称时item,list里面也支持python字典。

3.2 嵌套loops

[root@hadoop1010 loops]# cat loopsqt.yaml --- - hosts: all gather_facts: False tasks: - name: give users access to multiple databases debug: msg="name={{ item[0] }} priv={{ item[1] }}" with_nested: - [ 'alice', 'bob' ] - [ 'clientdb', 'employeedb', 'providerdb' ] [root@hadoop1010 loops]# ansible-playbook loopsqt.yaml -l 192.168.10.11 PLAY [all] ************************************************************************************************************************************************************************************** TASK [give users access to multiple databases] ************************************************************************************************************************************************** ok: [192.168.10.11] => (item=[u'alice', u'clientdb']) => { "changed": false, "item": [ "alice", "clientdb" ], "msg": "name=alice priv=clientdb" } ok: [192.168.10.11] => (item=[u'alice', u'employeedb']) => { "changed": false, "item": [ "alice", "employeedb" ], "msg": "name=alice priv=employeedb" } ok: [192.168.10.11] => (item=[u'alice', u'providerdb']) => { "changed": false, "item": [ "alice", "providerdb" ], "msg": "name=alice priv=providerdb" } ok: [192.168.10.11] => (item=[u'bob', u'clientdb']) => { "changed": false, "item": [ "bob", "clientdb" ], "msg": "name=bob priv=clientdb" } ok: [192.168.10.11] => (item=[u'bob', u'employeedb']) => { "changed": false, "item": [ "bob", "employeedb" ], "msg": "name=bob priv=employeedb" } ok: [192.168.10.11] => (item=[u'bob', u'providerdb']) => { "changed": false, "item": [ "bob", "providerdb" ], "msg": "name=bob priv=providerdb" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.11 : ok=1 changed=0 unreachable=0 failed=0

3.3 对哈希表使用循环

[root@hadoop1010 loops]# cat loopshash1.yaml --- - hosts: all gather_facts: False vars_files: - vars/user.yaml tasks: - name: Print phone records debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" with_dict: "{{users}}" [root@hadoop1010 loops]# cat loopshash.yaml --- - hosts: all gather_facts: False tasks: - name: Print phone records debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" with_dict: "{{users}}" [root@hadoop1010 loops]# cat vars/user.yaml --- users: alice: name: Alice Appleworth telephone: 123-456-7890 bob: name: Bob Bananarama telephone: 987-654-3210

执行效果:


3.4 对文件列表使用循环


3.5 对并行数据集使用循环

假设你通过某种方式加载了以下变量数据:
alpha: [ ‘a’, ‘b’, ‘c’, ‘d’ ]
numbers: [ 1, 2, 3, 4 ]
如果你想得到’(a, 1)’和’(b, 2)’之类的集合.可以使用’with_together’:

[root@hadoop1010 loops]# cat loopspral.yaml --- - hosts: all gather_facts: False vars_files: - vars/var1.yaml tasks: - debug: msg="{{ item.0 }} and {{ item.1 }}" with_together: - "{{lpha}}" - "{{numbers}}" [root@hadoop1010 loops]# cat vars/var1.yaml --- lpha: [ 'a', 'b', 'c', 'd' ] numbers: [ 1, 2, 3, 4 ]

执行效果:

3.6 随机选择

--- - hosts: all gather_facts: False tasks: - name: debug random choose debug: msg="name ========> {{ item }}" with_random_choice: - hadoop1 - 'hadoop2' - 'hadoop3' - 'hello hadoop'

3.7 条件判断

判断时间是否达到预计的时间,重试次数是5次,时间间隔是5s,如果达到预设值,任务执行成功,否则任务执行失败。

[root@hadoop1010 loops]# cat loopstiem.yaml --- - hosts: all gather_facts: False tasks: - name: debug loops shell: date '+%Y%m%d%H%M' register: time until: time.stdout.startswith('202303081709') retries: 5 delay: 5

执行成功:


执行失败:

3.8 循环中使用注册器

[root@hadoop1010 loops]# cat loopsregister.yaml #register loop --- - hosts: all gather_facts: True tasks: - name: debug loops register use shell: "{{ item }}" with_items: - 'hostname' - 'uname' - 'date "+%Y%m%d"' - 'uname -r' - 'echo $JAVA_HOME' register: ret - name: display loops debug: msg="{% for i in ret.results %} {{i.stdout}} {% endfor %}"

调测


执行效果

四、playbook的lookups

lookups插件是Jinja2模板语言的Ansible特定扩展。可以使用lookups插件从playbook中的外部源(文件、数据库、密钥/值存储、API和其他服务)访问数据。与所有模板一样,查找在Ansible控制机器上执行和评估。Ansible使用标准模板系统使查找插件返回的数据可用。可以使用查找插件从外部源加载包含信息的变量或模板。也可以创建自定义查找插件。

4.1 lookup files

[root@hadoop1010 lookups]# cat lookups1.yaml - hosts: all gather_facts: no tasks: - name: get file content with /tmp/test.txt set_fact: test: "{{ lookup('file', '/etc/hostname') }}" - name: register shell: cat /etc/hostname register: register_key - name: debug test and register_key debug: msg: - "{{ test }}" - "{{ register_key['stdout'] }}" [root@hadoop1010 lookups]# ansible-playbook lookups1.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [get file content with /tmp/test.txt] ****************************************************************************************************************************************************** ok: [192.168.10.11] ok: [192.168.10.10] ok: [192.168.10.12] TASK [register] ********************************************************************************************************************************************************************************* changed: [192.168.10.10] changed: [192.168.10.11] changed: [192.168.10.12] TASK [debug test and register_key] ************************************************************************************************************************************************************** ok: [192.168.10.11] => { "msg": [ "hadoop1010", "hadoop1011" ] } ok: [192.168.10.12] => { "msg": [ "hadoop1010", "hadoop1012" ] } ok: [192.168.10.10] => { "msg": [ "hadoop1010", "hadoop1010" ] } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=3 changed=1 unreachable=0 failed=0 192.168.10.11 : ok=3 changed=1 unreachable=0 failed=0 192.168.10.12 : ok=3 changed=1 unreachable=0 failed=0 [root@hadoop1010 lookups]#

4.2 lookup pipe

[root@hadoop1010 lookups]# cat lookupspip.yaml --- - hosts: all gather_facts: False tasks: - name: get contents set_fact: contents: "{{lookup('pipe','date +%Y%m%d')}}" - name: debug lookups debug: msg: - "The contents is {% for i in contents.split('\n') %} {{ i }} {% endfor %} " [root@hadoop1010 lookups]# ansible-playbook lookupspip.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [get contents] ***************************************************************************************************************************************************************************** ok: [192.168.10.12] ok: [192.168.10.11] ok: [192.168.10.10] TASK [debug lookups] **************************************************************************************************************************************************************************** ok: [192.168.10.11] => { "msg": [ "The contents is 20230308 " ] } ok: [192.168.10.10] => { "msg": [ "The contents is 20230308 " ] } ok: [192.168.10.12] => { "msg": [ "The contents is 20230308 " ] } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=2 changed=0 unreachable=0 failed=0 [root@hadoop1010 lookups]#

4.3 lookup template

[root@hadoop1010 lookups]# cat lookupstemplate.yaml --- - hosts: all gather_facts: False tasks: - name: get contents set_fact: contents: "{{lookup('template','./templates/test.j2')}}" - name: debug lookups debug: msg: - "{% for i in contents.split('\n') %} {{ i }} {% endfor %}" [root@hadoop1010 lookups]# ansible-playbook lookupstemplate.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [get contents] ***************************************************************************************************************************************************************************** ok: [192.168.10.10] ok: [192.168.10.11] ok: [192.168.10.12] TASK [debug lookups] **************************************************************************************************************************************************************************** ok: [192.168.10.10] => { "msg": [ " 12345 1234124 1241412 sadsf 123123 adasfsa 12312 asfasf " ] } ok: [192.168.10.11] => { "msg": [ " 12345 1234124 1241412 sadsf 123123 adasfsa 12312 asfasf " ] } ok: [192.168.10.12] => { "msg": [ " 12345 1234124 1241412 sadsf 123123 adasfsa 12312 asfasf " ] } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=2 changed=0 unreachable=0 failed=0

五、playbook conditions

[root@hadoop1010 condition]# cat condition.yaml --- - hosts: all #gather_facts: False tasks: - name: Host 192.168.10.12 run this task debug: msg = "{{ ansible_default_ipv4.address }}" when: ansible_default_ipv4.address == '192.168.10.12' - name: memtotal < 500M and processor_cores == 2 run this task debug: msg = "{{ansible_fqdn}}" when: ansible_memtotal_mb < 500 and processor_cores == 2 - name: all host run this task shell: hostname register: info - name: Hostname is python Machie run this task debug: msg="{{ansible_fqdn}}" when: info['stdout'] == "hadoop1010" - name: Host mac is 00:0c:29:3a:f6:1c run this task debug: msg = "{{ ansible_default_ipv4.macaddress }}" when: ansible_default_ipv4.macaddress == "00:0c:29:3a:f6:1c" [root@hadoop1010 condition]# ansible-playbook condition.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************************** ok: [192.168.10.10] ok: [192.168.10.12] ok: [192.168.10.11] TASK [Host 192.168.10.12 run this task] ********************************************************************************************************************************************************* skipping: [192.168.10.11] skipping: [192.168.10.10] ok: [192.168.10.12] => { "msg": "Hello world!" } TASK [memtotal < 500M and processor_cores == 2 run this task] *********************************************************************************************************************************** skipping: [192.168.10.11] skipping: [192.168.10.12] skipping: [192.168.10.10] TASK [all host run this task] ******************************************************************************************************************************************************************* changed: [192.168.10.11] changed: [192.168.10.12] changed: [192.168.10.10] TASK [Hostname is python Machie run this task] ************************************************************************************************************************************************** skipping: [192.168.10.11] skipping: [192.168.10.12] ok: [192.168.10.10] => { "msg": "hadoop1010" } TASK [Host mac is 00:0c:29:3a:f6:1c run this task] ********************************************************************************************************************************************** skipping: [192.168.10.11] skipping: [192.168.10.10] ok: [192.168.10.12] => { "msg": "Hello world!" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=3 changed=1 unreachable=0 failed=0 192.168.10.11 : ok=2 changed=1 unreachable=0 failed=0 192.168.10.12 : ok=4 changed=1 unreachable=0 failed=0


本文共计2876个文字,预计阅读时间需要12分钟。

如何使用Ansible Playbook编写并执行长尾词的自动化任务?

一、Playbook的基本语法和常用命令+Ansible的Playbook文件格式为YAML语法,菜鸟教程:YAML入门介绍。

二、案例展示:添加定时服务配置,重启crond服务。

第一行:表示YAML文件开始。

第二行:定义一个变量,名为cron,值为一个字典,包含以下内容:- 定义一个任务,名为重启crond,使用shell模块执行重启命令。- 定义定时任务,每小时执行一次。

第三行:表示YAML文件结束。


一、playbook的基本语法和常用命令

ansible的playbook文件格式为yaml语法,菜鸟教程:YAML入门介绍。
展示一个案例,加了定时服务配置,重启crond服务。

第一行:表示YAML文件;
第二行:定义该playbook针对的目标主机,all表示针对所有主机,这个此参数支持Ansible Ad-doc模式的所有参数;
第三行:定义该playbook所有tasks的集合,样例中是两个task;
第四行:定义一个task的名称,非必须,但建议 根据task实际任务命名;
第五行:使用template模板去管理crontab文件,定义属主和组,文件权限;
第七行:notify是触发handlers,如果同步后,文件的MD5值发生变化会触发Restart Crond Service这个handler;
第九行至十一行:定义一个handler状态让nginx服务重启,handler的名称:Restart Crond Service。

[root@hadoop1010 nginx_v1]# cat crond.yaml --- - hosts: all tasks: - name: Copy /etc/crontab template: src=crontab.j2 dest=/etc/crontab owner=root group=root mode=0644 #notify 检测到源文件和目标文件的MD值发生变化时触发handlers notify: - Restart Crond Service handlers: - name: Restart Crond Service service: name=crond state=restarted

修改模板:crontab.j2 之后,执行playbook的测试效果:


在编写yaml文件时,建议用编译器,比如idea或是pycharm。

  • 执行playbook,后面带参数:–syntax-check ,检测语法是否正确:
  • 根据报错提示进行修正。
  • 执行playbook,后面带参数:–list-task,查看playbook下所有task;
  • 执行playbook,后面带参数:–list-hosts,查看playbook的目标主机;
  • 执行playbook,后面带参数:–start-at-task=‘task名称’,针对某个任务执行;
  • 执行playbook,后面带参数:–step,进行交互式执行task;

二、playbook变量与引用

2.1 通过Inventory文件定义主机及主机组变量

[root@hadoop1010 nginx]# cat variable.yaml --- - hosts: all gather_facts: False tasks: - name: display Host Variable from hostfile debug: msg="The {{inventory_hostname}} Value is {{key}}" [root@hadoop1010 nginx]# cat hosts [nginx] 192.168.10.1[0:2] [nginx:vars] ansible_python_interpreter=/usr/bin/python2.7 key=nginx [root@hadoop1010 nginx]# cat hosts1 192.168.10.10 key=100 192.168.10.11 key=110 192.168.10.12 key=120 [root@hadoop1010 nginx]# ansible-playbook -i hosts1 variable.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [display Host Variable from hostfile] ****************************************************************************************************************************************************** ok: [192.168.10.10] => { "msg": "The 192.168.10.10 Value is 100" } ok: [192.168.10.11] => { "msg": "The 192.168.10.11 Value is 110" } ok: [192.168.10.12] => { "msg": "The 192.168.10.12 Value is 120" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=1 changed=0 unreachable=0 failed=0 [root@hadoop1010 nginx]# ansible-playbook -i hosts variable.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [display Host Variable from hostfile] ****************************************************************************************************************************************************** ok: [192.168.10.10] => { "msg": "The 192.168.10.10 Value is nginx" } ok: [192.168.10.11] => { "msg": "The 192.168.10.11 Value is nginx" } ok: [192.168.10.12] => { "msg": "The 192.168.10.12 Value is nginx" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=1 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=1 changed=0 unreachable=0 failed=0

2.2 通过/etc/ansible下的文件定义主机以及主机组变量

默认使用yum安装ansible的配置文件时在 /etc/ansible目录下,可以使用该目录下新建host_vars和group_vars目录来针对主机和主机组定义变量。若是用其他方式安装ansible,只需要在playbook文件当前目录下新建这两个目录。

2.3 通过ansile-playbook命令行传入

通过ansible-playbook命令行传参的方式定义变量,默认传进去时全局变量。

如何使用Ansible Playbook编写并执行长尾词的自动化任务?


目前ansible-playbook还支持指定文件的方式传入变量,变量的文件内容支持YAML和JSON两种格式:

2.4 在playbook文件内使用vars

在文件内通过vars字段定义变量:

2.5 在playbook文件内使用var_files

在playbook文件内通过var_files字段引用变量,首先把所有的变量定义到某个文件内,然后playbook文件内使用var_files参数引用这个变量文件。

注意:变量文件路径实在playbook下的。

2.6 使用register内的变量

ansible playbook内的task之间还可以相互传递数据,比如我们总共有两个task是,其中第2个task执行与否要判断第1个task运行后的结果,这个时候我们就得在task之间传递数据,需要把第1个task执行的结果传递给第2个task。ansible task之间传递数据使用register方式。


执行效果:

指定标准输出的stdout的信息输出

2.7 使用vars_prompt传入

ansible还支持在运行playbook的时候童话刚刚交互式的方式给定义好的参数传入变量值,只需要在playbook中定义var_prompt的变量名和交互式提示内容即可。

ansible还可以对输入变量值进行加密处理,比如采用SHA512和MD5算法加密。加密方式在可参照之前博客ansible组件介绍和简单playbook测试。


已经介绍了7种比较常用的定义变量以及如何引用的方式。ansible的变量引用方式相对比较少,都是比较固定的{{key}}或{{key[‘key’]}}或{{key[0][‘key’]}},根据变量的值定义了不同的数据结构,因而变量引用方法稍微有区别。

三、playbook循环

在编写playbook的过程中,发现有很多的task都是重复引用某个模块,比如一次想同步10个文件,如果按照以前写playbook的思路需要写10个task,这样的话playbook会显得臃肿。采用loops方式区编写playbook减少重复使用某个模块。

下面介绍几种常见的loops

3.1 标准循环

标准loops是我们在编写playbook过程中使用最多的一种loops,它能直接减少编写task的次数。


with_items的值时python list数据结构,可以理解为每个task会循环读取list里面的值,然后key的名称时item,list里面也支持python字典。

3.2 嵌套loops

[root@hadoop1010 loops]# cat loopsqt.yaml --- - hosts: all gather_facts: False tasks: - name: give users access to multiple databases debug: msg="name={{ item[0] }} priv={{ item[1] }}" with_nested: - [ 'alice', 'bob' ] - [ 'clientdb', 'employeedb', 'providerdb' ] [root@hadoop1010 loops]# ansible-playbook loopsqt.yaml -l 192.168.10.11 PLAY [all] ************************************************************************************************************************************************************************************** TASK [give users access to multiple databases] ************************************************************************************************************************************************** ok: [192.168.10.11] => (item=[u'alice', u'clientdb']) => { "changed": false, "item": [ "alice", "clientdb" ], "msg": "name=alice priv=clientdb" } ok: [192.168.10.11] => (item=[u'alice', u'employeedb']) => { "changed": false, "item": [ "alice", "employeedb" ], "msg": "name=alice priv=employeedb" } ok: [192.168.10.11] => (item=[u'alice', u'providerdb']) => { "changed": false, "item": [ "alice", "providerdb" ], "msg": "name=alice priv=providerdb" } ok: [192.168.10.11] => (item=[u'bob', u'clientdb']) => { "changed": false, "item": [ "bob", "clientdb" ], "msg": "name=bob priv=clientdb" } ok: [192.168.10.11] => (item=[u'bob', u'employeedb']) => { "changed": false, "item": [ "bob", "employeedb" ], "msg": "name=bob priv=employeedb" } ok: [192.168.10.11] => (item=[u'bob', u'providerdb']) => { "changed": false, "item": [ "bob", "providerdb" ], "msg": "name=bob priv=providerdb" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.11 : ok=1 changed=0 unreachable=0 failed=0

3.3 对哈希表使用循环

[root@hadoop1010 loops]# cat loopshash1.yaml --- - hosts: all gather_facts: False vars_files: - vars/user.yaml tasks: - name: Print phone records debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" with_dict: "{{users}}" [root@hadoop1010 loops]# cat loopshash.yaml --- - hosts: all gather_facts: False tasks: - name: Print phone records debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" with_dict: "{{users}}" [root@hadoop1010 loops]# cat vars/user.yaml --- users: alice: name: Alice Appleworth telephone: 123-456-7890 bob: name: Bob Bananarama telephone: 987-654-3210

执行效果:


3.4 对文件列表使用循环


3.5 对并行数据集使用循环

假设你通过某种方式加载了以下变量数据:
alpha: [ ‘a’, ‘b’, ‘c’, ‘d’ ]
numbers: [ 1, 2, 3, 4 ]
如果你想得到’(a, 1)’和’(b, 2)’之类的集合.可以使用’with_together’:

[root@hadoop1010 loops]# cat loopspral.yaml --- - hosts: all gather_facts: False vars_files: - vars/var1.yaml tasks: - debug: msg="{{ item.0 }} and {{ item.1 }}" with_together: - "{{lpha}}" - "{{numbers}}" [root@hadoop1010 loops]# cat vars/var1.yaml --- lpha: [ 'a', 'b', 'c', 'd' ] numbers: [ 1, 2, 3, 4 ]

执行效果:

3.6 随机选择

--- - hosts: all gather_facts: False tasks: - name: debug random choose debug: msg="name ========> {{ item }}" with_random_choice: - hadoop1 - 'hadoop2' - 'hadoop3' - 'hello hadoop'

3.7 条件判断

判断时间是否达到预计的时间,重试次数是5次,时间间隔是5s,如果达到预设值,任务执行成功,否则任务执行失败。

[root@hadoop1010 loops]# cat loopstiem.yaml --- - hosts: all gather_facts: False tasks: - name: debug loops shell: date '+%Y%m%d%H%M' register: time until: time.stdout.startswith('202303081709') retries: 5 delay: 5

执行成功:


执行失败:

3.8 循环中使用注册器

[root@hadoop1010 loops]# cat loopsregister.yaml #register loop --- - hosts: all gather_facts: True tasks: - name: debug loops register use shell: "{{ item }}" with_items: - 'hostname' - 'uname' - 'date "+%Y%m%d"' - 'uname -r' - 'echo $JAVA_HOME' register: ret - name: display loops debug: msg="{% for i in ret.results %} {{i.stdout}} {% endfor %}"

调测


执行效果

四、playbook的lookups

lookups插件是Jinja2模板语言的Ansible特定扩展。可以使用lookups插件从playbook中的外部源(文件、数据库、密钥/值存储、API和其他服务)访问数据。与所有模板一样,查找在Ansible控制机器上执行和评估。Ansible使用标准模板系统使查找插件返回的数据可用。可以使用查找插件从外部源加载包含信息的变量或模板。也可以创建自定义查找插件。

4.1 lookup files

[root@hadoop1010 lookups]# cat lookups1.yaml - hosts: all gather_facts: no tasks: - name: get file content with /tmp/test.txt set_fact: test: "{{ lookup('file', '/etc/hostname') }}" - name: register shell: cat /etc/hostname register: register_key - name: debug test and register_key debug: msg: - "{{ test }}" - "{{ register_key['stdout'] }}" [root@hadoop1010 lookups]# ansible-playbook lookups1.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [get file content with /tmp/test.txt] ****************************************************************************************************************************************************** ok: [192.168.10.11] ok: [192.168.10.10] ok: [192.168.10.12] TASK [register] ********************************************************************************************************************************************************************************* changed: [192.168.10.10] changed: [192.168.10.11] changed: [192.168.10.12] TASK [debug test and register_key] ************************************************************************************************************************************************************** ok: [192.168.10.11] => { "msg": [ "hadoop1010", "hadoop1011" ] } ok: [192.168.10.12] => { "msg": [ "hadoop1010", "hadoop1012" ] } ok: [192.168.10.10] => { "msg": [ "hadoop1010", "hadoop1010" ] } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=3 changed=1 unreachable=0 failed=0 192.168.10.11 : ok=3 changed=1 unreachable=0 failed=0 192.168.10.12 : ok=3 changed=1 unreachable=0 failed=0 [root@hadoop1010 lookups]#

4.2 lookup pipe

[root@hadoop1010 lookups]# cat lookupspip.yaml --- - hosts: all gather_facts: False tasks: - name: get contents set_fact: contents: "{{lookup('pipe','date +%Y%m%d')}}" - name: debug lookups debug: msg: - "The contents is {% for i in contents.split('\n') %} {{ i }} {% endfor %} " [root@hadoop1010 lookups]# ansible-playbook lookupspip.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [get contents] ***************************************************************************************************************************************************************************** ok: [192.168.10.12] ok: [192.168.10.11] ok: [192.168.10.10] TASK [debug lookups] **************************************************************************************************************************************************************************** ok: [192.168.10.11] => { "msg": [ "The contents is 20230308 " ] } ok: [192.168.10.10] => { "msg": [ "The contents is 20230308 " ] } ok: [192.168.10.12] => { "msg": [ "The contents is 20230308 " ] } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=2 changed=0 unreachable=0 failed=0 [root@hadoop1010 lookups]#

4.3 lookup template

[root@hadoop1010 lookups]# cat lookupstemplate.yaml --- - hosts: all gather_facts: False tasks: - name: get contents set_fact: contents: "{{lookup('template','./templates/test.j2')}}" - name: debug lookups debug: msg: - "{% for i in contents.split('\n') %} {{ i }} {% endfor %}" [root@hadoop1010 lookups]# ansible-playbook lookupstemplate.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [get contents] ***************************************************************************************************************************************************************************** ok: [192.168.10.10] ok: [192.168.10.11] ok: [192.168.10.12] TASK [debug lookups] **************************************************************************************************************************************************************************** ok: [192.168.10.10] => { "msg": [ " 12345 1234124 1241412 sadsf 123123 adasfsa 12312 asfasf " ] } ok: [192.168.10.11] => { "msg": [ " 12345 1234124 1241412 sadsf 123123 adasfsa 12312 asfasf " ] } ok: [192.168.10.12] => { "msg": [ " 12345 1234124 1241412 sadsf 123123 adasfsa 12312 asfasf " ] } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.11 : ok=2 changed=0 unreachable=0 failed=0 192.168.10.12 : ok=2 changed=0 unreachable=0 failed=0

五、playbook conditions

[root@hadoop1010 condition]# cat condition.yaml --- - hosts: all #gather_facts: False tasks: - name: Host 192.168.10.12 run this task debug: msg = "{{ ansible_default_ipv4.address }}" when: ansible_default_ipv4.address == '192.168.10.12' - name: memtotal < 500M and processor_cores == 2 run this task debug: msg = "{{ansible_fqdn}}" when: ansible_memtotal_mb < 500 and processor_cores == 2 - name: all host run this task shell: hostname register: info - name: Hostname is python Machie run this task debug: msg="{{ansible_fqdn}}" when: info['stdout'] == "hadoop1010" - name: Host mac is 00:0c:29:3a:f6:1c run this task debug: msg = "{{ ansible_default_ipv4.macaddress }}" when: ansible_default_ipv4.macaddress == "00:0c:29:3a:f6:1c" [root@hadoop1010 condition]# ansible-playbook condition.yaml PLAY [all] ************************************************************************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************************** ok: [192.168.10.10] ok: [192.168.10.12] ok: [192.168.10.11] TASK [Host 192.168.10.12 run this task] ********************************************************************************************************************************************************* skipping: [192.168.10.11] skipping: [192.168.10.10] ok: [192.168.10.12] => { "msg": "Hello world!" } TASK [memtotal < 500M and processor_cores == 2 run this task] *********************************************************************************************************************************** skipping: [192.168.10.11] skipping: [192.168.10.12] skipping: [192.168.10.10] TASK [all host run this task] ******************************************************************************************************************************************************************* changed: [192.168.10.11] changed: [192.168.10.12] changed: [192.168.10.10] TASK [Hostname is python Machie run this task] ************************************************************************************************************************************************** skipping: [192.168.10.11] skipping: [192.168.10.12] ok: [192.168.10.10] => { "msg": "hadoop1010" } TASK [Host mac is 00:0c:29:3a:f6:1c run this task] ********************************************************************************************************************************************** skipping: [192.168.10.11] skipping: [192.168.10.10] ok: [192.168.10.12] => { "msg": "Hello world!" } PLAY RECAP ************************************************************************************************************************************************************************************** 192.168.10.10 : ok=3 changed=1 unreachable=0 failed=0 192.168.10.11 : ok=2 changed=1 unreachable=0 failed=0 192.168.10.12 : ok=4 changed=1 unreachable=0 failed=0