Resolvido: Execute a tarefa somente quando uma tag for especificada


75

Tags possíveis podem ser usadas para executar apenas um subconjunto de tarefas / funções. Isso significa que, por padrão, todas as tarefas são executadas e só podemos impedir a execução de algumas tarefas.

Podemos limitar uma tarefa a ser executada apenas quando a tag "foo" for especificada? Podemos usar tags atuais na whenseção de uma tarefa?


2
parece que você precisa de alguma configuração de tarefa como limit_to_tags: foo que não existe e eu não acho que isso seja possível no momento. Uma implementação futura também precisa ter um plano para AND ou OR essas tags juntas.
— dgh

Dê uma olhada na minha resposta em "Ansible - Tags padrão / explícitas" stackoverflow.com/questions/28789912/…
— sirkubax 9/15/15

Respostas:


38

O Ansible 2.5 vem com tags especiais nevere always. A tag neverpode ser usada exatamente para esse fim. Por exemplo:

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]

Neste exemplo, a tarefa será executada apenas quando a tag debug(ou never) for solicitada explicitamente. [Referência em documentos ansible]


20

Embora seja uma solução indireta, ela funciona.

Dentro da lista de tarefas, registre uma variável quando a execução normal for executada. Em seguida, adicione uma condição when que verifique essa variável na tarefa marcada.

- shell: /bin/true
  register: normal_task_list

- name: Only run when tag is specified
  shell: /bin/echo "Only running because of specified tag"
  when: normal_task_list is not defined
  tags: specified

Você também pode usar untaggedpara fazer isso:- set_fact: untagged_run=true tags: untagged
— Pyzo 28/11

Você pode explicar um pouco mais sobre isso? Um exemplo do mundo real?
— Quintin Par

17

Não tenho reputação suficiente para votar ou comentar a resposta que sugere o uso de variáveis ​​de linha de comando ( --extra-vars), mas tenho isso a acrescentar:

A ressalva deste método é que a jogada irá errar e falhar se você não definir essa variável extra.

Você pode impedir a falha na reprodução na ausência de uma --extra-varsdefinição, definindo um valor padrão no próprio manual:

---
- hosts: ...
# ↓↓↓
  vars:
    thorough: false
# ↑↑↑
  tasks:
  - name: apt - install nfs-common only when thorough is true
    when: thorough | bool
    apt:
      cache_valid_time: 86400
      force: yes
      pkg:
        - nfs-common

A substituição via --extra-varsainda funcionará porque as variáveis ​​definidas na linha de comando têm precedência sobre todas as outras definições.

O resultado é que a reprodução é executada sem erro quando thoroughnão é alterada para truena linha de comando.


5
O mesmo pode ser alcançado usando thorough | default('no') | bool.
— Costi Ciudatu 10/10

2
Ou when: thorough is defined and thoroughse você preferir que a sintaxe
— KCD

Obrigado, ame mais a is defined andsintaxe. mais do que os múltiplos canos que não considero intuitivos.
— Elias Lynn

10

Você pode usar Condicionais para se proteger contra tarefas em execução acidental que, caso contrário, seriam executadas se você não especificar uma tag. A ressalva deste método é que a jogada irá falhar e falhar se você não definir essa variável extra.

Usando o argumento extra-vars, você pode ativar sua condicional para ser executada.

Do ansible-playbook --help:

 -e EXTRA_VARS, --extra-vars=EXTRA_VARS
    set additional variables as key=value or YAML/JSON

Exemplo:

ansible-playbook test.yaml -e "thorough=true"

test.yaml:

...
- name: apt - install nfs-common only when thorough is true
  apt:
    cache_valid_time: 86400
    force: yes
    pkg:
    - nfs-common
  when: thorough | default(False)
...

2
Para evitar um erro, se você não definir "completo", basta usar thorough | default("false") | match("true"). O padrão não precisa ser false, apenas algo que não corresponda true, mas melhora a legibilidade.
— Tom Wilson

4

Verificar a variável 'tags' não está funcionando no Ansible 2.1.1.0. Veja abaixo o teste. Eu tenho uma outra idéia para executar tarefas apenas quando uma tag é definida, trabalhando para o Ansible 1.9.X e 2.XY:

- set_fact: foo=true
  tags: bar
- set_fact: foo=false
- name: do something when 'bar' tag is defined
  debug: var=foo
  when: foo
  tags: bar

Com isso, ao executar o playbook sem nenhuma tag, a variável 'foo' será configurada como true e depois false, para que nada seja executado. Se você adicionar a tag 'bar', somente a primeira configuração será aplicada; portanto, a variável 'foo' será verdadeira; sua tarefa será executada. Desfrutar!


E aqui está o teste sobre a variável 'tags' no Ansible 2.1.1.0:

Aqui está o manual:

- hosts: localhost
  connection: local
  tasks:
    - name: display tags variable
      debug: var=tags
      tags: foo

    - name: do something only when tag 'foo' is provided
      debug: var=tag
      when: tags is defined
      tags: foo

E aqui está a saída:

$ ansible-playbook --version ; ansible-playbook ./test.yml -t foo
ansible-playbook 2.1.1.0
  config file = /home/nootal/projects/ivy/src/ansible/ansible.cfg
  configured module search path = Default w/o overrides

PLAY [localhost] ***************************************************************

TASK [display tags variable] ***************************************************
ok: [localhost] => {
    "tags": "VARIABLE IS NOT DEFINED!"
}

TASK [do something only when tag 'foo' is provided] ****************************

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

2

Sim. A execução do ansible-playbook com o --tags foosinalizador garantirá que apenas as tarefas marcadas foosejam executadas. Por exemplo, suponha que tenhamos um manual chamado example.yml:

tasks:

  - yum: name={{ item }} state=installed
    with_items:
       - httpd
       - memcached
    tags:
       - packages

  - name: some other task
    ..
    tags:
      - some other tag

corrida:

ansible-playbook example.yml --tags "packages"

Garantirá que apenas a tarefa yum seja executada.

Então, na verdade, você não precisa usar tags na seção when para executar condicionalmente uma tarefa. Observe que, dependendo da complexidade de seus playbooks / funções, pode ser necessário usar uma combinação de --tags e --skip-tags para controlar quais tarefas são executadas. Por exemplo, se uma tarefa de inclusão estiver marcada como 'foo' e alguma tarefa dentro do manual incluído estiver marcada como 'barra' e você executar

ansible-playbook --tags "foo"

A tarefa interna (marcada apenas como 'barra') será executada. Para evitar a execução de todas as tarefas internas marcadas como 'bar', você deverá executar o seguinte comando

ansible-playbook --tags foo --skip-tags bar

7
Isso não é verdade: "A especificação de uma marca em uma tarefa significa que somente quando ela for passada explicitamente para o comando ansible-playbook, essa tarefa será executada."
— gimboland

1
Destacada, a afirmação não é verdadeira.
— Chris

10
Sim, você pode obter o comportamento garantindo sempre o uso das ansible-playbookopções corretas , mas acho que o OP está pedindo uma maneira de anotar uma tarefa para que não seja executada, a menos que uma tag específica seja explicitamente adicionada ao ansible-playbookcomando.
— dgh

4
Sim, isso não está respondendo à pergunta do OP.
— Allen Luce

todas as ações marcadas / não marcadas são executadas quando você não especifica uma tag. Tags não podem excluir uma ação a ser executada, apenas incluir. Não há lógica de predicado, exceto para um filtro aditivo.
— bbaassssiiee 22/09


0

A cláusula when não pode avaliar a presença de tags. Como solução alternativa, uso variáveis ​​e tags juntas para executar tarefas específicas a essa tag / variável.

Ex: imagine um manual e um inventário

# inventário
[dev]
192.168.1.1

# site.yml
- hosts: dev
  funções:
    - {role: common}

e em comum / tasks / main.yml

# papéis / comum / tarefas / main.yaml
- nome: instalar links
  apt: nome = estado dos links = presente

- inclua: uninstall.yml
  quando: uninstall_links estiver definido
  Tag:
    - Desinstalar

# role / common / tasks / uninstall.yml
- nome: Desinstalar links
  apt: nome = estado dos links = ausente

Com essa abordagem, você usa a tag para selecionar apenas as tarefas em uninstall.yml, mas também precisa definir a variável 'uninstall_links' para algo que a habilite. Portanto, se você executar o manual sem nenhum parâmetro, ele executará, por padrão, a tarefa de instalação. Para desinstalar, você pode definir a tag 'uninstall' como seu playbook (ou cmdline) e DEVE definir a variável. Se você não definir a tag, ela executará tudo (instalar e desinstalar) nessa ordem, o que é bom para testar todo o processo.

Como executar tudo (ele será instalado e desinstalado):

$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true"

Como executar apenas a tag 'uninstall' no grupo dev

$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true" -t uninstall

Portanto, variáveis ​​e tags também podem estar nos arquivos site.yml / inventário, permitindo que você se comprometa com seu SCM e registre sua intenção.


0

nootal está certo, minha abordagem não funciona - ignore-a :( Agora eu uso "when: myvar is defined" e a linha de comando "-e" myvar = X "para executar tarefas apenas quando solicitadas explicitamente.

Ainda mais fácil (pelo menos com o ansible 2.1.1.0):

- name: do something only when tag 'foo' is provided
  when: tags is defined
  tags: foo

-> só será executado quando as tags forem fornecidas E as tags incluem "foo"


0

Em Ansible 2.3.2.0, aqui está minha solução para o problema:

---
- hosts: localhost
  gather_facts: no
  vars:
    in_tag: yes
  tasks:
    - set_fact: in_tag=no
    - fail:
        msg: "recently_added is set and you're using blah tag"
      when: ( in_tag | bool )
      tags:
        - blah
    - debug:
        msg: "always remember"

Ele começa definindo in_tagpara True, em seguida, há uma set_factque define-lo de volta para Falsequando você não especificar qualquer tagsde ansible-playbook.

Quando você especifica tags, in_tagpermanece em Truee a failtarefa é executada.

PS: você pode adicionar a lógica a qualquer tarefa que desejar

PS2: você também pode estender a lógica e codificar todas as tags que você possui e set_fact: in_tag_blah=Trueem combinação com, é tags: ["blah"]claro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.