5 votes

Comment attendre que user_data script s'exécute lors du démarrage d'instances EC2 avec ansible ?

J'utilise Ansible pour démarrer et configurer des instances EC2 qui sont actuellement basées sur une AMI (ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20161020 (ami-40d28157)) qui n'a pas Python installé dès le départ.

Comme la plupart des modules ansible ont besoin de Python sur la machine distante pour fonctionner, plutôt que d'utiliser une AMI différente, j'ai essayé d'installer Python sur les instances de départ à l'aide d'un fichier données_utilisateur script.

Il gentil a fonctionné (Python est installé correctement), mais le programme ansible ec2 retour des tâches avant le script user_data script finit de s'exécuter, et donc les tâches de la pièce suivante (celles qui configureraient réellement l'instance) échouent avec l'erreur '/bin/sh: 1: /usr/bin/python: not found\r\n'

Étant donné que, sans Python, je ne peux même pas exécuter la plupart des tâches sur l'hôte distant, je ne peux pas simplement vérifier si /usr/bin/python ou qu'un fichier marqueur est présent, ou vérifiez la sortie syslog, par exemple.

J'ai pensé à ajouter un nc -l $SOME_PORT à la fin du script de user_data et en le vérifiant à l'aide de la fonction wait_for mais cela ressemble trop à un piratage pour moi.

Est-il possible d'utiliser le ec2 pour démarrer une instance de manière à ce qu'elle attende que le script de user_data finisse de s'exécuter ?

Pour référence :

Un cahier des charges similaire à celui que j'utilise :

- name: Create the EC2 instance
  hosts: localhost
  gather_facts: false
  vars: 
    name: myinstance
    ami: ami-40d28157
    #Other vars ommited for brevity
  tasks:
    - name: Launch Instance
      ec2:
        key_name: "{{ keypair }}"
        group: "{{ security_group }}"
        instance_type: "{{ instance_type }}"
        image: "{{ ami }}"
        user_data: "{{ lookup('file', 'user_data.sh') }}"
        wait: true
        region: "{{ region }}"
        vpc_subnet_id: "{{ subnet }}"
        assign_public_ip: no
        zone: "{{ zone }}"
        instance_tags: "{{ tag_map }}"
        exact_count: 1
        count_tag:
          Name: "{{ name }}"
      register: ec2

    - name: Add new Instance to host group
      add_host: name={{ item.private_ip }} groups={{ name }}
      with_items: "{{ ec2.instances }}"

    - name: Wait for SSH to come up
      wait_for: host={{ item.private_ip }} port=22 delay=60 timeout=320 state=started
      with_items: "{{ ec2.instances }}"

- name: Configure instance(s)
  hosts: myinstance
  tasks:
    - name: Example task
      command: touch a_file

Le script user_data.sh script :

#!/bin/bash
set -e -x
export DEBIAN_FRONTEND=noninteractive
sudo locale-gen pt_BR.UTF-8
sudo apt-get update && apt-get upgrade -y
sudo apt-get install -y python-minimal

0 votes

Puisque vous attendez déjà le port 22, je le bloquerais dans le fichier user_data.sh script au début et débloquer à la fin. Il n'existe pas d'option de ce type pour ec2 module.

1 votes

Pourquoi ne pas créer votre propre AMI avec Python déjà installé ?

13voto

Adam Romanek Points 273

Il s'avère que vous pouvez utiliser cloud-init pour cela, à savoir :

cloud-init status --wait

Vous devez donc ajouter l'extrait suivant à votre playbook :

- name: Wait for cloud-init / user-data to finish
  command: cloud-init status --wait
  changed_when: false

Elle semble un peu plus propre par rapport à la première réponse.

6voto

Konstantin Suvorov Points 3696

Voici la réponse à votre question "Comment attendre que les données utilisateur script s'exécutent lors du démarrage des instances EC2 avec ansible ?" :

- raw: test -f /var/lib/cloud/instance/boot-finished
  retries: 20
  register: cmd_res
  changed_when: false
  until: cmd_res | success

Cette opération se connectera via ssh et réussira si boot-finished est présent, qui est créé après que le cloud-init sur l'hôte termine tous les modules (y compris user_data script).

Mais je suggère de créer une AMI avec Python préinstallé, ou d'utiliser raw o script Module Ansible pour vérifier/installer Python (ces modules ne nécessitent pas Python).

2 votes

Il est à noter qu'avec ansible >= 2.8 cette solution donne un avertissement de dépréciation. [AVERTISSEMENT DE DÉPRÉCIATION] : L'utilisation de tests comme filtres est dépréciée. Au lieu d'utiliser result|success utiliser result is success .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X