Это лишний тег ansible?

В то время как многим может понравиться ansible, мне кажется, что с ним довольно смешанные и несколько избыточные понятия, такие как tags, roles, inventory/hosts files, hostgroups, playbooks, tasks "when" conditionals, довольно сложно определить, что в конечном итоге будет выполнено. Суть этого вопроса заключается в tags.

Насколько я понимаю, если у меня есть playbook, в котором есть роль, содержащая список тегов, они добавляются (наследуются) всеми содержащимися задачами.

Пример:

[----./playbook.yml----]

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

означало бы, что все задачи, найденные в ./roles/role01/tasks/main.yml, будут неявно помечены тегами tag01 и tag02. Подтверждение этого было бы частью ответа на этот вопрос

Таким образом, все задачи в ./roles/role02/tasks/main.yml помечены tag01 и tag03, верно?

Теперь проблема в том, что, глядя на файл ./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']}

Также меня совершенно беспокоит, что здесь нужно было использовать другую концепцию ansible block?

Аспекты вопроса:

  1. Отметка в роли main.yml была лишней?
  2. Зачем использовать блок (учитывая, что задача все равно одна)?

person fraleone    schedule 10.02.2020    source источник


Ответы (1)


TL;Dr: да, действительно, в случае, объясненном в вопросе (неявная маркировка на уровне роли ansible делает маркировку отдельной задачи/блока внутри роли ненужной< /em> и, следовательно, лишнее).

Более длинная информация:

Ansible, к сожалению, часто предлагает чрезмерно сложный и искаженный синтаксис и стиль. В данном случае это была всего лишь ненужная двойная маркировка в сочетании с столь же ненужным использованием синтаксического элемента block (в ansible playbook).

Как было проверено/проверено поведение ansible в отношении тегов? => со сценарием оболочки/bash:

Я прибегнул к этому сценарию оболочки, который должен проверить, как ansible tags ведет себя по отношению к этому неявному наследованию относительно ролей.

сценарий bash создаст минимальный доступный тестовый пример, который содержит две роли role1 и role2, обе являются дословными копиями, за исключением имени (чтобы можно было их отличить) и с двумя задачами:

  • task(A) не явно помечен
  • task(B) явно помечен тегом 'tag01'.

Также в скрипте создается необходимый ansible playbook.yml и файл host/inventory 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"

Запустив этот сценарий оболочки, он в основном дает три результата для

  1. Тест 1 "TEST1", ansible-playbook -i inventory.ini playbook.yml: теги не используются => любое явное или неявное тегирование не имеет значения. Все задачи для обеих ролей role1 и role2 выполняются:
    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   
   
  1. Тест 2 "TEST2", ansible-playbook -i inventory.ini --tags 'tag01' playbook.yml: используются теги => неявные и явные теги имеют значение. Поскольку tag01 установлено для role1 на уровне role, выполняются обе содержащиеся задачи task(A) и task(B). Напротив, для role2 без неявно наследуемой маркировки выполняется только task(B). Вывод показывает, что:
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   
    
  1. Наконец, тест 3 «TEST3» инвертирует все с --skip-tags, где неявная маркировка для role1 приводит к тому, что вся роль пропускается. Для ansible-playbook -i inventory.ini --skip-tags 'tag01' playbook.yml имеем следующий результат:

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   
    

В заключение и в продолжение темы вопроса, тег a для задачи, содержащейся в роли, является излишним, если этот самый role (а) уже помечен в playbook и, следовательно, заставляет все свои задачи неявно наследовать задача и б) это единственная playbook роль, которая все равно используется (как это было здесь).

Несмотря на то, что вывод может быть сгенерирован путем выполнения сценария оболочки, предоставленный здесь его вывод в качестве любезности и для полноты:

.
./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
person fraleone    schedule 10.02.2020