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?
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:
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
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
S'il y a un defaults.cfg
dans /etc/cloud/cloud.cfg.d/
, supprime-le.
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
.
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.
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)
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:
Sudo yum install -y cloud-init
rm -rf /var/lib/cloud/data
rm -rf /var/lib/cloud/instance
rm -rf /var/lib/cloud/instances/*
/etc/cloud/cloud.cfg
avec la configuration dans la réponse ci-dessus, mais assurez-vous de définir distro: rhel
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.