Ansible: Como executar um Host de Tarefa por Host?

14

No nível de jogo, temos serial: 1que nos permitir executar o jogo inteiro, um host de cada vez. Mas não encontrei uma maneira simples de fazer isso em uma única tarefa. Isso é especialmente relevante se a tarefa em questão não executar o bloqueio adequado (por qualquer motivo).

Uma resposta óbvia é colocar a tarefa em seu próprio jogo. Mas isso não ajuda nos papéis. (Ter que fazer serial: 1a peça usando o papel não é realmente intuitivo.)

Elrond
fonte

Respostas:

10

Se você não deseja nenhum paralelismo na execução das etapas do seu manual, defina o nível da bifurcação como 1:

ansible-playbook --forks=1 ...

Você também pode colocar isso no seu arquivo cfg ansible:

[defaults]
forks=1

mas se você desejar individualmente, use a opção de linha de comando acima.

EDITAR:

serial: 1faz algo completamente diferente: é como executar o manual de instruções para cada host, aguardando a conclusão do manual completo antes de passar para o próximo host. forks=1significa executar a primeira tarefa em uma peça em um host antes de executar a mesma tarefa no próximo host, portanto, a primeira tarefa será executada para cada host antes que a próxima tarefa seja tocada.

Então você quer forks=1apenas uma peça; infelizmente isso não é possível no momento.

Wurtel
fonte
2
Eu não estava olhando para definir isso em um manual inteiro. Isso é muito não-granular. serial: 1deixe-me colocá-lo em uma peça pelo menos. Mas eu só quero colocá-lo no subitem de uma peça (qual seja o nome correto disso. Pensei que fosse "tarefa", mas o comentário acima parece discordar).
Elrond
3
serial: 1faz algo completamente diferente: é como executar o manual de instruções para cada host, aguardando a conclusão do manual completo antes de passar para o próximo host. forks=1significa executar a primeira tarefa em uma peça em um host antes de executar a mesma tarefa no próximo host, portanto, a primeira tarefa será executada para cada host antes que a próxima tarefa seja tocada. Então você quer forks=1apenas uma peça; infelizmente isso não é possível no momento.
wurtel
Bom ponto! Você se importaria de adicionar isso à resposta?
Elrond #
1

Se você estiver executando em uma única máquina, surgirão problemas de bloqueios exclusivos para mais de um host. Portanto, você deve executar um por um para todos os hosts --forks=1. Por exemplo: ansible-playbook webserver.yml --forks=1onde webserver.yml possui app01 e app02 dentro do seu[webserver]

Rohan Seth
fonte
1

Há uma solução alternativa para esse problema - é possível passar a lista de hosts (ou um grupo) para with_itemse usá-la delegate_tocom esta lista. Dessa forma, a tarefa será executada host por host.

Por exemplo:

- name: start and enable rabbitmq (run task host by host)
  service:
    name: "rabbitmq-server"
    state: "started"
    enabled: true
  delegate_to: "{{ item }}"
  with_items: "{{ groups['rabbitmq-cluster'] }}"
  run_once: true
Tomasz Klosinski
fonte
Para aqueles que se perguntam por que run_once: trueestá lá, tente retirá-lo. Você não vai gostar do que acontece. (tantos repetidas corre AAAAHHHH)
Almenon
0

Pense o que você quer é

run_once: true

user19151
fonte
4
não: "run_once: true" significa executar a tarefa para exatamente um host na lista de hosts. Quero executá-lo para cada host da lista, mas um após o outro.
Elrond
0

Para comandos que podem ser executados localmente, use um loop para iterar sobre todos os hosts na peça. Isso funciona apenas se o comando puder ser executado localmente. Você também pode executar um comando com o ssh nas máquinas remotas, uma a uma, dessa maneira, se as chaves estiverem configuradas, mas isso se torna difícil quando se trata de escalação.

POR EXEMPLO:

- name: Init New Appliances - Remove the known hosts entry for the server in case it has changed
  run_once: yes
  connection: local
  become: no
  command: "ssh-keygen -R {{ item }}"
  with_items:
  - "{{ inventory_hostname }}"
Michele
fonte
1
Você deve fornecer uma lista de hosts em vez de apenas no host nomeado inventory_hostname, caso contrário, o loop não faz sentido.
Konstantin Suvorov