ansible笔记(5)之tags

ansible笔记(5)之tags

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

本来打算自己写一波 ansible 系列的,后来发现一老哥写的太好了,「点击此处直达」,我这里也就边看边对该系列文章做下笔记,方便以后查阅,ansible 入门的话墙裂建议阅读前方链接博文~~~

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

---
- hosts: all
  remote_user: root
  tasks:
  - name: task1
    file:
      path: /testdir/t1
      state: touch
    tags: t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: t2
  - name: task3
    file: path=/testdir/t3
          state=touch
    tags: t3

如上例所示,上例的 play 中有 3 个task,每个 task 都有对应的 tags,为了方便示例,我只是简单的把 tags 的值写成了 t1t2t3,在实际的使用中,我们应该让 tags 的值能够见名知义,现在每个 task 都有了标签。

执行指定标签

假如在执行上述 playbook 时,我们只想执行 task2,该怎样执行呢?我们可以使用如下命令:

$ ansible-playbook --tags=t2 test.yml

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

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

$ ansible-playbook --tags t2,t3 test.yml

不执行指定的标签

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

$ ansible-playbook --skip-tags='t2' test.yml

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

其它语法

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

---
- hosts: all
  tasks: 
  - name: task1
    file: 
      path: /testdir/t1
      state: touch
    tags:
      - t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: ['t2']

之前描述的三种语法都可以指定标签,不过上例中,每个任务只有一个标签,其实,我们可以为每个任务添加多个标签,三种语法添加多个标签的示例如下

# 语法一:
tags:
 - testtag
 - t1
 
# 语法二:
tags: tag1,t1
 
# 语法三:
tags: ['tagtest','t2']

上述示例的语法一使用了 YAML 块序列的语法格式指定多个标签,语法二与语法三都是在原来语法的基础上,使用逗号隔开多个标签。

使用相同标签

如下例所示,不同的任务可以使用相同的标签。

---
- hosts: all
  tasks:
  - name: install httpd package
    tags: httpd,package
    yum:
      name=httpd
      state=latest
 
  - name: start up httpd service
    tags: httpd,service
    service:
      name: httpd
      state: started

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

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

---
- hosts: all
  tags: httpd
  tasks:
  - name: install httpd package
    tags: ['package']
    yum:
      name=httpd
      state=latest
 
  - name: start up httpd service
    tags:
      - service
    service:
      name: httpd
      state: started

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

查看标签列表

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

$ ansible-playbook --list-tags test.yml

内置标签

其实,ansible 还内置了 5 个特殊 tag,这 5 个特殊 tag 分别为

  • always
  • never
  • tagged
  • untagged
  • all

always & never

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

---
- hosts: all
  tasks:
  - name: task1
    file:
      path: /testdir/t1
      state: touch
    tags:
      - t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: ['t2']
  - name: task3
    file: path=/testdir/t3
          state=touch
    tags: t3,always

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

$ ansible-playbook --tags=t1 test.yml

PLAY [all] ****************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************
ok: [C]
ok: [B]

TASK [task1] **************************************************************************************************************************************
changed: [B]
changed: [C]

TASK [task3] **************************************************************************************************************************************
changed: [C]
changed: [B]

PLAY RECAP ****************************************************************************************************************************************
B                          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
C                          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

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

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

$ ansible-playbook --skip-tags always test.yml

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

$ ansible-playbook --skip-tags t3 test.yml

在 2.5 版本的 ansible 中,引入了新的特殊标签 never,从字面上理解, never 的作用应该与 always 正好相反。

never 是针对 --skip-tags 选项来说的,执行 ansible 命令时如果使用 --skip-tags 指定要跳过的标签,即便没有指定 never 标记的任务,never 标记的任务也会被跳过不会被执行。

tagged & untagged & all

剩余的三个特殊标签分别为 taggeduntaggedall,这三个特殊标签并非像 alwaysnever 一样,alwaysnever 作为标签值存在,而这三个特殊标签则是在调用标签时使用,看下面示例:

$ ansible-playbook --tags tagged test.yml

上述命令表示只执行有标签的任务,没有任何标签的任务不会被执行。

$ ansible-playbook --skip-tags tagged test.yml

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

$ ansible-playbook --skip-tags untagged test.yml

上述命令表示跳过没有标签的任务。

特殊标签 all 表示所有任务会被执行,不用指定,默认情况下就是使用这个标签。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/ansible5.html

Buy me a cup of coffee ☕.