Sou novo no ansible e estou tentando automatizar algumas etapas.
Esta tarefa é executada bem na primeira vez.
# Copy Root ssh keys within all devices
- hosts: etall
tasks:
- name: ssh keygen
command: ssh-keygen -t rsa -f /root/.ssh/id_rsa -q -P ""
Na segunda vez, ele simplesmente trava depois de reunir os fatos. A configuração ANSIBLE_DEBUG=1
mostra a etapa suspensa em:
16584 1554867575.39541: _low_level_execute_command(): executing: /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1554867574.524454-229535370546451/AnsiballZ_command.py && sleep 0'
Durante o rastreamento na máquina cliente:
/usr/bin/python -m trace --trace /root/.ansible/tmp/ansible-tmp-1554873279.0459487-106888464136363/AnsiballZ_command.py
<---output snippet---->
AnsiballZ_command.py(16): import base64
--- modulename: trace, funcname: _unsettrace
trace.py(80): sys.settrace(None)
Traceback (most recent call last):
File "/usr/lib64/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/usr/lib64/python2.7/trace.py", line 819, in <module>
main()
File "/usr/lib64/python2.7/trace.py", line 807, in main
t.runctx(code, globs, globs)
File "/usr/lib64/python2.7/trace.py", line 513, in runctx
exec cmd in globals, locals
File "/root/.ansible/tmp/ansible-tmp-1554873279.0459487-106888464136363/AnsiballZ_command.py", line 113, in <module>
_ansiballz_main()
File "/root/.ansible/tmp/ansible-tmp-1554873279.0459487-106888464136363/AnsiballZ_command.py", line 16, in _ansiballz_main
import base64
ImportError: No module named base64
eu posso import base64
depois/usr/bin/python
Isso não foi um problema durante a primeira execução. Também funciona após a reinstalação do sistema operacional na máquina cliente.
Versão:
ansible 2.7.6
config file = /user/user1/plays/ansible.cfg
configured module search path = ['/user/user1/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /user/user1/p363/lib/python3.6/site-packages/ansible-2.7.6-py3.6.egg/ansible
executable location = /user/user1/p363/bin/ansible
python version = 3.6.3 (default, Jul 8 2018, 21:13:48) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
A versão do Python na máquina cliente é 2.7.5
CONFIGURAÇÃOansible-config dump --only-changed
DEFAULT_FORKS(/user/user1/plays/ansible.cfg) = 1
DEFAULT_HOST_LIST(/user/user1/plays/ansible.cfg) = ['/user/user1/plays/hosts.ini']
DEFAULT_LOG_PATH(/user/user1/plays/ansible.cfg) = /user/user1/plays/ansible.log
DEFAULT_ROLES_PATH(/user/user1/plays/ansible.cfg) = ['/user/user1/plays/hosts']
RETRY_FILES_ENABLED(/user/user1/plays/ansible.cfg) = False
AMBIENTE: mestre ansible
$ cat /etc/os-release
NAME="Red Hat Enterprise Linux Workstation"
VERSION="7.5 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VARIANT="Workstation"
VARIANT_ID="workstation"
VERSION_ID="7.5"
PRETTY_NAME="Red Hat Enterprise Linux"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.5:GA:workstation"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.5
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.5"
cliente ansible
# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
livro de cantadas:
# Copy Root ssh keys within all machines
- hosts: etall
tasks:
- name: ssh keygen
command: ssh-keygen -t rsa -f /root/.ssh/id_rsa -q -P ""
- name: Fetch keyfile
fetch:
src: "~/.ssh/id_rsa.pub"
dest: "buffer/{{ ansible_hostname }}-id_rsa.pub"
flat: yes
- name: Copy keyfile to destination
authorized_key:
user: root
state: present
key: "{{ lookup('file','buffer/{{ item }}-id_rsa.pub') }}"
when: item != ansible_hostname
with_items:
- "{{ groups['etall'] }}"
- name: ssh keyscan
shell: ssh-keyscan {{ item }} >> /root/.ssh/known_hosts
when: item != ansible_hostname
with_items:
- "{{ groups['etall'] }}"
Trecho de saída detalhada logo após a coleta de fatos:
TASK [ssh keygen] *************************************************************************************************************************************************************************************************
task path: /user/user1/plays/auth_keys.yml:4
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 linux-user5 '/bin/sh -c '"'"'echo ~root && sleep 0'"'"''
<linux-user5> (0, b'/root\n', b'')
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 linux-user5 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890 `" && echo ansible-tmp-1554878730.6050982-46540706020890="` echo /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890 `" ) && sleep 0'"'"''
<linux-user5> (0, b'ansible-tmp-1554878730.6050982-46540706020890=/root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890\n', b'')
Using module file /user/user1/p363/lib/python3.6/site-packages/ansible-2.7.6-py3.6.egg/ansible/modules/commands/command.py
<linux-user5> PUT /user/user1/.ansible/tmp/ansible-local-312468ua784d6/tmp9l2vw34v TO /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py
<linux-user5> SSH: EXEC sshpass -d11 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 '[linux-user5]'
<linux-user5> (0, b'sftp> put /user/user1/.ansible/tmp/ansible-local-312468ua784d6/tmp9l2vw34v /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py\n', b'')
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 linux-user5 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/ /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py && sleep 0'"'"''
<linux-user5> (0, b'', b'')
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 -tt linux-user5 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py && sleep 0'"'"''
Trava após a coleta de fatos.
Isso foi concluído bem durante a primeira execução. Também funcionou após a reinstalação do sistema operacional na máquina cliente.
Você tentou executar seu
ssh-keygen
comando duas vezes manualmente?Primeira corrida:
Segunda corrida:
Seu comando está simplesmente esperando para sempre uma resposta que nunca virá.
Solução 1: responda à(s) pergunta(s)
Você pode usar o
expect
módulo para responder aos prompts interativos se os conhecer com antecedênciaEmbora isso funcione em todas as execuções, é uma solução ruim, pois não é idempotente : haverá uma alteração em seu servidor toda vez que você executar seu playbook, embora nenhuma alteração tenha sido feita em seu inventário ou variáveis
Solução 2: gere apenas quando necessário.
Uma abordagem melhor seria criar a chave somente se ela não existir ou se precisar ser atualizada. Existem várias formas de o fazer e depende muito das suas necessidades, dos seus desejos, do tamanho do seu parque de servidores...
Com um parque relativamente pequeno, você poderia gerar as chaves localmente e armazená-las em seu inventário (usando o ansible-vault para ofuscar as chaves privadas). Você simplesmente precisa copiar os arquivos para os servidores. Nenhuma alteração será feita se o arquivo já existir e tiver o mesmo conteúdo.
Se o parque for maior, as chaves podem ser armazenadas no Hashicorp Vault, Cyberark...
Se você ainda deseja criar as chaves em cada servidor, aqui está minha opinião para fazê-lo idem-potencialmente:
Agora, se você executar seu playbook normalmente, as chaves serão criadas apenas se ainda não existirem. Se você quiser atualizar as chaves em servidores que já possuem uma, você pode passar um var extra para o playbook