AWS Certified CloudOps Engineer - Associate
CloudFormation StackSets
Déployer un seul template dans de nombreux comptes et Regions en une opération : stack sets et stack instances, permissions self-managed contre service-managed, cibles de déploiement et filtres de comptes, concurrence et tolérance aux échecs, dérive, et les échecs qui se cachent derrière un statut SUCCEEDED.
- Distinguer un stack set, une stack instance et une stack, et expliquer pourquoi une stack instance peut exister sans stack
- Choisir entre permissions self-managed et service-managed, et nommer les rôles exigés par chaque modèle
- Cibler une organisation, des OU précises ou des comptes filtrés, et prévoir quels comptes reçoivent une stack
- Régler la tolérance aux échecs, le maximum de comptes concurrents et la concurrence entre Regions selon le risque du déploiement
- Interpréter les codes de statut de stack set et de stack instance, dont OUTDATED et INOPERABLE
- Expliquer en quoi la drift detection d'un stack set diffère de celle d'une stack isolée
- Diagnostiquer les échecs courants de StackSets, dont une opération qui affiche SUCCEEDED alors que des stacks ont échoué
Une équipe sécurité a besoin d'un rôle IAM en lecture seule, d'un recorder Config et d'une règle d'expédition de logs dans 40 comptes répartis sur 4 Regions. Cela fait 160 stacks. La version scriptée est une boucle qui assume un rôle dans chaque compte et appelle create-stack, et elle fonctionne jusqu'au compte 23 qui tape dans un quota de service : la boucle continue, et personne ne remarque pendant trois semaines que quatre comptes n'ont aucun recorder Config.
Le problème n'est pas la boucle. C'est que la boucle n'a pas de mémoire. Rien n'enregistre que ces 160 stacks sont censées être la même chose, donc rien ne peut vous dire lesquelles sont à jour, lesquelles ont échoué et lesquelles quelqu'un a modifiées à la main.
StackSets est cette mémoire. Vous définissez le template une fois, vous nommez les comptes et les Regions, et CloudFormation suit chaque stack produite comme membre d'un ensemble géré.
Stack set, stack instance, stack
Trois mots qui semblent interchangeables et qui ne le sont pas.
Un stack set est le conteneur : un template, un jeu de parameters, et la configuration de déploiement. Il vit dans le compte administrateur, et c'est une ressource régionale. Créez un stack set dans eu-west-1 et vous ne le verrez pas quand la console est basculée sur us-east-1, ce qui surprend ceux qui supposent qu'une fonctionnalité multi-Regions doit elle-même être globale.
Une stack instance est une référence à une stack dans un compte cible, dans une Region donnée. Trois comptes sur deux Regions donnent 6 stack instances, et chacune porte son propre statut.
Une stack est la stack CloudFormation ordinaire qui contient réellement les ressources, dans le compte cible.
Cette séparation entre instance et stack ressemble à du pédantisme comptable jusqu'au premier échec. Une stack instance peut exister sans stack : si la création a échoué, il n'y a pas de stack, mais l'instance subsiste et porte le motif. C'est ce qui rend un déploiement raté diagnosticable au lieu d'invisible.
aws cloudformation list-stack-instances --stack-set-name org-baseline \
--filters Name=DETAILED_STATUS,Values=FAILED
Deux modèles de permissions, un seul vrai choix
Déployer dans un autre compte veut dire y assumer un rôle. StackSets propose deux façons d'organiser cela, et l'examen teste laquelle un scénario impose.
Les permissions self-managed signifient que vous construisez vous-même la chaîne de confiance, avec deux rôles dont les noms comptent :
AWSCloudFormationStackSetAdministrationRoledans le compte administrateur. Sa trust policy autorisecloudformation.amazonaws.comà l'assumer, et sa permissions policy autorisests:AssumeRolesur l'execution role des cibles.AWSCloudFormationStackSetExecutionRoledans chaque compte cible, qui fait confiance au compte administrateur. Ce rôle a besoin des permissions CloudFormation complètes, plus les permissions de tout ce que le template crée.
Utilisez ces noms exacts et StackSets les reprend automatiquement. Utilisez des noms personnalisés et chaque opération doit les nommer explicitement. Les templates d'exemple publiés par AWS pour ces rôles accordent "Action": "*" à l'execution role, ce qui convient à un premier test et ne convient à rien de permanent. Restreignez l'execution role aux types de ressources que votre template crée vraiment, parce que ce rôle est le plafond de tout ce qu'une opération de stack set pourra faire dans ce compte.
Les permissions service-managed confient le problème des rôles à CloudFormation. Vous activez le trusted access entre CloudFormation et AWS Organizations, et à partir de là CloudFormation crée et entretient les rôles dans les comptes membres. Vous ciblez des OU au lieu de lister des ID de comptes, et vous obtenez le déploiement automatique.
| Self-managed | Service-managed | |
|---|---|---|
| Comptes cibles | Tout compte où vous pouvez créer un rôle | Uniquement les comptes de votre organisation |
| Mise en place des rôles | Vous créez les deux rôles | CloudFormation les crée |
| Cibles exprimées en | ID de comptes | Racine de l'organisation ou ID d'OU |
| Un nouveau compte rejoint l'OU | Rien ne se passe | Le déploiement automatique ajoute une stack |
| Piloté depuis | N'importe quel compte | Compte de gestion, ou administrateur délégué |
| Nested stacks, macros, transforms | Pris en charge | Non pris en charge |
Deux contraintes du modèle service-managed méritent d'être mémorisées, parce qu'elles contredisent ce que l'on suppose.
Le compte de gestion ne reçoit jamais de stack. Ciblez l'organisation entière et CloudFormation l'ignore quand même. Si le compte de gestion a besoin de la même baseline, il reçoit sa propre stack ou son propre stack set self-managed.
Un administrateur délégué ne peut pas être restreint. Le compte de gestion peut enregistrer jusqu'à 5 comptes membres comme administrateurs délégués, ce qui donne à une équipe plateforme centrale la possibilité de piloter des stack sets à l'échelle de l'organisation sans détenir les identifiants du compte de gestion. Mais un administrateur délégué atteint tous les comptes de l'organisation. Il n'existe aucun réglage du type « cette équipe ne déploie que dans l'OU Sandbox ».
aws organizations register-delegated-administrator \
--service-principal member.org.stacksets.cloudformation.amazonaws.com \
--account-id 444455556666
Depuis le compte administrateur délégué, chaque commande porte --call-as DELEGATED_ADMIN. Omettez l'option et le CLI cherche des stack sets self-managed dans le compte membre lui-même, n'en trouve aucun, et renvoie une liste vide qui ressemble à un problème de permissions.
Choisir qui reçoit une stack
Avec les permissions service-managed, les cibles de déploiement sont la racine de l'organisation ou une liste d'ID d'OU. Cibler une OU parente inclut automatiquement ses OU enfants, ce qui est le comportement souhaité pour une baseline de sécurité et celui qui vous surprend quand une OU sandbox imbriquée hérite d'une politique de production.
Par défaut, chaque compte d'une OU ciblée reçoit une stack. Les filtres de comptes affinent cela :
| Type de filtre | Signification |
|---|---|
NONE (défaut) | Tous les comptes des OU listées |
INTERSECTION | Uniquement les comptes listés, et seulement s'ils sont dans les OU listées |
DIFFERENCE | Tous les comptes des OU listées sauf les comptes listés |
UNION | Tous les comptes des OU listées, plus les comptes listés |
aws cloudformation create-stack-instances --stack-set-name org-baseline \
--deployment-targets OrganizationalUnitIds=ou-rcuk-1x5j1lwo,Accounts=111122223333,AccountFilterType=DIFFERENCE \
--regions eu-west-1 us-east-1
DIFFERENCE est celui qui gagne sa place dans la vraie vie. Une baseline s'applique à toute l'OU Workloads sauf au seul compte hérité qu'elle casserait, et vous exprimez cette exception dans le déploiement plutôt qu'en sortant le compte de son OU.
Concurrence et tolérance aux échecs
Pousser un template vers 160 endroits d'un coup est un bon moyen de casser 160 endroits d'un coup. Quatre réglages contrôlent le rayon d'action, et ils interagissent.
Maximum concurrent accounts limite le nombre de comptes cibles traités en même temps, en valeur absolue ou en pourcentage. Les pourcentages sont arrondis à l'inférieur : 25 % de 10 comptes font 2, pas 3.
Failure tolerance est le nombre ou le pourcentage d'échecs autorisés par Region avant que CloudFormation s'arrête. Arrondi à l'inférieur également.
Region concurrency vaut SEQUENTIAL (le défaut, une Region à la fois dans l'ordre de déploiement que vous avez fixé) ou PARALLEL (toutes les Regions en même temps).
Concurrency mode décide de ce qui arrive à la concurrence quand les échecs commencent. STRICT_FAILURE_TOLERANCE maintient le maximum de comptes concurrents à au plus la tolérance aux échecs plus 1, donc l'opération ralentit à mesure que les échecs s'accumulent. SOFT_FAILURE_TOLERANCE conserve votre niveau de concurrence quoi qu'il arrive.
Déroulons une opération. Vous déployez vers 10 comptes dans eu-west-1, us-east-1 et ap-southeast-2, dans cet ordre, avec une tolérance aux échecs de 20 %, un maximum de comptes concurrents de 50 %, et des Regions séquentielles.
- 20 % de 10 arrondi à l'inférieur donne 2 échecs autorisés par Region. 50 % de 10 donne 5 comptes à la fois.
eu-west-1traite 5 comptes, puis les 5 autres. Deux échouent. C'est exactement la tolérance, donc la Region se termine et l'opération continue.us-east-1démarre et un troisième compte échoue dans cette Region. La tolérance y est dépassée, donc le statut de l'opération passe àFAILEDetap-southeast-2est annulée entièrement.
La tolérance aux échecs se réinitialise à chaque Region. C'est ce qui fait du déploiement séquentiel un vrai mécanisme de sécurité : un template cassé partout échoue dans la première Region et n'atteint jamais les suivantes.
Les valeurs par défaut sont volontairement timides, MaxConcurrentCount=1 et FailureToleranceCount=0 dans les exemples CLI, soit un compte à la fois et un arrêt au premier échec. Pour le premier déploiement d'un nouveau template, c'est le bon choix. Vous augmentez ensuite, quand le template a fait ses preuves.
Les statuts, et celui qui ment
Les opérations de stack set affichent RUNNING, SUCCEEDED, FAILED, QUEUED, STOPPING ou STOPPED. QUEUED apparaît avec le déploiement automatique : déplacez un compte d'une OU à une autre et StackSets lance une suppression pour l'ancienne OU puis met en file d'attente une création pour la nouvelle.
Les stack instances portent leurs propres statuts, et deux d'entre eux signalent du travail en attente :
OUTDATEDveut dire que la stack n'est pas à jour avec le stack set, presque toujours parce qu'une création ou une mise à jour y a échoué, ou parce que l'opération s'est arrêtée avant de l'atteindre.INOPERABLEveut dire qu'une opération de suppression d'instances a échoué et laissé la stack dans un état instable. Les instances dans cet état sont exclues des mises à jour ultérieures du stack set, donc elles cessent silencieusement de recevoir vos changements. La récupération consiste à supprimer l'instance avecRetainStacksà true, puis à nettoyer la stack à la main.
Vient maintenant l'idée fausse qui coûte de la couverture réelle. Une opération SUCCEEDED ne veut pas dire que chaque stack a réussi. Elle veut dire que la tolérance aux échecs n'a jamais été dépassée. Fixez la tolérance à 10 sur 10 comptes, et une opération où chaque stack échoue renvoie quand même SUCCEEDED, parce que vous avez déclaré ce nombre d'échecs acceptable.
Le chiffre que vous voulez vraiment se trouve dans les détails du statut :
aws cloudformation describe-stack-set-operation \
--stack-set-name org-baseline --operation-id 5550e62f-c822-4331-88fa-21c1d7bafc60
{
"StackSetOperation": {
"Status": "SUCCEEDED",
"StatusDetails": { "FailedStackInstancesCount": 3 }
}
}
SUCCEEDED avec un FailedStackInstancesCount non nul est la signature d'une baseline partiellement déployée. Traitez ce champ, et non le statut de l'opération, comme la définition du travail terminé.
La dérive à l'échelle d'un stack set
La drift detection au niveau du stack set lance la détection de dérive sur chaque stack instance et agrège les réponses. Une ressource dérivée rend sa stack dérivée, une stack dérivée rend son instance dérivée, et une instance dérivée rend le stack set entier DRIFTED.
aws cloudformation detect-stack-set-drift --stack-set-name org-baseline
L'opération renvoie un ID parce qu'elle est longue, et describe-stack-set-operation publie les compteurs à mesure : DriftedStackInstancesCount, InSyncStackInstancesCount, InProgressStackInstancesCount, FailedStackInstancesCount, sur un total TotalStackInstancesCount. Une seule détection de dérive peut tourner à la fois sur un stack set donné, et vous pouvez l'interrompre avec stop-stack-set-operation.
Deux limites décident de ce que vaut un résultat propre :
- Les changements passés par CloudFormation ne sont jamais de la dérive. Mettez à jour la stack d'un compte cible avec un autre template et la détection rapporte quand même
IN_SYNC, parce que la stack correspond à sa propre configuration attendue. Cette stack est maintenant incohérente avec ses sœurs, ce qui est un vrai problème, et la drift detection n'est pas l'outil qui le trouve. - La détection au niveau d'une stack ne remonte pas. Lancez la détection sur une stack isolée dans un compte cible et ces résultats n'apparaîtront jamais sur la page StackSets de la console. Démarrez la détection au niveau du stack set, sinon son statut de dérive reste périmé.
Les surcharges de parameters sont traitées correctement : comme la détection tourne par stack, une instance avec des valeurs de parameters surchargées est comparée à ses propres attentes surchargées, et non au défaut du stack set.
Quand les opérations échouent
Les échecs se regroupent en une courte liste, et le motif de statut nomme en général la cause directement.
| Symptôme | Cause |
|---|---|
should have 'AWSCloudFormationStackSetExecutionRole' role with trust relationship... | Chaîne de confiance self-managed absente ou mal nommée dans la cible |
| Échec dans un seul compte, template correct ailleurs | Permissions insuffisantes sur l'execution role pour un type de ressource dans ce compte |
| Échecs dans de nombreux comptes sur un nom global | Le template crée une ressource au nom globalement unique, un bucket S3 à nom fixe par exemple |
| Erreur de quota dans certains comptes seulement | Le compte cible détient déjà le maximum d'une ressource créée par le template, des rôles IAM par exemple |
| La suppression échoue sur une stack | La termination protection est activée sur cette stack |
Instance bloquée en INOPERABLE après un import | L'import a échoué : supprimez l'instance avec RetainStacks, corrigez, réessayez |
Réessayer n'est pas une API spéciale. Vous corrigez la cause, puis vous lancez une mise à jour du stack set avec le même template ou un template corrigé, et les instances OUTDATED se remettent à niveau.
Les quotas qui comptent à l'échelle : 1 000 stack sets par compte administrateur, 100 000 stack instances par stack set, et 10 000 opérations de stack instance simultanées par Region et par compte administrateur, tous stack sets confondus. C'est le dernier qui rend un grand déploiement mystérieusement lent plutôt qu'en échec.
Conseils pour l'examen
- « Déployer le même template dans de nombreux comptes et Regions depuis un seul endroit » désigne StackSets. Une réponse décrivant un script qui boucle sur les comptes est fausse même si elle fonctionnerait.
- « Comptes gérés par AWS Organizations » plus « les nouveaux comptes doivent l'obtenir automatiquement » désigne les permissions service-managed avec déploiement automatique. « Comptes hors de l'organisation » ou « pas d'organisation » impose le self-managed.
AWSCloudFormationStackSetAdministrationRolevit dans le compte administrateur,AWSCloudFormationStackSetExecutionRoledans chaque cible. Un motif de statut nommant l'execution role est un problème de confiance self-managed, jamais un problème de trusted access.- Le compte de gestion ne reçoit jamais de stack instance service-managed. Guettez les scénarios où le compte manquant est justement le compte de gestion.
- La tolérance aux échecs s'applique par Region et s'arrondit à l'inférieur. La dépasser dans une Region annule les Regions restantes.
- Un statut d'opération
SUCCEEDEDavec des ressources manquantes veut dire que la tolérance aux échecs a absorbé les échecs. RegardezFailedStackInstancesCount. - Retain stacks conserve les ressources et supprime l'association au stack set. Cette option ne supprime rien.
OUTDATEDsignale une opération échouée ou sautée.INOPERABLEsignale une instance exclue des futures mises à jour tant que vous ne l'avez pas supprimée.- Les stack sets service-managed ne prennent pas en charge les nested stacks, les macros ni les transforms,
AWS::Serverlesscompris. - La drift detection d'un stack set ne considère jamais un changement fait via CloudFormation comme de la dérive.
Retenez une règle de cette leçon : avec StackSets, « déployé » est un fait par instance, pas par opération. Avant de déclarer un déploiement terminé, regardez les statuts des instances et le compteur d'instances en échec, parce que le statut de l'opération est conçu pour vous dire quelque chose de plus étroit que ce que vous voulez savoir.
StackSets pousse des ressources identiques dans les comptes. La leçon suivante traite le mouvement inverse : garder une ressource dans un seul compte et laisser les autres comptes l'utiliser, avec AWS RAM.
