Comment gérer les changements de port SSH avec Ansible?
27
J'essaie d'utiliser Ansible pour automatiser le processus d'installation de nouvelles instances de serveur. L'une des tâches de configuration modifie le port SSH par défaut, m'obligeant donc à mettre à jour la liste des hôtes.
Est-il possible d'automatiser cela en ayant une solution de repli Ansible sur un port spécifié si la connexion n'a pas pu être établie avec le port SSH par défaut?
Vous pouvez essayer une action locale sur les hôtes pour voir si vous pouvez vous connecter aux ports respectifs et enregistrer celui qui réussit et définir cela comme un fait. Vous souhaitez désactiver la collecte des faits, sinon le module d'installation échouera lorsqu'il tentera de se connecter avec les hôtes qui ont déjà été reconfigurés. Une fois que vous avez terminé ce jeu, ajoutez-en d'autres ci-dessous avec recueillir_facts et tout le reste.
- name: determine ssh port
hosts: all
gather_facts: false
vars:
custom_ssh_port: 222
tasks:
- name: test default ssh port
local_action: wait_for port=22 timeout=5 host={{inventory_hostname}}
register: default_ssh
ignore_errors: true
- name: set ansible_ssh_port to default
set_fact: ansible_ssh_port=22
when: default_ssh.elapsed < 5
- name: test ssh on high port
local_action: wait_for port={{custom_ssh_port}} timeout=5 host={{inventory_hostname}}
register: high_ssh
when: default_ssh.elapsed >= 5
ignore_errors: true
- name: set ansible_ssh_port high
set_fact: ansible_ssh_port={{custom_ssh_port}}
when: default_ssh.elapsed >= 5 and high_ssh.elapsed < 5
On m'a fait remarquer que cela ferait sauter le temps pour les playbooks où vous l'utilisez. Vous pouvez également définir ansible_ssh_port dans la section vars des lectures qui ne doivent être exécutées que sur des hôtes avec un port ssh reconfiguré. par exemple
Votre stratégie de test de port conjointement avec la définition de faits semble être une approche idéale pour ces cas. Merci!!!
Jay Taylor
10
@RichardSalts merci de m'avoir aidé à démarrer. J'ai utilisé nc pour vérifier les ports qui devraient être beaucoup plus rapides. Voici mon bootstrap.xml:
Testé avec ansible 1.5 (devel 3b8fd62ff9) dernière mise à jour le 2014/01/28 20:26:03
---
# Be sure to set the following variables for all hosts:
# vars:
# oldsshport: 22
# sshport: 555
# Might fail without setting remote_tmp = /tmp/ansible/$USER in your ansible.cfg. Also fix for directly below.
# Once host is setup most of the checks are skipped and works very quickly.
# Also, be sure to set non-standard shells in a different playbook later. Stick with /bin/bash until you can run apt install.
# Assumes root user has sshkey setup already. Not sure how to utilize the --ask-pass option. For now, use ssh-copy-id prior to running playbook on new host for root user (if needed).
# Test new ssh port
- name: ssh test nc {{ sshport }}
local_action: shell nc -z -w5 {{ inventory_hostname }} {{ sshport }}
register: nc_ssh_port
failed_when: nc_ssh_port.stdout.find('failed') != -1
changed_when: nc_ssh_port.stdout == ""
ignore_errors: yes
# Set port to new port if connection success
- name: set ansible_ssh_port
set_fact: ansible_ssh_port={{ sshport }}
when: nc_ssh_port|success
# Fail back to old port if new ssh port fails
- name: ssh test nc port {{ oldsshport }}
local_action: shell nc -z -w5 {{ inventory_hostname }} {{ oldsshport }}
register: nc_ssh_default
changed_when: nc_ssh_default.stdout == ""
ignore_errors: yes
when: nc_ssh_port|changed
# Set ansible to old port since new failed
- name: set ansible_ssh_port to {{ oldsshport }}
set_fact: ansible_ssh_port={{ oldsshport }}
when: nc_ssh_default|success and nc_ssh_port|changed
# Check if root user can ssh
- name: find user
local_action: shell ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 -p {{ ansible_ssh_port }} root@{{ inventory_hostname }} exit
register: ssh_as_root
failed_when: ssh_as_root.stdout.find('failed') != -1
changed_when: ssh_as_root.stderr.find('Permission denied') == -1
# If root user success, set this up to change later
- name: first user
set_fact: first_user={{ ansible_ssh_user }}
when: ssh_as_root|changed
# Set ssh user to root
- name: root user
set_fact: ansible_ssh_user=root
when: ssh_as_root|changed
# ANSIBLE FIX: /tmp/ansible isn't world-writable for setting remote_tmp = /tmp/ansible/$USER in ansible.cfg
- name: /tmp/ansible/ directory exists with 0777 permission
file: path=/tmp/ansible/ owner=root group=root mode=0777 recurse=no state=directory
changed_when: False
sudo: yes
# Setup user accounts
- include: users.yml
# Set ssh user back to default user (that was setup in users.yml)
- name: ansible_ssh_user back to default
set_fact: ansible_ssh_user={{ first_user }}
when: ssh_as_root|changed
# Reconfigure ssh with new port (also disables non-ssh key logins and disable root logins)
- name: sshd.conf
template: src=sshd_config.j2 dest=/etc/ssh/sshd_config owner=root group=root mode=0644
register: sshd_config
sudo: yes
# Force changes immediately to ssh
- name: restart ssh
service: name=ssh state=restarted
when: sshd_config|changed
sudo: yes
# Use updated ssh port
- name: set ansible_ssh_port
set_fact: ansible_ssh_port={{ sshport }}
when: nc_ssh_port|changed
Puisque vous déployez probablement votre configuration ssh tôt, vous devriez vraiment garder cela simple. Il vous suffit de configurer votre inventaire avec la cible ansible_ssh_portet de l'utiliser -elors du premier déploiement de votre configuration ssh:
Est-il possible d'automatiser cela en ayant une solution de repli Ansible sur un port spécifié si la connexion n'a pas pu être établie avec le port SSH par défaut?
J'avais également besoin de fonctionnalités similaires, j'ai donc bifurqué et patché le plugin Ansible ssh en espérant qu'Ansible Inc. l'adopterait; ils ne l'ont pas fait. Il teste les spécifications de port ssh non std pour voir si elles sont ouvertes et revient au port ssh par défaut sinon. Il s'agit d'un très petit patch, disponible sur https://github.com/crlb/ansible .
Si vous avez une liste de ports et que vous souhaitez tous les vérifier et en utiliser un qui fonctionne, vous pouvez l'utiliser dans votre playbook:
- name: just test
hosts: server
gather_facts: false
vars:
list_of_ssh_ports: [22, 222, 234]
tasks:
- name: test ssh on port
sudo: no
local_action: wait_for port={{item}} timeout=5 host={{inventory_hostname}}
register: ssh_checks
with_items: "{{list_of_ssh_ports}}"
ignore_errors: true
- debug: msg = "{{item}}"
with_items: "{{ssh_checks.results}}"
- name: set available ansible_ssh_port
sudo: no
set_fact: ansible_ssh_port={{item.item}}
when: ssh_checks is defined and {{item.elapsed}} < 5
with_items: "{{ssh_checks.results}}"
Je suis venu avec une liste de tâches idempotente robuste à mettre dans un rôle pour changer le port SSH et gérer la connexion au bon port sans avoir à changer votre fichier d'inventaire. J'ai publié les détails sur mon blog: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/
@RichardSalts merci de m'avoir aidé à démarrer. J'ai utilisé nc pour vérifier les ports qui devraient être beaucoup plus rapides. Voici mon bootstrap.xml:
Testé avec ansible 1.5 (devel 3b8fd62ff9) dernière mise à jour le 2014/01/28 20:26:03
la source
Puisque vous déployez probablement votre configuration ssh tôt, vous devriez vraiment garder cela simple. Il vous suffit de configurer votre inventaire avec la cible
ansible_ssh_port
et de l'utiliser-e
lors du premier déploiement de votre configuration ssh:Notez qu'il
ansible_ssh_port
est déconseillé dans 2.0 (remplacé paransible_port
)la source
J'avais également besoin de fonctionnalités similaires, j'ai donc bifurqué et patché le plugin Ansible ssh en espérant qu'Ansible Inc. l'adopterait; ils ne l'ont pas fait. Il teste les spécifications de port ssh non std pour voir si elles sont ouvertes et revient au port ssh par défaut sinon. Il s'agit d'un très petit patch, disponible sur https://github.com/crlb/ansible .
la source
Si vous avez une liste de ports et que vous souhaitez tous les vérifier et en utiliser un qui fonctionne, vous pouvez l'utiliser dans votre playbook:
la source
Je suis venu avec une liste de tâches idempotente robuste à mettre dans un rôle pour changer le port SSH et gérer la connexion au bon port sans avoir à changer votre fichier d'inventaire. J'ai publié les détails sur mon blog: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/
la source
'dict object' has no attribute 'state'