AWS Certified CloudOps Engineer - Associate
AMI et EC2 Image Builder
Ce que contient réellement une AMI, où passe la frontière entre intégrer à l'image et amorcer au démarrage, comment un pipeline EC2 Image Builder transforme une image de base en AMI dorée testée et distribuée, et la différence entre déprécier, désactiver et désenregistrer une image.
- Décrire ce que contient une AMI et quelles propriétés sont figées à sa création
- Décider ce qui appartient à l'image et ce qui appartient à l'amorçage au démarrage
- Expliquer les cinq ressources d'EC2 Image Builder et la façon dont un pipeline les assemble en une exécution
- Prédire ce qui se passe quand l'étape de test d'un pipeline Image Builder échoue
- Comparer déprécier, désactiver et désenregistrer une AMI, et choisir l'action juste pour une exigence donnée
- Énoncer ce qu'exige le partage d'une AMI adossée à des snapshots chiffrés avec un autre compte
Un Auto Scaling group ajoute une instance pendant un pic de trafic. L'instance démarre en 40 secondes environ, puis passe 8 minutes de plus dans le user data : correctifs de l'OS, téléchargement de trois agents, compilation d'une dépendance. Quand elle passe enfin son health check, le pic est terminé. Pire, l'instance lancée mardi dernier a installé des versions de paquets légèrement différentes de celle lancée aujourd'hui, parce que les deux ont résolu « latest » contre un dépôt qui a bougé entre-temps.
Les deux problèmes ont le même remède. Faites ce travail une fois, avant le lancement, et stockez le résultat sous forme d'image.
Ce qu'est réellement une AMI
Une Amazon Machine Image n'est pas un fichier que vous téléchargez. C'est un enregistrement dans EC2 qui pointe vers un ou plusieurs snapshots EBS et porte les métadonnées nécessaires pour transformer ces snapshots en instance démarrable :
- Le block device mapping : quel snapshot devient le volume racine, sa taille, les volumes supplémentaires à attacher, et s'ils sont supprimés à la terminaison.
- Les métadonnées de boot et de plateforme : architecture (x86_64 ou arm64), type de virtualisation, type de volume racine et boot mode.
- Les launch permissions : quels comptes, organisations ou OU peuvent lancer depuis cette image.
Deux conséquences découlent de cette structure, et les deux tombent à l'examen.
Une AMI est régionale. Les snapshots vivent dans une seule Region, donc l'ID d'AMI n'a de sens que dans cette Region. Pour lancer la même image dans une seconde Region, vous l'y copiez, et la copie reçoit un ID différent. C'est pour cette raison qu'un template CloudFormation qui code en dur un ID d'AMI casse dès que quelqu'un le déploie ailleurs.
Vous ne payez pas l'AMI, vous payez ses snapshots. L'enregistrement AMI lui-même est gratuit. Chaque AMI que vous avez créée vous facture discrètement le stockage des snapshots derrière elle, ce qui explique pourquoi la section sur le nettoyage, à la fin de cette leçon, compte plus qu'elle n'en a l'air.
Une AMI est aussi figée sur ces propriétés. Vous ne transformez pas une AMI x86_64 en arm64, ni une AMI instance-store en AMI adossée à EBS. Quand il vous faut une autre combinaison, vous construisez une nouvelle image.
Intégrer à l'image ou amorcer au démarrage : la décision qui structure tout le reste
Chaque élément de configuration dont un serveur a besoin peut arriver de deux façons. L'intégration à l'image (baking) le place dans l'image au moment du build. L'amorçage (bootstrapping) l'applique au lancement, via le user data, une association Systems Manager ou un outil de gestion de configuration.
Rien ne vous oblige à choisir un camp. La bonne question est de savoir quelle moitié de votre configuration va de quel côté.
| Intégré à l'AMI | Amorcé au lancement | |
|---|---|---|
| Coût en temps de lancement | Nul, le travail a déjà eu lieu | Payé à chaque lancement |
| Cohérence | Identique au bit près sur chaque instance | Dépend de ce que les dépôts amont servent à cette minute |
| Modification | Reconstruire l'image et remplacer les instances | Modifier le script, le lancement suivant le prend |
| Valeurs propres à un environnement | Force une image par environnement | Traitées naturellement |
| Auditabilité | Un ID d'image répond à « qu'y a-t-il sur cette machine » | Il faut le reconstituer depuis les logs |
La règle de décision qui tombe de ce tableau : intégrez ce qui est lent et stable, amorcez ce qui est rapide et variable. Les correctifs de l'OS, les agents, les runtimes et les dépendances compilées sont lents et stables, donc ils appartiennent à l'image. L'endpoint de base de données, le nom de l'environnement et le rôle de l'instance dans le cluster sont rapides et varient à chaque déploiement, donc ils appartiennent au user data ou à Parameter Store.
Une image construite de cette façon s'appelle en général une AMI dorée : une base durcie, corrigée et préchargée depuis laquelle toutes les charges de travail de l'organisation se lancent.
Voici la fausse idée que cette section existe pour tuer : « une AMI dorée, cela veut dire que tout est dans l'image ». Poussez le raisonnement jusque-là et vous reconstruisez une image pour changer un niveau de log, en maintenant une image par environnement et par application. L'image est une ligne de départ, pas un serveur terminé.
Pourquoi les AMI dorées faites à la main finissent par céder
La première AMI dorée est facile. Vous lancez une instance, vous la corrigez, vous installez ce qu'il faut, vous exécutez create-image et vous notez l'ID sur une page de wiki.
C'est au deuxième mois que le procédé se fissure. De nouvelles CVE sortent, donc l'image a besoin d'une reconstruction, et la personne qui l'avait montée est en congé et n'a jamais écrit l'étape 4. Personne n'a testé la nouvelle image avant qu'un Auto Scaling group ne commence à lancer depuis elle. L'image n'existe que dans us-east-1, alors que la Region de reprise en a besoin aussi. Et aucune trace ne dit ce qui a changé entre la version 3 et la version 4.
Ces échecs ne viennent pas d'un manque de sérieux. Ils arrivent quand un processus de build vit dans la mémoire de quelqu'un au lieu de vivre dans un fichier. EC2 Image Builder existe pour le déplacer dans des fichiers.
Les cinq ressources d'Image Builder
Image Builder découpe la construction d'une image en cinq ressources, et dès que vous voyez ce que chacune possède, le service cesse de paraître gros.
| Ressource | Répond à la question | Contient |
|---|---|---|
| Image recipe | Que met-on dans l'image ? | L'image de base, une liste ordonnée de components, des réglages d'instance comme la taille du volume racine |
| Component | Comment réalise-t-on une personnalisation ? | Un document YAML AWSTOE avec des phases et des étapes : installer un paquet, durcir un réglage, exécuter un test |
| Infrastructure configuration | Où l'image est-elle construite ? | Types d'instance, subnet, security groups, IAM instance profile, topic SNS, bucket S3 de logs, terminaison en cas d'échec |
| Distribution settings | Où part l'image finie ? | Regions cibles, nom de l'AMI de sortie, clé KMS, comptes et OU pour le partage ou la copie, configuration de launch template |
| Image pipeline | Quand tout cela s'exécute-t-il ? | Une recipe, une infrastructure configuration, des distribution settings et une planification |
Deux d'entre elles méritent un regard plus long.
Les components sont l'endroit où vit votre personnalisation réelle. Un component est un document YAML qu'AWSTOE exécute sur l'instance de build, et il en existe deux familles : les build components personnalisent l'instance avant le snapshot, les test components la valident après. AWS publie des components managés pour les tâches courantes, dont update-linux et les jeux de durcissement STIG et CIS, et vous écrivez les vôtres pour tout ce qui vous est propre.
name: InstallAndVerifyNginx
description: Installer nginx et vérifier qu'il répond sur le port 80
schemaVersion: 1.0
phases:
- name: build
steps:
- name: InstallNginx
action: ExecuteBash
inputs:
commands:
- dnf install -y nginx
- systemctl enable nginx
- name: validate
steps:
- name: ConfirmBinary
action: ExecuteBash
inputs:
commands:
- nginx -v
Les noms de phase ne sont pas décoratifs. Image Builder décide du moment où un component s'exécute d'après les phases qu'il définit : un component s'exécute pendant l'étape de build s'il définit build ou validate, et pendant l'étape de test s'il définit test et rien d'autre. Un component ne peut pas être à cheval sur les deux, et vous ne pouvez pas enchaîner une valeur produite en build vers une étape test, parce que ces étapes tournent sur des instances différentes.
L'infrastructure configuration est la ressource qu'on oublie jusqu'au premier build en échec. L'instance de build tourne dans votre VPC, donc elle a besoin d'un subnet avec une route vers les dépôts de paquets, d'un security group qui autorise ce trafic et d'un instance profile portant les permissions Image Builder. C'est aussi là que se trouve l'interrupteur de diagnostic : par défaut l'instance de build se termine quand le build échoue, et désactiver ce comportement garde l'instance vivante pour que vous puissiez vous y connecter et lire les logs AWSTOE.
Ce que fait réellement une exécution de pipeline
Suivez un build de bout en bout, parce que l'ordre des étapes explique plusieurs réponses d'examen.
- Étape de build. Image Builder lance une instance EC2 depuis l'image de base, dans le subnet de votre infrastructure configuration. AWSTOE exécute la phase
buildde chaque build component dans l'ordre de la recipe, puis la phasevalidatede chacun. Si une étape échoue, tout s'arrête ici. - Snapshot. Les personnalisations appliquées, Image Builder arrête l'instance et prend un snapshot, ce qui produit l'image candidate.
- Étape de test. Pour un workflow d'AMI, Image Builder lance une nouvelle instance depuis cette image candidate et exécute la phase
testde chaque component de la recipe. C'est un vrai lancement de l'artefact réel, pas une revérification de l'instance de build, et c'est pour cela qu'il attrape un service qui ne démarre pas au premier boot. - Distribution. Seulement si tous les tests ont réussi, Image Builder copie l'AMI dans chaque Region de vos distribution settings, applique la clé KMS configurée, pose les launch permissions et met éventuellement à jour un launch template pour qu'il pointe vers le nouvel ID d'AMI.
Cette dernière option mérite une pause. La distribution peut écrire le nouvel ID d'AMI dans une version précise d'un launch template EC2, donc un Auto Scaling group qui pointe vers la version $Latest ou $Default de ce template récupère la nouvelle image sans que personne ne modifie quoi que ce soit.
Le service lui-même est gratuit. Vous payez les instances EC2 de build et de test pendant leur exécution, les snapshots EBS occupés par les images, le stockage des logs sur S3, Amazon Inspector si vous activez l'analyse de vulnérabilités pendant le build, et ECR pour les images de conteneurs produites en sortie.
Planification : construire à l'heure, ou construire au changement
Un pipeline s'exécute à la demande, sur une planification cron, ou en réponse à une règle EventBridge. La planification porte un second réglage qui concentre l'essentiel de la valeur, et l'examen le vise souvent.
- Construire à l'heure prévue, toujours. Chaque créneau planifié produit un build, que quelque chose ait changé en amont ou non. Vous obtenez une image fraîche à cadence fixe et vous payez un build à chaque fois.
- Construire à l'heure prévue uniquement si des mises à jour de dépendances existent. Image Builder vérifie si l'image de base ou un component possède une version sémantique plus récente, et saute le build si rien n'a bougé.
La seconde option ne fonctionne que si votre recipe utilise le versionnage sémantique pour l'image de base et les components, ce qui dans la console revient à choisir « utiliser la dernière version d'OS disponible » et « utiliser la dernière version disponible » plutôt qu'une version exacte. Figez tout sur des versions fixes et Image Builder n'a plus rien à comparer : selon la façon dont la recipe est écrite, il reconstruit à chaque fois ou ne détecte jamais de mise à jour.
Un pipeline hebdomadaire réglé sur « seulement en cas de mise à jour de dépendances » est la forme que veulent la plupart des équipes : aucun brassage d'images pendant une semaine calme, et une image corrigée dès qu'AWS publie une nouvelle AMI de base.
Distribuer et partager le résultat
Les distribution settings prennent en charge le travail inter-Régions et inter-comptes que les équipes font sinon à la main.
Dans votre propre compte, la distribution copie l'AMI dans chaque Region cible. Entre comptes, vous avez deux options différentes, et la différence porte sur la propriété :
- Les launch permissions autorisent un autre compte à lancer depuis votre AMI. Vous restez propriétaire de l'image, vous continuez de payer les snapshots, et l'autre compte ne paie que les instances qu'il lance. Retirez la permission et ses futurs lancements s'arrêtent.
- Les comptes et OU cibles créent une copie de l'AMI dans chaque compte cible. Ce compte possède sa copie, paie ses snapshots, et la copie survit à tout ce que vous faites à l'originale.
Le chiffrement ajoute une exigence qui piège plus de monde que le reste du partage d'AMI. Une AMI dont les snapshots sont chiffrés avec la clé gérée par AWS par défaut ne peut pas être partagée du tout, parce que la policy de cette clé n'est pas modifiable. Partager une AMI chiffrée veut dire chiffrer ses snapshots avec une clé KMS gérée par le client et autoriser les comptes cibles à utiliser cette clé. Le remède habituel est une copie : copiez l'AMI sur elle-même en spécifiant votre propre clé KMS, puis partagez la copie.
Deux comportements plus discrets à connaître. Vous n'avez pas à partager les snapshots séparément, parce qu'EC2 accorde l'accès en lancement à votre place. Et vos tags utilisateur ne voyagent pas avec une AMI partagée, donc le compte destinataire voit une image sans tags.
Retirer une image : trois verbes qui ne sont pas synonymes
Une organisation qui construit une AMI dorée par semaine accumule 52 images par an, par Region et par OS. Les nettoyer est un vrai travail d'exploitation, et AWS propose trois actions distinctes que les apprenants confondent régulièrement.
| Déprécier | Désactiver | Désenregistrer | |
|---|---|---|---|
| De nouvelles instances peuvent-elles se lancer ? | Oui, si celui qui lance connaît l'ID | Non, les lancements échouent | Non |
| Auto Scaling groups et launch templates | Continuent de fonctionner | Continuent de la référencer, et leurs lancements échouent | Leurs lancements échouent |
| Visible dans les listes | Masquée aux utilisateurs, visible au propriétaire | Masquée par défaut, visible au seul propriétaire avec --include-disabled | Disparue |
| Partage | Inchangé | Toutes les launch permissions retirées, l'AMI redevient privée | Disparu |
| Réversible | Oui, en annulant la date de dépréciation | Oui, en réactivant, mais le partage n'est pas rétabli | Non, sauf depuis la Recycle Bin si une règle de rétention s'appliquait |
| Snapshots encore facturés | Oui | Oui, et ils ne peuvent pas être supprimés tant que l'AMI est désactivée | Seulement si vous les avez laissés derrière |
| Instances en marche | Inchangées | Inchangées | Inchangées |
Lisez ce tableau comme une échelle d'escalade. Déprécier est un signal : cessez de choisir cette image, mais rien ne casse. Désactiver est un arrêt : les lancements échouent, et vous pouvez revenir en arrière. Désenregistrer est une suppression.
Les chiffres qu'AWS interroge directement : vous pouvez fixer une date de dépréciation jusqu'à 10 ans pour une AMI privée, les AMI publiques sont dépréciées par défaut 2 ans après leur création, et le seul moyen de repousser la dépréciation d'une AMI publique est de la rendre privée en la partageant avec des comptes précis.
Reste le piège de coût. Désenregistrer une AMI ne supprime pas ses snapshots sous-jacents par défaut. Une équipe qui désenregistre 40 AMI périmées en attendant que la facture de stockage baisse va être déçue, parce que les snapshots sont toujours là. Passez --delete-associated-snapshots sur l'appel de désenregistrement, ou nettoyez-les après. Un snapshot référencé par plusieurs AMI est conservé dans tous les cas.
Rien de tout cela ne se fait forcément à la main. Les lifecycle policies d'Image Builder appliquent la dépréciation, la désactivation et la suppression aux images produites par un pipeline, avec des règles fondées sur l'âge ou le nombre et des règles d'exclusion pour protéger les images à garder. Amazon Data Lifecycle Manager couvre le même terrain pour les AMI adossées à EBS en général, y compris celles que vous n'avez pas construites avec Image Builder.
Conseils pour l'examen
- « Arrêter les lancements tout de suite, avec la possibilité d'annuler » vaut désactiver. « Marquer comme obsolète mais garder fonctionnel » vaut déprécier. « Supprimer » vaut désenregistrer. Les options qui mélangent les effets sont les distracteurs.
- Si un énoncé dit qu'un Auto Scaling group lance encore depuis une vieille image après une dépréciation, c'est le comportement attendu, pas un bug. La dépréciation masque une AMI des listes ; elle ne bloque jamais un lancement par ID.
- Le désenregistrement n'arrête pas la facturation des snapshots à lui seul. Toute réponse qui traite le désenregistrement comme un nettoyage complet est fausse.
- Le partage d'une AMI chiffrée exige une clé KMS gérée par le client plus une autorisation d'usage pour le compte cible. Si l'énoncé mentionne la clé gérée par AWS par défaut, le partage est impossible, et la réponse passe par une copie avec votre propre clé.
- Un pipeline Image Builder qui rate ses tests ne distribue rien. Si une question demande pourquoi une nouvelle AMI n'est jamais apparue dans la Region de reprise, un test component en échec est un suspect de premier plan, à côté de la Region tout simplement absente des distribution settings.
- « Construire seulement quand l'image de base est corrigée » désigne le réglage de mise à jour des dépendances, qui dépend du versionnage sémantique dans la recipe.
- Image Builder est gratuit. Les frais viennent des instances de build et de test, des snapshots, des logs, d'Inspector et d'ECR.
- Guettez le partage entre intégration et amorçage dans les scénarios. Des temps de lancement longs pointent vers l'intégration à l'image ; une configuration propre à un environnement pointe vers l'amorçage.
L'idée à emporter, c'est qu'une image est un artefact de build avec une version, une suite de tests et une date de péremption, pas un serveur que quelqu'un a configuré un jour. Ce cadrage rend tout le domaine cohérent : l'image est construite depuis un fichier, testée avant d'être livrée, distribuée par politique et retirée sur planning.
Tout dans cette leçon supposait que l'unité livrée est une machine. La leçon suivante change cette hypothèse. Quand la machine existe déjà et que seule l'application change, vous livrez une image de conteneur, et presque toutes les idées vues ici réapparaissent sous une forme plus petite et plus rapide.
