web-dev-qa-db-fra.com

Comment configurer cloud-init sur des AMI personnalisées dans AWS? (CentOS)

La définition des données utilisateur pour les instances dans AWS semble vraiment utile pour effectuer toutes sortes d'actions de type bootstrap. Malheureusement, je dois utiliser une AMI CentOS personnalisée qui ne provient pas de l'une des AMI fournies pour des raisons PCI, donc cloud-init n'est pas déjà installé et configuré. Je veux seulement qu'il définisse un nom d'hôte et exécute un petit script bash. Comment le faire fonctionner?

30
whereswalden

cloud-init est un outil très puissant mais très peu documenté. Même une fois installé, de nombreux modules actifs par défaut écrasent les éléments que vous avez peut-être déjà définis sur votre AMI. Voici les instructions pour une configuration minimale à partir de zéro:

Instructions

  1. Installez cloud-init à partir d'un référentiel standard. Si vous êtes préoccupé par PCI, vous ne voudrez probablement pas utiliser les référentiels personnalisés d'AWS.

    # rpm -Uvh https://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    # yum install cloud-init
    
  2. Modifier /etc/cloud/cloud.cfg, un fichier yaml, pour refléter la configuration souhaitée. Vous trouverez ci-dessous une configuration minimale avec une documentation pour chaque module.

    #If this is not explicitly false, cloud-init will change things so that root
    #login via ssh is disabled. If you don't want it to do anything, set it false.
    disable_root: false
    
    #Set this if you want cloud-init to manage hostname. The current
    #/etc/hosts file will be replaced with the one in /etc/cloud/templates.
    manage_etc_hosts: true
    
    #Since cloud-init runs at multiple stages of boot, this needs to be set so
    #it can log in all of them to /var/log/cloud-init.
    syslog_fix_perms: null
    
    #This is the bit that makes userdata work. You need this to have userdata
    #scripts be run by cloud-init.
    datasource_list: [Ec2]
    datasource:
      Ec2:
        metadata_urls: ['http://169.254.169.254']
    
    #modules that run early in boot
    cloud_init_modules:
     - bootcmd  #for running commands in pre-boot. Commands can be defined in cloud-config userdata.
     - set-hostname  #These 3 make hostname setting work
     - update-hostname
     - update-etc-hosts
    
    #modules that run after boot
    cloud_config_modules:
     - runcmd  #like bootcmd, but runs after boot. Use this instead of bootcmd unless you have a good reason for doing so.
    
    #modules that run at some point after config is finished
    cloud_final_modules:
     - scripts-per-once  #all of these run scripts at specific events. Like bootcmd, can be defined in cloud-config.
     - scripts-per-boot
     - scripts-per-instance
     - scripts-user
     - phone-home  #if defined, can make a post request to a specified url when done booting
     - final-message  #if defined, can write a specified message to the log
     - power-state-change  #can trigger stuff based on power state changes
    
    system_info:
      #works because Amazon's linux AMI is based on CentOS
      distro: Amazon
    
  3. S'il y a un defaults.cfg dans /etc/cloud/cloud.cfg.d/, supprime-le.

  4. Pour tirer parti de cette configuration, définissez les données utilisateur suivantes pour les nouvelles instances:

    #cloud-config
    hostname: myhostname
    fqdn: myhostname.mydomain.com
    runcmd:
     - echo "I did this thing post-boot"
     - echo "I did this too"
    

    Vous pouvez également simplement exécuter un script bash en remplaçant #cloud-config avec #!/bin/bash et en mettant le script bash dans le corps, mais si vous le faites, vous devez supprimer tous les modules liés au nom d'hôte de cloud_init_modules.


Notes complémentaires

Notez qu'il s'agit d'une configuration minimale et que cloud-init est capable de gérer les utilisateurs, les clés ssh, les points de montage, etc. Consultez les références ci-dessous pour plus de documentation sur ces fonctionnalités spécifiques.

En général, il semble que cloud-init fasse des choses basées sur les modules spécifiés. Certains modules, comme "disable-ec2-metadata", font des choses simplement en étant spécifiés. D'autres, comme "runcmd", ne font des choses que si leurs paramètres sont spécifiés, soit dans cloud.cfg, soit dans cloud-config userdata. La plupart de la documentation ci-dessous ne vous indique que les paramètres possibles pour chaque module, pas son nom, mais le cloud.cfg par défaut devrait avoir une liste complète de modules pour commencer. Le meilleur moyen que j'ai trouvé pour désactiver un module est simplement de le retirer de la liste.

Dans certains cas, "rhel" peut fonctionner mieux pour la balise "distro" que "Amazon". Je n'ai pas vraiment compris quand.


Les références

50
whereswalden

Voici un bref tutoriel sur la façon d'exécuter des scripts au démarrage à l'aide de cloud-init sur AWS EC2 (CentOS).

Ce tutoriel explique:

  • comment définir le fichier de configuration /etc/cloud/cloud.cfg
  • comment le chemin du cloud /var/lib/cloud/scripts ressemble
  • les fichiers de script sous le chemin du cloud à l'aide d'un exemple, et
  • comment vérifier si les fichiers de script sont exécutés au démarrage de l'instance

Fichier de configuration

Le fichier de configuration ci-dessous se trouve sur AWS CentOS6. Pour Amazon Linux, voir ici .

# cat /etc/cloud/cloud.cfg
manage_etc_hosts: localhost
user: root
disable_root: false
ssh_genkeytypes: [ rsa, dsa ]

cloud_init_modules:
 - resizefs
 - update_etc_hosts
 - ssh

cloud_final_modules:
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - scripts-user

Arborescence du répertoire

Voici ce que le chemin du cloud /var/lib/cloud/scripts ressemble à:

# cd /var/lib/cloud/scripts
# tree `pwd`
/var/lib/cloud/scripts
├── per-boot
│     └── per-boot.sh
├── per-instance
│     └── per-instance.sh
└── per-once
       └── per-once.sh

Contenu des fichiers de script

Voici le contenu des exemples de fichiers de script.
Les fichiers doivent se trouver sous l'utilisateur root. Voir mon chemin création du script de démarrage .

# cat /var/lib/cloud/scripts/per-boot/per-boot.sh
#!/bin/sh
echo per-boot: `date` >> /tmp/per-xxx.txt

# cat /var/lib/cloud/scripts/per-instance/per-instance.sh
#!/bin/sh
echo per-instance: `date` >> /tmp/per-xxx.txt

# cat /var/lib/cloud/scripts/per-once/per-once.sh   
#!/bin/sh
echo per-once: `date` >> /tmp/per-xxx.txt

Résultat de l'exécution

En cas de démarrage initial

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST

En cas de redémarrage

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:32:24 JST

En cas de départ à partir de l'AMI

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:32:24 JST 
per-boot: 1 January 3, 2013 Thursday 17:44:08 JST

Référence
Le moment auquel le script est exécuté dans cloud-init (CentOS6) a été examiné (traduit)

6
Chetabahana

Extension sur la réponse précédente pour toute personne essayant de créer une AMI CentOS qui est cloud-init activé (et capable d'exécuter réellement vos scripts CloudFormation), vous pourriez avoir du succès en procédant comme suit:

  1. lancer une AMI CentOS de marché avec mises à jour - assurez-vous que cloud-init est présent ou Sudo yum install -y cloud-init
  2. rm -rf /var/lib/cloud/data
  3. rm -rf /var/lib/cloud/instance
  4. rm -rf /var/lib/cloud/instances/*
  5. remplacer /etc/cloud/cloud.cfg avec la configuration dans la réponse ci-dessus, mais assurez-vous de définir distro: rhel
  6. Ajoutez les assistants CloudFormation ( http://docs.aws.Amazon.com/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html )
  7. créer une image AMI à partir de cette instance

J'ai eu beaucoup de temps à essayer de comprendre pourquoi mes UserData n'étaient pas invoquées jusqu'à ce que je réalise que les images sur le marché n'exécutent naturellement vos UserData qu'une fois par instance ET bien sûr, elles avaient déjà été exécutées. Suppression des indicateurs que ceux-ci avaient déjà été exécutés et modification du distro: rhel dans le cloud.cfg le fichier a fait l'affaire.

Pour les curieux, les distro: la valeur doit correspondre à l'un des scripts python dans /usr/lib/python2.6/site-packages/cloudinit/distros. Il s'avère que l'AMI que j'ai lancé n'avait pas de Amazon.py, vous devez donc utiliser rhel pour CentOS. En fonction de l'AMI que vous lancez et de la version de cloud-init, YMMV.

6
bigfoot