date: 2020-10-26title: Ansible:tags用法 #标题
tags: ansible #标签
categories: ansible # 分类

你写了一个很长的playbook,其中有很多的任务,这并没有什么问题,不过在实际使用这个剧本时,你可能只是想要执行其中的一部分任务而已,或者,你只想要执行其中一类任务而已,而并非想要执行整个剧本中的全部任务,这个时候我们该怎么办呢?我们可以借助tags实现这个需求。

tags牛刀小试

见名知义,tags可以帮助我们对任务进行“打标签”的操作,当任务存在标签以后,我们就可以在执行playbook时,借助标签,指定执行哪些任务,或者指定不执行哪些任务了,这样说可能不够直观,我们来看一个小示例:

  1. - hosts: 192.168.10.3
  2. remote_user: root
  3. tasks:
  4. - name: task1
  5. file:
  6. path: /test/t1
  7. state: touch
  8. tags: t1
  9. - name: task2
  10. file:
  11. path: /test/t2
  12. state: touch
  13. tags: t2
  14. - name: task3
  15. file:
  16. path: /test/t3
  17. state: touch
  18. tags: t3

如上例所示,上例的play中有3个task,每个task都有对应的tags,为了方便示例,我只是简单的把tags的值写成了t1、t2、t3,在实际的使用中,我们应该让tags的值能够见名知义,现在每个task都有了标签,假如在执行上述playbook时,我们只想执行task2,该怎样执行呢?我们可以使用如下命令:

  1. $ ansible-playbook --tags=t2 play5.yml

如你所见,可以使用—tags选项指定某个标签,当指定标签后,只有标签对应的任务会被执行,其他任务都不会被执行,执行上述命令后,只有task2会执行,因为task2的标签值为t2,task1和task3都不会执行,这样就达到了只执行playbook中部分任务的目的。

借助标签,除了能够指定“需要执行的任务”,还能够指定“不执行的任务”,示例命令如下:

  1. $ ansible-playbook --skip-tags='t2' play5.yml

我们可以使用 —skip-tags选项指定“不执行的任务”,执行上述命令后,task1和task3会执行,task2不会执行,因为我们已经在命令中指定了 “跳过” 标签t2所对应的任务,相当于使用了“排除法”,t2对应的任务被排除了,其他任务都会执行。

除了使用上例中的语法指定标签,还能够使用下例中的三种语法指定标签的值:

  1. 语法一:
  2. tags:
  3. - t1
  4. - t2
  5. 语法二:
  6. tags: t1,t2
  7. 语法三:
  8. tags:['t1','t2']

在ploybook中,不同任务可以使用相同的标签,如下:

  1. ---
  2. - hosts: 192.168.10.3
  3. remote_user: root
  4. tasks:
  5. - name: INSTALL HTTPD PACKEGE
  6. tags: httpd,packege
  7. yum:
  8. name: httpd
  9. state: latest
  10. - name: START UP HTTPD SERVICE
  11. tags: httpd,service
  12. service:
  13. name: httpd
  14. state: started

上例中每个任务都有多个标签,而且上例中两个任务都有一个共同的标签,就是httpd标签,所以,当我们执行“ansible-playbook —tags=httpd play6.yml”,上述两个任务都会执行。

上例的play中的所有任务都有共同的httpd标签,像这种情况,我们可以把httpd标签提取出来,写在play中,示例如下:

  1. ---
  2. - hosts: 192.168.10.3
  3. remote_user: root
  4. tags: httpd #tags一定要放在tasks里面,否则报错。
  5. tasks:
  6. - name: INSTALL HTTPD PACKEGE
  7. tags: packege
  8. yum:
  9. name: httpd
  10. state: latest
  11. - name: START UP HTTPD SERVICE
  12. tags: service
  13. service:
  14. name: httpd
  15. state: started

当tags写在play中而非task中时,play中的所有task会继承当前play中的tags,而上例中,两个任务都会继承httpd标签,同时还有拥有自己的标签。

在调用标签时,也可以一次性指定多个标签,调用多个标签需要用逗号隔开,命令如下:

  1. $ ansible-playbook --tags packege,service play6.yml

在调用标签之前,如果你想要概览一下playbook中都有哪些标签,可以使用 “—list-tags” 选项,示例如下:

  1. $ ansible-playbook --list-tags play6.yml

ansible中内置的特殊tag

ansible中内置了5个特殊的tag,分别是:

  • always
  • never
  • tagged
  • untagged
  • all

always 标签

当我们把任务的tags的值指定为always时,那么这个任务就总是会被执行,除非你使用”—skip-tags”选项明确指定不执行对应的任务,这样说可能不容易理解,不如看个小示例,示例如下:

  1. ---
  2. - hosts: 192.168.10.2
  3. remote_user: root
  4. tasks:
  5. - name: taks1
  6. file:
  7. path: /test/t1
  8. state: touch
  9. tags: t1
  10. - name: tasks2
  11. file:
  12. path: /test/t2
  13. state: touch
  14. tags: ['t2']
  15. - name: task3
  16. file:
  17. path: /test/t3
  18. state: touch
  19. tags:
  20. - t3
  21. - always

上例中,task3的标签有两个,t3和always,那么我们来执行一下这个playbook,假设,我只想运行上述playbook中标签为t1的任务,那么我会执行如下图中的命令:

Ansible:tags用法 - 图1

如图所示,在执行上述playbook时,我只指定了“t1”,正常情况下应该只执行“t1”对应的任务,也就是应该只执行task1,但是实际上执行了task1和task3,这是因为task3的标签的值包含always关键字,所以即使task3对应的标签没有被调用,task3也会执行,这就是always的作用。

如果你不想执行标签中包含always的任务,你可以使用“—skip-tags”选项明确指定跳过它们,仍然以上例的playbook为例,假设我们就是不想执行task3,我们可以执行如下命令:

  1. $ ansible-playbook --skip-tags always play7.yml

但是需要注意,如果上述play中有多个任务都有always标签,那么上述命令将会跳过所有包含always标签的任务,如果上例中的play中的多个任务都有always标签,则可以使用如下命令只跳过task3,其他带有always标签的任务不会跳过,前提是task3有除了always以外的自定义标签。我们可以执行如下命令:

  1. $ ansible-playbook --skip-tags t3 play7.yml

never标签

never标签的含义,顾名思义,它是和always标签恰恰相反的,表示总是不执行,示例如下:

  1. ---
  2. - hosts: 192.168.10.2
  3. remote_user: root
  4. tasks:
  5. - name: taks1
  6. file:
  7. path: /test/t1
  8. state: touch
  9. tags: t1
  10. - name: tasks2
  11. file:
  12. path: /test/t2
  13. state: touch
  14. tags: ['t2']
  15. - name: task3
  16. file:
  17. path: /test/t3
  18. state: touch
  19. tags:
  20. - t3
  21. - never

当我们执行这个剧本时,发现插入了never标签的剧本,默认不执行:只有标签t1 t2的tasks执行了。

Ansible:tags用法 - 图2

tagged标签

tagged标签,表示只执行有标签的任务,没有任何标签的任务将不会被执行:

  1. $ ansible-playbook --tags tagged play7.yml

下述命令表示跳过包含标签的任务,即使对应的任务包含always标签,也会被跳过:

  1. $ ansible-playbook --skip-tags tagged play7.yml

untagged标签

下述命令表示只执行没有标签的任务,但是如果某些任务包含always标签,那么这些任务也会被执行:

  1. $ ansible-playbook --tags untagged play7.yml

下述命令表示跳过没有标签的任务执行,也就是执行有标签的任务:

  1. $ ansible-playbook --skip-tags untagged play7.yml