Skip to main content

Améliorer la couverture des ressources cloud pour réduire la dérive de l’infrastructure

Écrit par
Headshot of Stephane Jourdan

Stephane Jourdan

feature iac drift purple

23 mars 2022

0 minutes de lecture

Avis de dépréciation : détection de la dérive des ressources gérées

La détection de la dérive des ressources gérées, notamment snyk iac describe --only-managed and snyk iac describe --drift, est obsolète. La détection de la dérive des ressources gérées prendra fin le 30 septembre 2023.

En tant que développeurs, nous avons besoin d’une visibilité maximale sur ce qui s’exécute réellement dans nos environnements cloud afin de les sécuriser. L’infrastructure as code (IaC) aide les développeurs à automatiser leurs infrastructures cloud, pour que les déploiements dans le cloud soient contrôlés et faciles à auditer. Mais atteindre et maintenir une couverture IaC de 100 % de votre infrastructure présente de nombreux défis.

Notre sécurité dépend uniquement de ce qui est effectivement déployé et exécuté dans nos environnements cloud. Or, bien souvent, nous-mêmes, d’autres équipes ou des services authentifiés effectuons encore régulièrement de nombreuses actions manuelles. Ces modifications échappent à l’IaC et aux audits, et entraînent des problèmes tels que des erreurs de configuration et des risques de sécurité. C’est là que la gestion de la dérive devient importante : nous voulons obtenir des rapports sur les ressources qui ne sont pas encore gérées par l’IaC ou qui ont été modifiées pour une raison quelconque.

Dans cet article, nous allons montrer comment Snyk IaC aide les développeurs à détecter les ressources cloud qui ne sont pas gérées par l’infrastructure as code (IaC) (ressources non gérées), ou qui ont dérivé de leur état attendu (ressources gérées).

Configurer l’environnement

Snyk IaC répertorie les ressources détectées sous forme de ressources Terraform, ce qui vous permet de savoir facilement quelle partie du service cloud est concernée par la détection. Par exemple, un seul service Amazon API Gateway v2 se compose d’au moins 12 ressources Terraform. Grâce aux informations de détection fournies par Snyk, vous pourrez rapidement décider s’il faut annuler la modification, importer une nouvelle ressource ou simplement supprimer ce nouveau changement.

Pour suivre les étapes, vous pouvez utiliser le fichier Terraform ci-dessous afin de créer deux ressources AWS que nous utiliserons dans ce guide. Il crée un utilisateur IAM nommé « user1 » avec un suffixe aléatoire, une clé d’accès et une stratégie associée autorisant un accès en lecture seule.

Au moment de la rédaction de cet article, nous utilisions Terraform v1.1.7 avec le fournisseur AWS v3.74.2

Réutilisez la configuration HCL suivante :

main.tf

resource "random_string" "prefix" {
  length  = 6
  upper   = false
  special = false
}

resource "aws_iam_user" "user1" {
  name = "user1-${random_string.prefix.result}"

  tags = {
    Name = "user1-${random_string.prefix.result}"
    manual = "true"
  }
}

resource "aws_iam_access_key" "user1" {
  user = aws_iam_user.user1.name
}

resource "aws_iam_user_policy_attachment" "user1" {
  user       = aws_iam_user.user1.name
  policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}

Appliquez cette configuration Terraform :

$ terraform init
[...]
$ terraform apply
[...]

Vérifiez que vous avez un fichier terraform.tfstate à la racine du répertoire :

$ ls -al terraform.tfstate
-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.

Commencer sur une base vierge

Commençons par répertorier toutes les ressources cloud qui ne sont pas gérées par Terraform :

$ snyk iac describe --only-unmanaged

Vous obtiendrez probablement une longue liste de ressources qui ne sont pas gérées par Terraform. Ces informations sont déjà très utiles, mais elles ne sont pas vraiment exploitables dans notre cas. Snyk IaC intègre une fonctionnalité permettant d’ignorer des ressources en bloc en ajoutant toutes les ressources détectées au fichier de stratégie .snyk.

Ignorons toutes ces ressources non gérées existantes afin de travailler plus précisément dans un environnement contrôlé, avec uniquement les deux ressources créées précédemment :

$ snyk iac describe --only-unmanaged --json  | snyk iac update-exclude-policy

Effectuez un nouveau scan pour confirmer que votre environnement ignore désormais les dérives détectées (vous aurez tout le temps plus tard de planifier leur importation). 

$ snyk iac describe --only-unmanaged

Scanned states (1)
Found 3 resource(s)
 - 100% coverage
Congrats! Your infrastructure is fully in sync.

Nous sommes maintenant prêts à repartir d’un état vierge.

Créons une dérive avec IAM !

Nous allons maintenant créer trois types de dérive pour simuler des situations réelles :

  1. Une modification de l’utilisateur IAM existant (que nous voudrons annuler)

  2. L’ajout manuel d’une nouvelle stratégie IAM (que nous voudrons supprimer)

  3. Un nouvel utilisateur IAM (que nous voudrons améliorer)

Pour cela, accédez à la console AWS pour IAM.

Modifier l’utilisateur IAM existant en lui ajoutant une balise

  1. Sur la page des utilisateurs IAM, cliquez sur « user1 »

  2. Cliquez sur l’onglet Tags

  3. Cliquez sur le bouton Edit Tags

  4. Ajoutez une nouvelle clé (« environment ») et une nouvelle valeur (« production »)

  5. Cliquez sur Save

Associer une stratégie puissante à l’utilisateur IAM existant

  1. Sur la page des utilisateurs IAM, cliquez sur « user1 »

  2. Cliquez sur l’onglet Permissions

  3. Cliquez sur le bouton Add permissions

  4. Cliquez sur Attach existing policies directly

  5. Sélectionnez Administrator Access

  6. Cliquez sur Next: Review

  7. Confirmez en cliquant sur Add permissions

Créer manuellement un autre utilisateur IAM

  1. Sur la page des utilisateurs IAM, cliquez sur le bouton Add Users

  2. Saisissez « user2 » dans le champ User name:

  3. Sélectionnez Access key

  4. Cliquez sur le bouton Next: Permissions

  5. Ne définissez aucune autorisation ni balise

  6. Cliquez sur Create user (les identifiants affichés ne nous intéressent pas, vous pouvez donc les ignorer).

Nous sommes maintenant prêts à traiter ces différents types de modifications manuelles à l’aide de la détection de dérive de Snyk IaC.

Dérive de l’infrastructure gérée et non gérée

Voyons maintenant comment Snyk IaC détecte ces modifications, en commençant par les ressources qui ne sont tout simplement pas gérées par Terraform.

$ snyk iac describe --only-unmanaged

Scanned states (1)
Found resources not covered by IaC:
  aws_iam_access_key:
    - AKIASBXWQ3AYQETE6OFR
        User: user2
  aws_iam_policy_attachment:
    - user1-84i30k-arn:aws:iam::aws:policy/AdministratorAccess
  aws_iam_user:
    - user2
Found 6 resource(s)
 - 50% coverage
 - 3 resource(s) managed by Terraform
 - 3 resource(s) not managed by Terraform
 - 0 resource(s) found in a Terraform state but missing on the cloud provider

Ce scan a signalé les éléments suivants, en utilisant la terminologie des ressources Terraform :

  • L’utilisateur IAM « user2 » créé manuellement, avec sa clé d’accès IAM

  • La stratégie IAM associée manuellement à l’utilisateur IAM « user1 » géré par Terraform.

Vérifions maintenant les modifications apportées uniquement aux ressources gérées par Terraform et présentes dans les différents états Terraform :

$ snyk iac describe –only-managed
Scanned states (1)
Found changed resources:
  From tfstate://terraform.tfstate
    - user1-84i30k (aws_iam_user.user1):
        + tags.environment: <nil> => "production"
Found 5 resource(s)
 - 100% coverage
 - 5 resource(s) managed by Terraform
     - 1/5 resource(s) out of sync with Terraform state
 - 0 resource(s) found in a Terraform state but missing on the cloud provider

Ce scan a produit un résultat très différent et a pris beaucoup plus de temps (36 s contre 9 s pour le mode de scan « non géré »).

Ce résultat nous apprend que l’utilisateur IAM nommé « user1-84i30k », que nous trouvons dans le HCL (en tant que ressource) sous le nom « user1 », comporte une balise nommée « environment » dont la valeur est « production ».

Plan d’action

L’outil de détection de dérive de Snyk nous a aidés à découvrir quatre écarts inattendus entre nos attentes et la réalité. Pour les besoins de cet article, supposons que l’équipe décide ce qui suit :

  • L’utilisateur IAM « user2 » est utilisé en production et doit être importé dans Terraform.

  • La clé d’accès IAM de « user2 » doit être renouvelée pour des raisons de sécurité.

  • « user1 » ne doit en aucun cas être administrateur.

  • La nouvelle balise de « user1 » répond à un besoin et doit être importée dans Terraform.

Élément

Type de ressource

Nom

Type de dérive

Action

Un utilisateur IAM

aws_iam_user

user2

Non géré

IMPORTER

Une clé d’accès IAM

aws_iam_access_key

AKIASBXWQ3AYQETE6OFR

Non gérée

RENOUVELER

Une stratégie IAM associée

aws_iam_policy_attachment

arn:aws:iam::aws:policy/AdministratorAccess

Non gérée

SUPPRIMER

Une balise sur un utilisateur IAM

aws_iam_user

tags.environment

Gérée

IMPORTER

Les pipelines de déploiement ne sont pas une solution de remédiation

Nous avons mis en place un excellent pipeline de déploiement Terraform. Au prochain déclenchement de terraform apply, nous pourrions nous attendre à ce que tout revienne à la normale.

Dans ce cas, que fera Terraform ? Une tâche de déploiement :

$ terraform apply
Terraform will perform the following actions:

  # aws_iam_user.user1 will be updated in-place
  ~ resource "aws_iam_user" "user1" {
        id            = "user1-84i30k"
        name          = "user1-84i30k"
      ~ tags          = {
          - "environment" = "production" -> null
            # (1 unchanged element hidden)
        }
[...]

Plan: 0 to add, 1 to change, 0 to destroy.

Terraform n’a jamais été conçu pour détecter les ressources créées ou associées manuellement. Il rétablira simplement les ressources modifiées à leur état initial (ce que nous ne souhaitons pas dans cette situation).

Élément

Type de ressource

Nom

Type de dérive

Action

Un utilisateur IAM

aws_iam_user

user2

Non géré

AUCUNE

Une clé d’accès IAM

aws_iam_access_key

AKIASBXWQ3AYQETE6OFR

Non gérée

AUCUNE

Une stratégie IAM associée

aws_iam_policy_attachment

arn:aws:iam::aws:policy/AdministratorAccess

Non gérée

AUCUNE

Une balise sur un utilisateur IAM

aws_iam_user

tags.environment

Gérée

RÉTABLIR

Dans aucun de ces cas, nous n’obtenons l’aide attendue :

  • L’utilisateur IAM créé manuellement et sa clé d’accès ne sont pas signalés (inutile)

  • La stratégie Administrator associé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 (préjudiciable)

Ce type de détection et de travail nécessite un autre type d’outil.

Améliorer notre couverture

Nous commençons avec une couverture de 50 % des ressources non gérées :

$ snyk iac describe --only-unmanaged

Scanned states (1)
Found resources not covered by IaC:
  aws_iam_access_key:
    - AKIASBXWQ3AYQETE6OFR
        User: user2
  aws_iam_policy_attachment:
    - user1-84i30k-arn:aws:iam::aws:policy/AdministratorAccess
  aws_iam_user:
    - user2
Found 6 resource(s)
 - 50% coverage
 - 3 resource(s) managed by Terraform
 - 3 resource(s) not managed by Terraform
 - 0 resource(s) found in a Terraform state but missing on the cloud provider

Améliorons-la en suivant le plan de l’équipe.

Supprimer la stratégie IAM de « user1 »

Commençons par l’action la plus urgente et la plus simple : supprimer la stratégie « Administrator » de l’utilisateur IAM géré « user1 » :

  • Accédez à IAM > Users > « user1 »

  • Cliquez sur Permissions > supprimez « AdministratorAccess »

$ snyk iac describe --only-unmanaged
Scanned states (1)
Found resources not covered by IaC:
  aws_iam_access_key:
    - AKIASBXWQ3AYQETE6OFR
        User: user2
  aws_iam_user:
    - user2
Found 5 resource(s)
 - 60% coverage
 - 3 resource(s) managed by Terraform
 - 2 resource(s) not managed by Terraform

Nous couvrons désormais 60 % de nos ressources AWS, contre 50 % auparavant.

Élément

Type de ressource

Nom

Type de dérive

Action

État

Un utilisateur IAM

aws_iam_user

user2

Non géré

IMPORTER

Une clé d’accès IAM

aws_iam_access_key

AKIASBXWQ3AYQETE6OFR

Non gérée

RENOUVELER

Une stratégie IAM associée

aws_iam_policy_attachment

arn:aws:iam::aws:policy/AdministratorAccess

Non gérée

SUPPRIMER

*

Une balise sur un utilisateur IAM

aws_iam_user

tags.environment

Gérée

AJOUTER

Continuons.

Débloquer le pipeline de déploiement Terraform

Le pipeline est actuellement bloqué par cette modification manuelle des balises de aws_iam_user.user1. Si un déploiement est effectué, les balises reviendront à celles définies dans le HCL. Quelle est donc la solution ? Utiliser le résultat de détection de dérive de Snyk IaC pour adapter notre configuration Terraform.

Voici les informations dont nous disposons :

Found changed resources:
  From tfstate://terraform.tfstate
    - user1-84i30k (aws_iam_user.user1):
        + tags.environment: <nil> => "production"

Ce résultat nous apprend que :

  • Nous recherchons une ressource nommée « user1 » de type aws_iam_user

  • Cette ressource se trouve dans terraform.tfstate (très utile lorsque vous avez des dizaines ou des centaines d’états)

  • Une nouvelle clé de balise nommée environment a pour valeur « production ».

Mettons à jour la ressource de notre utilisateur IAM en ajoutant simplement environment = "production", afin qu’elle ressemble désormais à ceci :

resource "aws_iam_user" "user1" {
 name = "user1-${random_string.prefix.result}"

 tags = {
   Name = "user1-${random_string.prefix.result}"
   environment = "production"
 }
}

Nous pouvons maintenant débloquer sans risque notre pipeline de déploiement Terraform :

$ terraform apply
No changes. Your infrastructure matches the configuration.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Nous avons corrigé nos dérives « gérées » pour le moment :

$ snyk iac describe --only-managed
Scanned states (1)
Found 3 resource(s)
 - 100% coverage
Congrats! Your infrastructure is fully in sync.

Élément

Type de ressource

Nom

Type de dérive

Action

État

Un utilisateur IAM

aws_iam_user

user2

Non géré

IMPORTER

Une clé d’accès IAM

aws_iam_access_key

AKIASBXWQ3AYQETE6OFR

Non gérée

RENOUVELER

Une stratégie IAM associée

aws_iam_policy_attachment

arn:aws:iam::aws:policy/AdministratorAccess

Non gérée

SUPPRIMER

*

Une balise sur un utilisateur IAM

aws_iam_user

tags.environment

Gérée

AJOUTER

*

Importer et renouveler la clé IAM de user2

Occupons-nous maintenant du cas de « user2 ». Nous voulons :

  • L’importer dans Terraform

  • Renouveler la clé

Commençons par importer l’utilisateur IAM dans Terraform. Voici une méthode simple pour le faire.

Commencez par recueillir les informations fournies par Snyk IaC :

Type de ressource

Nom

aws_iam_user

user2

Comment importer une aws_iam_user resource ? Selon la documentation officielle de Terraform : les utilisateurs IAM peuvent être importés à l’aide de leurnom, par exemple : $ terraform import aws_iam_user.lb loadbalancer.

Nous pouvons également lire que le seul argument obligatoire est name. Ajoutons donc cette structure de base à notre fichier HCL :

resource "aws_iam_user" "user2" {
 name = "user2" # required
}

Importons maintenant cet utilisateur dans Terraform :

$ terraform import aws_iam_user.user2 user2
aws_iam_user.user2: Importing from ID "user2"...
aws_iam_user.user2: Import prepared!
  Prepared aws_iam_user for import
aws_iam_user.user2: Refreshing state... [id=user2]

Import successful!

Comment notre couverture a-t-elle évolué ? Voyons cela :

$ snyk iac describe --only-unmanaged
Scanned states (1)
Found resources not covered by IaC:
  aws_iam_access_key:
    - AKIASBXWQ3AYQETE6OFR
        User: user2
Found 5 resource(s)
 - 80% coverage
 - 4 resource(s) managed by Terraform
 - 1 resource(s) not managed by Terraform

Nous atteignons désormais une couverture de 80 % (contre 60 % auparavant) et il ne reste qu’une seule ressource.

Élément

Type de ressource

Nom

Type de dérive

Action

État

Un utilisateur IAM

aws_iam_user

user2

Non géré

IMPORTER

*

Une clé d’accès IAM

aws_iam_access_key

AKIASBXWQ3AYQETE6OFR

Non gérée

RENOUVELER

Une stratégie IAM associée

aws_iam_policy_attachment

arn:aws:iam::aws:policy/AdministratorAccess

Non gérée

SUPPRIMER

*

Une balise sur un utilisateur IAM

aws_iam_user

tags.environment

Gérée

AJOUTER

*

Renouveler la clé

Occupons-nous maintenant de cette tâche. Nous voulons renouveler la clé tout en l’ajoutant à Terraform. Commençons par ajouter la nouvelle clé au HCL pour en créer une (afin de pouvoir la transmettre à l’équipe concernée, par exemple), puis supprimons simplement l’ancienne clé d’AWS.

La documentation Terraform pour aws_iam_access_key est très claire : il suffit de créer une ressource en indiquant le nom de user2 comme argument :

resource "aws_iam_access_key" "user2" {
 user = aws_iam_user.user2.name
}

Le pipeline de déploiement ayant été débloqué, nous pouvons appliquer sans risque cette configuration avec Terraform afin de créer une nouvelle clé :

$ terraform apply 
[...]
Terraform will perform the following actions:

  # aws_iam_access_key.user2 will be created
  + resource "aws_iam_access_key" "user2" {
      + create_date          = (known after apply)
      + encrypted_secret     = (known after apply)
      + id                   = (known after apply)
      + key_fingerprint      = (known after apply)
      + secret               = (sensitive value)
      + ses_smtp_password_v4 = (sensitive value)
      + status               = "Active"
      + user                 = "user2"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

aws_iam_access_key.user2: Creating...
aws_iam_access_key.user2: Creation complete after 1s [id=AKIASBXWQ3AY4KPUNIHZ]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Il nous reste l’ancienne clé à supprimer. D’après les informations du résultat Snyk IaC, le nom de la clé est AKIASBXWQ3AYQETE6OFR.

La méthode la plus simple pour supprimer cette clé consiste à :

  • Accéder à IAM > Users > user2 > Security Credentials

  • Supprimez la clé nommée AKIASBXWQ3AYQETE6OFR, signalée par Snyk IaC, en la désactivant puis en la supprimant.

À quoi ressemble maintenant notre couverture ?

$ snyk iac describe --only-unmanaged
Scanned states (1)
Found 5 resource(s)
 - 100% coverage
Congrats! Your infrastructure is fully in sync.

Félicitations ! Tout est de nouveau sous contrôle grâce à la détection de dérive de Snyk IaC !

Élément

Type de ressource

Nom

Type de dérive

Action

État

Un utilisateur IAM

aws_iam_user

user2

Non géré

IMPORTER

*

Une clé d’accès IAM

aws_iam_access_key

AKIASBXWQ3AYQETE6OFR

Non gérée

RENOUVELER

*

Une stratégie IAM associée

aws_iam_policy_attachment

arn:aws:iam::aws:policy/AdministratorAccess

Non gérée

SUPPRIMER

*

Une balise sur un utilisateur IAM

aws_iam_user

tags.environment

Gérée

AJOUTER

*

Pour conclure

Dans cet article, nous avons montré comment la détection de dérive de Snyk IaC permet de découvrir les ressources AWS créées manuellement et de présenter les résultats selon la terminologie Terraform, avec les informations nécessaires pour aider les développeurs à importer ces ressources dans leur code HCL Terraform. Nous avons également vu brièvement que le rétablissement automatique des modifications n’est pas toujours souhaitable et qu’un système léger d’alertes de détection de dérive doit compléter le pipeline de déploiement.

Nous sommes convaincus que toute l’infrastructure devrait être définie sous forme de code, afin que les ingénieurs puissent obtenir rapidement des retours de sécurité et une visibilité sur les problèmes.

C’est pourquoi Snyk IaC aide les équipes à réintégrer rapidement dans le code Terraform toutes les ressources réellement utilisées dans leur compte AWS, afin d’accroître la couverture IaC globale et de réduire les problèmes de sécurité. Snyk IaC accélère les corrections en bouclant la boucle de rétroaction entre les équipes de sécurité cloud et d’ingénierie, et en transmettant directement aux ingénieurs des correctifs exploitables, dans des termes qui leur parlent.

Sécurisez votre infrastructure dès la source

Snyk automatise la sécurité et la conformité de l’IaC dans vos workflows, et détecte les ressources dont la configuration a dérivé ou qui sont manquantes.