这是一个多余的标签吗?



虽然许多人可能喜欢ansible,但在我看来,它似乎与它相当混为一谈和有些多余的概念,如tagsrolesinventory/hosts fileshostgroupsplaybookstasks"when" conditionals确定最终将执行的内容存在相当大的挑战。这个问题的核心问题是tags.

我的理解是,如果我有一个剧本,其中有一个包含标签列表的角色,这些标签将由所有包含的任务添加(继承)

例:

[----./playbook.yml----]
---
- hosts: all
roles: 
- {role: role01, tags: ['tag01', 'tag02']} 
- {role: role02, tags: ['tag01', 'tag03']}

意味着在./roles/role01/tasks/main.yml中找到的所有任务都将隐式标记为tag01tag02。确认这将是这个问题的答案的一部分

同样,./roles/role02/tasks/main.yml中的所有任务都被标记为tag01tag03,对吧?

现在这里的问题是,查看文件./roles/role01/tasks/main.yml我看到此内容

[----./roles/role01/tasks/main.yml----]
---
- block:
- name: "upgrade all packages"
yum:
name: '*'
state: latest
tags:
- tag01

考虑到该角色仅从上面显示的./playbook.yml行中引用,我看不出拥有tag01有什么意义,因为它应该在给定的行中隐式标记:

- {role: role01, tags: ['tag01', 'tag02']}

另外,我完全感到不安的是,另一个block概念,必须在这里使用?

问题的各个方面:

  1. 角色main.yml中标记是多余的吗?
  2. 为什么要使用块(考虑到无论如何只有一个任务)?

TL;博士:是的,在问题中解释的情况下(在 ansible 角色级别隐式标记,使得角色内部单个任务/块的标记变得不必要,因此是多余的)。

更长的信息:

可悲的是,Ansible经常招致过于复杂和扭曲的语法和风格。在这种情况下,它只是一个不必要的重复标记,再加上同样没有必要使用block的语法元素(在 ansible playbook 中)。

ansible 在标记方面的行为是如何验证/测试的? => 带有 shell/bash sctipt:

我已经求助于这个 shell 脚本,它应该测试tags在角色的隐式继承中的行为方式。

bash脚本将创建一个最小的ansible测试用例,它 包含两个角色role1role2,都是逐字副本 除了名字(所以能够告诉他们公寓)和 有 2 个任务:

  • task(A)显式标记
  • task(B)明确标记为"tag01"。

必要的 ansibleplaybook.yml和主机/清单文件inventory.ini也是 在脚本中创建:

#!/bin/bash
#make a temporary directory for test
TEMPDIR="$(mktemp -d)"
#change to temporary directory
cd "$TEMPDIR"
# create ansible hosts file "./inventory.ini" 
# only host we need is the the local box (to be simple disregard any ssh overhead)
cat > inventory.ini <<'EOF'
[hosts]
localhost ansible_connection=local
EOF
# create ansilble role "role1"
# (to keep it simple, we have minimal role with only a tasks entry)
mkdir -p roles/role1/tasks
# (the content for the tasks/main.yml file are two tasks, with one task
#  namely task(A) not being explicitly and the task(B) being explicitly
#  tagged)
cat > roles/role1/tasks/main.yml <<'EOF'
---
# tasks file for role1 and role2
- name: "task(A) tagged not explicitly 'tag01'"
debug:
msg: "debug-msg: this is "task(A) tag explicitly 'tag01'" {{ role_name }} ."
- name: "task(B) tagged explicitly 'tag01'"
debug:
msg: "debug-msg: this is "task(B) tagged explicitly 'tag01'" {{ role_name }} ."
tags:
- tag01
EOF

# create ansible role "role2" as a verbatim copy of "role1"
cp -r roles/role1 roles/role2
# now create an ansible playbook that uses these two ansible roles 
# (note that for the role "role1" we used "implicit tagging"
cat > playbook.yml <<'EOF'
---
- hosts: all
roles:
- role: "role1"
tags: 
- "tag01"
- role: "role2"
EOF
# show the test setup 
find . 
# TEST 1:
# run "playbook.yml" one time "as is" ( i.e. no using of tags -> "all tasks"
# should be run)
echo "TEST1" | tee TEST1
ansible-playbook -i inventory.ini playbook.yml | tee -a TEST1
# TEST 2:
# run "playbook.yml" with --tags command line options ( meaning this time
# we limit the task to be run to only those that have the specific tag)
echo "TEST2" | tee TEST2
ansible-playbook -i inventory.ini --tags 'tag01' playbook.yml | tee -a TEST2
# TEST 3:
# run "playbook.yml" with --skip-tags command line options ( meaning this time
# we limit the task to be run all, but those to tags to be "skipped")
echo "TEST3" | tee TEST3
ansible-playbook -i inventory.ini --skip-tags 'tag01' playbook.yml | tee -a TEST3
# show path of temporary directory 
echo "TEMPDIR is $TEMPDIR"

运行此 shell 脚本后,它基本上会产生三个结果

  1. 测试 1 "TEST1",ansible-playbook -i inventory.ini playbook.yml:无标记用法 => 任何隐式或显式标记都不起作用 运行两个角色的所有任务role1role2
测试1 播放 [全部] ****** 任务 [收集事实] ****** 确定:[本地主机] 任务 [角色 1 : 任务 (A) 未明确标记为"tag01"] ****** 确定: [本地主机] => { "msg": "debug-msg: 这是任务 (A) 标记显式 'tag01'\" role1 ." } 任务 [角色 1:任务 (B) 显式标记为"tag01"] ****** 确定: [本地主机] => { "msg": "debug-msg: 这是 \"任务 (B) 显式标记为 'tag01'\" role1 ." } 任务 [角色 2 : 任务 (A) 未明确标记为"tag01"] ****** 确定: [本地主机] => { "msg": "debug-msg: 这是 \"task(A) 标记显式 'tag01'\" role2 ." } 任务 [角色 2 : 任务 (B) 显式标记为 'tag01'] ****** 确定: [本地主机] => { "msg": "debug-msg: 这是 \"任务 (B) 显式标记为 'tag01'\" role2 ." } 播放回顾 ****** 本地主机:确定=5 已更改=0 无法访问=0 失败=0
  1. 测试 2 "TEST2",ansible-playbook -i inventory.ini --tags 'tag01' playbook.yml:使用标签 =>隐式和显式标记很重要。因为tag01设置为在role运行包含的任务任务 (A) 和task(B)的级别进行role1。相比之下,对于没有隐式继承标记的role2,仅运行task(B)。输出显示:
测试2 播放 [全部] ****** 任务 [收集事实] ****** 确定:[本地主机] 任务 [角色 1 : 任务 (A) 未明确标记为"tag01"] ****** 确定: [本地主机] => {"msg": "debug-msg: 这是任务 (A) 标记显式 'tag01'\" role1 ." } 任务 [角色 1:任务 (B) 显式标记为"tag01"] ****** 确定: [本地主机] => { "msg": "debug-msg: 这是 \"任务 (B) 显式标记为 'tag01'\" role1 ." } 任务 [角色 2 : 任务 (B) 显式标记为 'tag01'] ****** 确定: [本地主机] => { "msg": "debug-msg: 这是 \"任务 (B) 显式标记为 'tag01'\" role2 ." } 播放回顾 ****** 本地主机 : 确定=4 已更改=0 无法访问=0 失败=0
  1. 最后,测试 3 "TEST3" 反转所有内容--skip-tags其中隐式标记role1导致跳过整个角色。对于ansible-playbook -i inventory.ini --skip-tags 'tag01' playbook.yml,我们得到以下结果:
测试3 播放 [全部] ****** 任务 [收集事实] ****** 确定:[本地主机] 任务 [角色 2 : 任务 (A) 未明确标记为"tag01"] ****** 确定: [本地主机] => { "msg": "debug-msg: 这是 \"task(A) 标记显式 'tag01'\" role2 ." } 播放回顾 ****** 本地主机 : 确定=2 已更改=0 无法访问=0 失败=0 总之

,为了接近问题的主题,角色中包含的任务的 a 标签是多余的,如果该role是 (a) 已经在playbook中标记了自己,因此使其所有任务隐式继承任务,并且 b) 这是使用该角色的唯一playbook(情况确实如此)这里)。

虽然输出可以通过执行此处提供的 shell 脚本来生成,但出于礼貌和完整,它的输出是:

.
./playbook.yml
./roles
./roles/role2
./roles/role2/tasks
./roles/role2/tasks/main.yml
./roles/role1
./roles/role1/tasks
./roles/role1/tasks/main.yml
./inventory.ini
TEST1
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role1 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(A) tag explicitly 'tag01'" role1 ."
}
TASK [role1 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(B) tagged explicitly 'tag01'" role1 ."
}
TASK [role2 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(A) tag explicitly 'tag01'" role2 ."
}
TASK [role2 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(B) tagged explicitly 'tag01'" role2 ."
}
PLAY RECAP **************************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0   
TEST2
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role1 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(A) tag explicitly 'tag01'" role1 ."
}
TASK [role1 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(B) tagged explicitly 'tag01'" role1 ."
}
TASK [role2 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(B) tagged explicitly 'tag01'" role2 ."
}
PLAY RECAP **************************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0   
TEST3
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role2 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is "task(A) tag explicitly 'tag01'" role2 ."
}
PLAY RECAP **************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   
TEMPDIR is /tmp/tmp.cPE6a4gGiG

最新更新