Améliorer la couverture des ressources cloud pour réduire les dérives de l’infrastructure
Stephane Jourdan
23 mars 2022
0 minutes de lectureAvis d’obsolescence : détection des dérives dans les ressources gérées
La détection des dérives dans les ressources gérées, y compris les commandes snyk iac describe --only-managed et snyk iac describe --drift
, n’est plus active. La détection des dérives dans les ressources gérées est devenue obsolète le 30 septembre 2023.
Les développeurs ont besoin de la meilleure visibilité possible sur les ressources qui s’exécutent dans les environnements cloud pour les protéger. L’infrastructure en tant que code (IaC) les aide à automatiser les infrastructures cloud pour que toutes les ressources déployées dans le cloud soient contrôles et puissent être auditées facilement. Pour autant, il n’est pas facile d’atteindre et de maintenir une couverture à 100 % de votre infrastructure par l’IaC.
La sécurité dépend des ressources déployées et exécutées dans les environnements cloud. Or, bien souvent, de nombreuses actions manuelles interviennent régulièrement, que ce soit par nous-mêmes, par d’autres équipes ou par des services authentifiés. Ces modifications ne sont pas visibles dans l’IaC et les audits, et sont ainsi source de nombreux problèmes, notamment des erreurs de configuration et des failles de sécurité. C’est pour cette raison que la gestion des dérives est importante : il faut absolument avoir connaissance des ressources qui ne sont pas encore contrôlées par l’IaC ou qui ont changé pour une raison ou pour une autre.
Dans cet article, nous allons voir comment Snyk IaC aide les développeurs à détecter les ressources qui ne sont pas contrôlées par l’IaC (ressources non gérées) ou qui se sont écartées de leur état attendu (ressources gérées)
Configurer l’environnement
Snyk IaC vous aide à répertorier les ressources localisées en tant que ressources Terraform pour vous aider à déterminer quelle partie du service cloud fait l’objet de la détection. Par exemple, un service Amazon API Gateway v2 se compose d’au moins 12 ressources Terraform. Avec les informations de détection fournies par Snyk, vous pourrez décider rapidement si vous devez inverser la modification, importer une nouvelle ressource ou simplement supprimer cette nouvelle modification.
Pour suivre notre démonstration, vous pouvez utiliser le fichier Terraform ci-dessous afin de créer les deux ressources AWS que nous allons utiliser. Il crée un utilisateur IAM nommé « user1 » avec un suffixe aléatoire, une clé d’accès et une politique attachée d’accès en lecture seule.
Au moment de l’écriture de cet article, la version de Terraform utilisée était la 1.1.7 et celle du fournisseur AWS 3.74.2.
Réutilisez la configuration HCL suivante :
main.tf
1resource "random_string" "prefix" {
2 length = 6
3 upper = false
4 special = false
5}
6
7resource "aws_iam_user" "user1" {
8 name = "user1-${random_string.prefix.result}"
9
10 tags = {
11 Name = "user1-${random_string.prefix.result}"
12 manual = "true"
13 }
14}
15
16resource "aws_iam_access_key" "user1" {
17 user = aws_iam_user.user1.name
18}
19
20resource "aws_iam_user_policy_attachment" "user1" {
21 user = aws_iam_user.user1.name
22 policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
23}
Appliquez la configuration Terraform :
1$ terraform init
2[...]
3$ terraform apply
4[...]
Vérifiez que vous disposez d’un fichier terraform.tfstate
à la racine du répertoire :
1$ ls -al terraform.tfstate
2-rw-r--r-- 1 sjourdan staff 5049 Mar 16 18:31 terraform.tfstate
Vérifiez également que l’utilisateur IAM a bien été créé sur AWS.
Créer un environnement propre
Commençons par répertorier toutes les ressources cloud non contrôlées par Terraform :
1$ snyk iac describe --only-unmanaged
Vous allez probablement obtenir une liste très longue. Ces informations sont utiles, mais peu exploitables dans notre situation. Snyk IaC permet d’ignorer des ressources par lot : il suffit d’ajouter toutes les ressources détectées dans le fichier de politique .snyk
.
Ignorons donc toutes ces ressources non gérées pour profiter d’un environnement contrôlé comportant uniquement les deux ressources que nous avons créées ci-dessus :
1$ snyk iac describe --only-unmanaged --json | snyk iac update-exclude-policy
Renouvelez l’analyse pour confirmer que votre environnement ignore bien les dérives découvertes (vous pourrez programmer leur importation plus tard).
1$ snyk iac describe --only-unmanaged
2
3Scanned states (1)
4Found 3 resource(s)
5 - 100% coverage
6Congrats! Your infrastructure is fully in sync.
Nous sommes maintenant prêts à partir d’un environnement propre.
Partons à la dérive avec l’IAM !
Nous allons maintenant créer trois types de dérives afin de simuler des scénarios susceptibles de survenir dans le monde réel :
Une modification de l’utilisateur IAM actuel (que nous devrons annuler)
L’attachement manuel d’une nouvelle politique IAM (que nous devrons supprimer)
La création d’un nouvel utilisateur IAM (que nous devrons améliorer)
Pour ce faire, rendez-vous dans la console AWS pour IAM.
Modifier l’utilisateur IAM existant en ajoutant une balise
Sur la page des utilisateurs IAM, cliquez sur « user1 ».
Cliquez sur l’onglet Tags (Balises).
Cliquez sur le bouton Edit Tags (Modifier les balises).
Ajoutez une nouvelle clé (« environment ») et une nouvelle valeur (« production »).
Cliquez sur Save (Enregistrer).
Attacher une politique importante à l’utilisateur IAM existant
Sur la page des utilisateurs IAM, cliquez sur « user1 ».
Cliquez sur l’onglet Permissions (Autorisations).
Cliquez sur le bouton Add permissions (Ajouter des autorisations).
Cliquez sur Attach existing policies directly (Attacher directement des politiques existantes).
Sélectionnez Administrator Access (Accès administrateur).
Cliquez sur Next: Review (Suivant : revue).
Validez en cliquant sur Add permissions (Ajouter autorisations).
Créer un autre utilisateur IAM manuellement
Sur la page des utilisateurs IAM, cliquez sur le bouton Add Users (Ajouter des utilisateurs).
Saisissez « user2 » dans le champ User name: (Nom d’utilisateur :).
Sélectionnez Access key (Clé d’accès).
Cliquez sur le bouton Next: Permissions (Suivant : autorisations).
Ne définissez aucune autorisation ni aucune balise.
Cliquez sur Create user (Créer l’utilisateur). Les informations d’identification qui s’affichent ne nous intéressent pas, n’en tenez pas compte.
Nous sommes maintenant prêts à gérer les modifications manuelles à l’aide de la fonction de détection des dérives de Snyk IaC.
Dérives des ressources gérées et non gérées
Voyons comment ces modifications sont détectées par Snyk IaC, en commençant par les ressources qui ne sont pas gérées du tout par Terraform.
1$ snyk iac describe --only-unmanaged
2
3Scanned states (1)
4Found resources not covered by IaC:
5 aws_iam_access_key:
6 - AKIASBXWQ3AYQETE6OFR
7 User: user2
8 aws_iam_policy_attachment:
9 - user1-84i30k-arn:aws:iam::aws:policy/AdministratorAccess
10 aws_iam_user:
11 - user2
12Found 6 resource(s)
13 - 50% coverage
14 - 3 resource(s) managed by Terraform
15 - 3 resource(s) not managed by Terraform
16 - 0 resource(s) found in a Terraform state but missing on the cloud provider
L’analyse donne les résultats suivants, en utilisant les dénominations de ressources Terraform :
Utilisateur IAM « user2 » créé manuellement, avec sa clé d’accès IAM
Politique IAM attachée manuellement à l’utilisateur IAM « user1 » géré par Terraform
Regardons maintenant les modifications concernant uniquement les ressources gérées par Terraform et présentées dans les différents états Terraform :
1$ snyk iac describe –only-managed
2Scanned states (1)
3Found changed resources:
4 From tfstate://terraform.tfstate
5 - user1-84i30k (aws_iam_user.user1):
6 + tags.environment: <nil> => "production"
7Found 5 resource(s)
8 - 100% coverage
9 - 5 resource(s) managed by Terraform
10 - 1/5 resource(s) out of sync with Terraform state
11 - 0 resource(s) found in a Terraform state but missing on the cloud provider
Cette analyse génère des résultats très différents et a pris nettement plus longtemps (36 s contre 9 s en mode d’analyse « non géré »).
Ces résultats nous apprennent que l’utilisateur IAM nommé « user1-84i30k », que nous trouvons dans le fichier HCL (sous forme de ressource) sous le nom « user1 », dispose d’une balise « environment » définie sur « production ».
Plan d’action
L’outil de détection des dérives de Snyk nous a aidés à détecter quatre différences inattendues par rapport à ce que nous anticipions. Dans le cadre de cet article, disons que l’équipe a pris les décisions suivantes :
L’utilisateur IAM « user2 » est utilisé en production et doit être importé dans Terraform.
La clé d’accès IAM de « user2 » doit être modifiée pour des questions de sécurité.
L’utilisateur « user1 » ne doit en aucun cas être administrateur.
La nouvelle balise de « user1 » est nécessaire en raison d’une obligation quelconque et doit être importée dans Terraform.
Objet | Type de ressource | Nom | Type de dérive | Action |
---|---|---|---|---|
Utilisateur IAM |
|
| Non gérée | IMPORTER |
Clé d’accès IAM |
|
| Non gérée | MODIFIER |
Politique IAM attachée |
|
| Non gérée | SUPPRIMER |
Balise d’un utilisateur IAM |
|
| Gérée | IMPORTER |
Les pipelines de déploiement ne sont pas synonymes de correction
Nous disposons d’un pipeline de déploiement Terraform très efficace. La prochaine fois que la commande terraform apply
sera exécutée, il est donc probable que la situation revienne à la normale.
Dans notre cas, que fera Terraform ? Voici une tâche de déploiement :
1$ terraform apply
2Terraform will perform the following actions:
3
4 # aws_iam_user.user1 will be updated in-place
5 ~ resource "aws_iam_user" "user1" {
6 id = "user1-84i30k"
7 name = "user1-84i30k"
8 ~ tags = {
9 - "environment" = "production" -> null
10 # (1 unchanged element hidden)
11 }
12[...]
13
14Plan: 0 to add, 1 to change, 0 to destroy.
Terraform n’est pas conçue pour détecter les ressources créées ou attachées manuellement. La plateforme se contentera de rétablir les ressources modifiées dans leur état d’origine (ce qui n’est pas ce que nous souhaitons ici).
Objet | Type de ressource | Nom | Type de dérive | Action |
---|---|---|---|---|
Utilisateur IAM |
|
| Non gérée | AUCUNE |
Clé d’accès IAM |
|
| Non gérée | AUCUNE |
Politique IAM attachée |
|
| Non gérée | AUCUNE |
Balise d’un utilisateur IAM |
|
| Gérée | RÉTABLIR |
Nous n’obtenons le résultat attendu dans aucun des cas :
L’utilisateur IAM créé manuellement et sa clé d’accès ne sont pas signalés (inutile).
La politique d’administrateur attachée manuellement à un utilisateur géré n’est pas signalée (inutile).
La balise importante ajoutée manuellement à un utilisateur géré sera supprimée (dommageable).
Nous avons donc besoin d’un autre outil pour ce type de détection et d’action.
Amélioration de la couverture
Au départ, notre couverture des ressources non gérées atteint 50 %.
1$ snyk iac describe --only-unmanaged
2
3Scanned states (1)
4Found resources not covered by IaC:
5 aws_iam_access_key:
6 - AKIASBXWQ3AYQETE6OFR
7 User: user2
8 aws_iam_policy_attachment:
9 - user1-84i30k-arn:aws:iam::aws:policy/AdministratorAccess
10 aws_iam_user:
11 - user2
12Found 6 resource(s)
13 - 50% coverage
14 - 3 resource(s) managed by Terraform
15 - 3 resource(s) not managed by Terraform
16 - 0 resource(s) found in a Terraform state but missing on the cloud provider
Améliorons ce chiffre avec notre plan d’action.
Supprimez la politique IAM pour « user1 »
Commençons par le plus urgent et le plus simple : supprimer la politique « administrateur » associée à l’utilisateur IAM géré « user1 ».
Accédez à IAM > Users > user1 (IAM > Utilisateurs > User1).
Cliquez sur Permissions (Autorisations) et supprimez « AdministratorAccess ».
1$ snyk iac describe --only-unmanaged
2Scanned states (1)
3Found resources not covered by IaC:
4 aws_iam_access_key:
5 - AKIASBXWQ3AYQETE6OFR
6 User: user2
7 aws_iam_user:
8 - user2
9Found 5 resource(s)
10 - 60% coverage
11 - 3 resource(s) managed by Terraform
12 - 2 resource(s) not managed by Terraform
Nous couvrons désormais 60 % des ressources AWS, contre 50 % précédemment.
Objet | Type de ressource | Nom | Type de dérive | Action | Statut |
---|---|---|---|---|---|
Utilisateur IAM |
|
| Non gérée | IMPORTER | |
Clé d’accès IAM |
|
| Non gérée | MODIFIER | |
Politique IAM attachée |
|
| Non gérée | SUPPRIMER | * |
Balise d’un utilisateur IAM |
|
| Gérée | AJOUTER |
Continuons.
Débloquer le pipeline de déploiement Terraform
Le pipeline est actuellement bloqué par la modification manuelle apportée aux balises de aws_iam_user.user1. Si un déploiement survient, les balises seront rétablies conformément aux valeurs du fichier HCL. La solution ? Utiliser le résultat de l’analyse des dérives de Snyk IaC pour adapter notre configuration Terraform.
Nous disposons des informations suivantes :
1Found changed resources:
2 From tfstate://terraform.tfstate
3 - user1-84i30k (aws_iam_user.user1):
4 + tags.environment: <nil> => "production"
Ces résultats nous donnent les indications suivantes :
Nous cherchons une ressource
aws_iam_user
nommée « user1 ».Cette ressource se trouve dans le fichier terraform.tfstate (très utile lorsque vous disposez de dizaines ou de centaines d’états).
Nous avons une nouvelle clé de balise nommée
environment
dont la valeur est « production ».
Actualisons notre ressource d’utilisateur IAM en ajoutant environment = "production"
pour que notre ressource se présente comme suit :
1resource "aws_iam_user" "user1" {
2 name = "user1-${random_string.prefix.result}"
3
4 tags = {
5 Name = "user1-${random_string.prefix.result}"
6 environment = "production"
7 }
8}
Nous pouvons maintenant débloquer notre pipeline de déploiement Terraform en toute sécurité :
1$ terraform apply
2No changes. Your infrastructure matches the configuration.
3Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Nous avons temporairement corrigé nos dérives « gérées » :
1$ snyk iac describe --only-managed
2Scanned states (1)
3Found 3 resource(s)
4 - 100% coverage
5Congrats! Your infrastructure is fully in sync.
Objet | Type de ressource | Nom | Type de dérive | Action | Statut |
---|---|---|---|---|---|
Utilisateur IAM |
|
| Non gérée | IMPORTER | |
Clé d’accès IAM |
|
| Non gérée | MODIFIER | |
Politique IAM attachée |
|
| Non gérée | SUPPRIMER | * |
Balise d’un utilisateur IAM |
|
| Gérée | AJOUTER | * |
Importer l’utilisateur IAM user2 et modifier sa clé
Intéressons-nous maintenant à l’utilisateur « user2 ». Nous voulons :
l’importer dans Terraform ;
modifier sa clé.
Commençons par importer l’utilisateur IAM dans Terraform. Nous avons à notre disposition une méthode très simple pour le faire :
Commençons par récupérer des informations depuis Snyk IaC :
Type de ressource | Nom |
---|---|
|
|
Comment importer une ressource aws_iam_user
? D’après la documentation officielle de Terraform : il est possible d’importer des utilisateurs IAM avec leur nom, par exemple,$ terraform import aws_iam_user.lb loadbalancer
.
La documentation indique également que le seul argument requis est le nom
. Ajoutons cette structure de base à notre fichier HCL :
1resource "aws_iam_user" "user2" {
2 name = "user2" # required
3}
Importons maintenant cet utilisateur dans Terraform :
1$ terraform import aws_iam_user.user2 user2
2aws_iam_user.user2: Importing from ID "user2"...
3aws_iam_user.user2: Import prepared!
4 Prepared aws_iam_user for import
5aws_iam_user.user2: Refreshing state... [id=user2]
6
7Import successful!
Notre couverture a-t-elle changé ? Nous allons vite le savoir :
1$ snyk iac describe --only-unmanaged
2Scanned states (1)
3Found resources not covered by IaC:
4 aws_iam_access_key:
5 - AKIASBXWQ3AYQETE6OFR
6 User: user2
7Found 5 resource(s)
8 - 80% coverage
9 - 4 resource(s) managed by Terraform
10 - 1 resource(s) not managed by Terraform
Notre couverture atteint désormais 80 % (contre 60 % précédemment) et il ne reste qu’une seule ressource à traiter.
Objet | Type de ressource | Nom | Type de dérive | Action | Statut |
---|---|---|---|---|---|
Utilisateur IAM |
|
| Non gérée | IMPORTER | * |
Clé d’accès IAM |
|
| Non gérée | MODIFIER | |
Politique IAM attachée |
|
| Non gérée | SUPPRIMER | * |
Balise d’un utilisateur IAM |
|
| Gérée | AJOUTER | * |
modifier sa clé.
Passons maintenant à cette opération. Nous savons que nous voulons modifier la clé lors de son ajout à Terraform. Commençons par ajouter la nouvelle clé au fichier HCL afin de la créer (nous pourrons par exemple la communiquer à l’équipe concernée). Nous supprimerons ensuite l’ancienne clé d’AWS.
Terraform documentation for aws_iam_access_key est une commande très simple. Nous pouvons simplement créer une ressource acceptant le nom user2 en tant qu’argument :
1resource "aws_iam_access_key" "user2" {
2 user = aws_iam_user.user2.name
3}
Le pipeline de déploiement ayant été débloqué, nous pouvons l’appliquer en toute sécurité en utilisant Terraform pour créer la nouvelle clé :
1$ terraform apply
2[...]
3Terraform will perform the following actions:
4
5 # aws_iam_access_key.user2 will be created
6 + resource "aws_iam_access_key" "user2" {
7 + create_date = (known after apply)
8 + encrypted_secret = (known after apply)
9 + id = (known after apply)
10 + key_fingerprint = (known after apply)
11 + secret = (sensitive value)
12 + ses_smtp_password_v4 = (sensitive value)
13 + status = "Active"
14 + user = "user2"
15 }
16
17Plan: 1 to add, 0 to change, 0 to destroy.
18
19aws_iam_access_key.user2: Creating...
20aws_iam_access_key.user2: Creation complete after 1s [id=AKIASBXWQ3AY4KPUNIHZ]
21
22Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Il nous reste à supprimer l’ancienne clé. Les résultats de Snyk IaC nous ont permis de déterminer que le nom de la clé est AKIASBXWQ3AYQETE6OFR
.
Voici le moyen le plus simple de la supprimer :
Rendez-vous dans IAM > Users > user2 > Security Credentials (IAM > Utilisateurs >user2 > Informations de sécurité).
Supprimez la clé
AKIASBXWQ3AYQETE6OFR
signalée par Snyk IaC en commençant par la désactiver, puis en la supprimant.
À combien se monte désormais notre couverture ?
1$ snyk iac describe --only-unmanaged
2Scanned states (1)
3Found 5 resource(s)
4 - 100% coverage
5Congrats! Your infrastructure is fully in sync.
Félicitations ! Tout est sous contrôle grâce à l’outil de détection des dérives de Snyk IaC !
Objet | Type de ressource | Nom | Type de dérive | Action | Statut |
---|---|---|---|---|---|
Utilisateur IAM |
|
| Non gérée | IMPORTER | * |
Clé d’accès IAM |
|
| Non gérée | MODIFIER | * |
Politique IAM attachée |
|
| Non gérée | SUPPRIMER | * |
Balise d’un utilisateur IAM |
|
| Gérée | AJOUTER | * |
Conclusion
Dans cet article, nous avons vu que l’outil de détection des dérives de Snyk IaC permet de détecter des ressources AWS créées manuellement, et qu’il formule ses résultats en utilisant les dénominations Terraform et en fournissant les informations dont les développeurs ont besoin pour importer ces ressources dans leur code Terraform HCL. Nous avons aussi vu brièvement que l’annulation automatique des modifications n’est pas toujours la bonne solution et qu’il est nécessaire d’utiliser un système d’alerte de dérive léger en conjonction avec le pipeline de déploiement.
Nous sommes persuadés que toute l’infrastructure doit être intégrée au code pour que les ingénieurs disposent d’informations sur sa sécurité et d’une visibilité sur les problèmes dès que possible.
C’est pour cette raison que Snyk IaC peut aider les équipes à réintégrer rapidement l’ensemble de leurs ressources s’exécutant dans leur compte AWS dans le code Terraform afin d’étendre la couverture globale par l’IaC et réduire les problèmes de sécurité. Snyk IaC permet d’apporter des corrections plus rapides en bouclant la boucle de rétroaction entre les équipes de sécurité du cloud et les équipes techniques, et en fournissant des corrections exploitables directement aux ingénieurs, dans un format qu’ils comprennent.
Une infrastructure sécurisée à la source
Snyk automatise la sécurité et la conformité de l’IaC dans les workflows, et détecte les ressources manquantes ou ayant dérivé.