![AWS Config : La conformité managée](https://blog.wescale.fr/hubfs/article-aws-config.png)
Sommaire
Déployer des ressources AWS c’est bien, s’assurer que ces dernières soient conformes à vos attentes lors de la mise en place et a posteriori, c’est encore mieux ! Et c’est d’autant plus important lorsque vous travaillez en équipe ou de manière transverse.
Prenons quelques lignes pour rappeler ce qu’est la conformité au sens strict :
"la conformité (aussi appelée compliance) consiste pour les entreprises à déployer des procédures préventives leur permettant d’éviter de s’exposer à des risques liés au non-respect de la réglementation. La mise en place d'une politique de conformité permet aux entreprises une meilleure gestion des risques et leur évite de s’exposer à des risques financiers et réputationnels."
Cette définition ne s’applique pas seulement à la réglementation définie par les autorités, elle s’applique également aux politiques internes définies par une entreprise. C’est pour cela que les personnes concernées ne sont pas uniquement les responsables d’une infrastructure qui vont mettre en place les outils nécessaires, c’est aussi le(la) développeur(se) d’une application, l’architecte Cloud, le(la) QA Analyst, le(la) Product Owner, le(la) CTO, … en résumé : toutes les personnes impliquées dans la mise à disposition d’un service, du code jusqu’à l’utilisateur.
Dans cet article, nous allons nous intéresser au service AWS Config qui va nous permettre de répondre à ce besoin en quelques minutes en se concentrant sur l’aspect infrastructure. Pour que le fonctionnement soit limpide dans votre esprit, quoi de mieux que de déployer les différentes ressources nécessaires sur un compte AWS et prendre des exemples.
Go 🚀
Présentation
AWS Config permet d’observer et d’enregistrer en continu les changements effectués sur vos ressources. Ce n’est cependant pas sa seule fonctionnalité ! Vous pourrez entre autres suivre les dépendances entre ces ressources, vous assurer de leur conformité vis-à-vis de règles prédéfinies par AWS (ou par vous-même), générer des rapports et des analyses en temps réel via des requêtes SQL… Tout cela sur un ou plusieurs comptes, une ou plusieurs régions. Vous obtiendrez alors un outil supplémentaire vous permettant de simplifier le débogage en ayant un historique complet des changements sur l’ensemble de votre infrastructure. AWS Config est également un allié de taille quand il s’agit de la sécurité de votre organisation car il peut éviter de lourds désagréments suite à une simple erreur de configuration en appliquant automatiquement une action de remédiation.
Fonctionnement
Pour illustrer nos propos, nous allons passer par trois étapes :
- Configurer AWS Config afin de récupérer et d'enregistrer les changements
- Mettre en place une règle définissant la politique de conformité
- Mettre en place une action de remédiation pour corriger manuellement ou automatiquement les ressources non conformes
Prérequis
Avant de rentrer dans le vif du sujet, nous allons devoir préparer notre environnement de travail. Vous trouverez ci-dessous la liste des outils nécessaires évoqués au fil de l’article :
- Un compte AWS
- Un utilisateur IAM (et ses informations d'identification valides)
- AWS CLI
- Terraform (backend initialisé)
⚠️ En parlant de prérequis, il est utile de souligner que le service AWS Config a un coût (voir section Liens). La facturation s’effectue à l’utilisation et est découpée en trois parties :
- Au nombre de ‘configuration item’, correspondant à un changement d’état d’une ressource ;
- Au nombre d'évaluations d’une règle prédéfinie par AWS ou par vous-même ;
- Au nombre d'évaluations d’une règle d’un Conformance pack (voir section Pour aller plus loin).
Si vous souhaitez reproduire ce tutoriel chez vous, cela ne sera donc pas gratuit (bien que le tarif soit très raisonnable). Exemple de tarification fourni par AWS :
Exemple de tarification
Configuration du service
Architecture simplifiée
Pour avoir un service fonctionnel a minima, nous allons déployer les ressources suivantes via Terraform :
- Un bucket S3 pour stocker les informations récupérées
resource "aws_s3_bucket" "awsconfig-iac-config" {
bucket = "awsconfig-iac-config"
tags = {
Name = "awsconfig-iac-config"
}
}
resource "aws_s3_bucket_acl" "awsconfig-iac-config" {
bucket = aws_s3_bucket.awsconfig-iac-config.id
acl = "private"
}
resource "aws_s3_bucket_ownership_controls" "awsconfig-iac-config" {
bucket = aws_s3_bucket.awsconfig-iac-config.id
rule {
object_ownership = "BucketOwnerEnforced"
}
}
resource "aws_s3_bucket_public_access_block" "awsconfig-iac-config" {
bucket = aws_s3_bucket.awsconfig-iac-config.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
- Un rôle IAM pour donner les droits d’accès sur le bucket S3 précédemment créé au service AWS Config
resource "aws_iam_role" "aws_config" {
name = "aws-config"
assume_role_policy = jsonencode(
{
"Version" : "2012-10-17",
"Statement" : [
{
"Action" : [
"sts:AssumeRole"
],
"Effect" : "Allow",
"Principal" : {
"Service" : [
"config.amazonaws.com"
]
}
}
]
}
)
tags = {
Name = "aws-config"
}
}
resource "aws_iam_role_policy" "aws_config_s3" {
name = "aws-config-s3"
role = aws_iam_role.aws_config.id
policy = jsonencode(
{
"Version" : "2012-10-17",
"Statement" : [
{
"Action" : [
"s3:*"
],
"Effect" : "Allow",
"Resource" : [
aws_s3_bucket.awsconfig-iac-config.arn,
"${aws_s3_bucket.awsconfig-iac-config.arn}/*"
]
}
]
}
)
}
data "aws_iam_policy" "aws_config" {
name = "AWS_ConfigRole"
}
resource "aws_iam_role_policy_attachment" "aws_config" {
role = aws_iam_role.aws_config.name
policy_arn = data.aws_iam_policy.aws_config.arn
}
- Un “recorder” pour récupérer les informations des ressources
resource "aws_config_configuration_recorder" "sandbox" {
name = "sandbox"
role_arn = aws_iam_role.aws_config.arn
}
- Un “delivery channel” pour indiquer où stocker les informations récupérées
resource "aws_config_delivery_channel" "sandbox" {
name = "sandbox"
s3_bucket_name = aws_s3_bucket.awsconfig-iac-config.id
depends_on = [
aws_config_configuration_recorder.sandbox
]
}
- Un “configuration recorder status” pour lancer l’enregistrement des changements
resource "aws_config_configuration_recorder_status" "sandbox" {
name = aws_config_configuration_recorder.sandbox.name
is_enabled = true
depends_on = [
aws_config_delivery_channel.sandbox
]
}
- Un topic SNS pour envoyer des notifications en cas d'événements
resource "aws_sns_topic" "aws_config" {
name = "aws-config"
tags = {
Name = "aws-config"
}
}
Ne reste plus qu’à créer les ressources à l’aide des commandes terraform “plan” & “apply” :
$ terraform plan -out awsconfig.tfplan
$ terraform apply awsconfig.tfplan
Vérification du bon fonctionnement
Maintenant que les ressources sont en place, vérifions si l’enregistrement des changements a bien commencé via AWS CLI :
$ aws configservice describe-configuration-recorder-status
{
"ConfigurationRecordersStatus": [
{
"name": "sandbox",
"lastStartTime": "2023-03-21T14:41:03.845000+01:00",
"recording": true,
"lastStatus": "SUCCESS",
"lastStatusChangeTime": "2023-03-22T12:41:16.176000+01:00"
}
]
}
Mise en place d’une règle
Le service étant configuré, nous allons maintenant mettre en place une règle prédéfinie par AWS. Je vous invite à consulter la section Liens de cet article pour la liste complète de ces règles.
Pour chaque règle présente dans la liste, vous trouverez les informations suivantes :
- Identifier : Identifiant unique (sous la forme S3_BUCKET_VERSIONING_ENABLED)
- Trigger type : Spécifie quand la règle doit être évaluée (Configuration changes, Periodic ou Hybrid)
- Resources types : Spécifie quelles ressources doivent être évaluées (sous la forme AWS::S3::Bucket)
- AWS Region : Région dans laquelle la règle est disponible
- Parameters (optionnel) : Paramètres pouvant être passés lors de l’évaluation de la règle
Voici le code Terraform qui va nous permettre de déployer la règle S3_BUCKET_VERSIONING_ENABLED. Comme son nom l’indique, elle va vérifier que le versioning est activé sur l’ensemble des buckets :
resource "aws_config_config_rule" "s3_versioning" {
name = "s3-versioning"
source {
owner = "AWS"
source_identifier = "S3_BUCKET_VERSIONING_ENABLED"
}
depends_on = [aws_config_configuration_recorder.sandbox]
}
Mise en place d’une action de remédiation
Si vous le souhaitez, AWS Config vous donne la possibilité de corriger manuellement ou automatiquement les ressources non conformes. Ces actions de remédiation sont à mettre en place au niveau de chaque règle. Vous aurez besoin d’un certain nombre d’informations avant la mise en place :
- target_id : Nom du document contenant les actions à effectuer
- target_type : Type du document contenant les actions à effectuer
- config_rule_name : Nom de la règle pour laquelle les actions sont à effectuer
- parameter : Paramètres pouvant être passés aux actions à effectuer
Code Terraform :
resource "aws_config_remediation_configuration" "s3_versioning" {
config_rule_name = aws_config_config_rule.s3_versioning.name
target_type = "SSM_DOCUMENT"
target_id = "AWS-ConfigureS3BucketVersioning"
parameter {
name = "BucketName"
resource_value = "RESOURCE_ID"
}
parameter {
name = "VersioningState"
static_value = "Enabled"
}
}
Attention toutefois : si cette ressource est gérée via Terraform, l’action de remédiation générera un ‘drift’ lors du prochain ‘terraform plan’ car son état ne sera plus cohérent vis-à-vis du state Terraform. Il sera alors nécessaire de corriger le code Terraform dans laquelle la ressource est déclarée pour correspondre à l’état défini par la règle AWS Config.
Résultat
En quelques minutes et lignes de code, vous obtiendrez :
- Un dashboard vous donnant accès à une vue d’ensemble des ressources de votre infrastructure respectant (ou pas) les règles que vous aurez défini.
Aperçu de la conformité
Détails d’une règle
- La possibilité de corriger manuellement ou automatiquement les ressources non conformes.
Pour aller plus loin
Règles personnalisées
Si les règles prédéfinies par AWS ne correspondent pas à vos besoins, vous avez la possibilité de définir les vôtres. Dans ce cas, il vous faudra passer par une fonction AWS Lambda ou utiliser le langage de ‘policy-as-code’ Guard (voir section Liens).
Notifications
AWS Config publie les événements survenus sur votre infrastructure vers un topic AWS SNS de votre choix. Vous aurez alors la possibilité d’envoyer ces événements vers une fonction AWS Lambda, une adresse e-mail, un channel Slack, un SMS et bien d’autres encore.
Agrégation multi compte / multi région
Grâce à ce que l’on appelle un Aggregator, il est possible de centraliser toutes les informations dans un même compte AWS. Vous avez le choix entre fournir à l’aggregator une liste de compte via leur ID ou activer le service globalement pour toute votre organisation. Vous pouvez également spécifier les régions AWS dans lesquelles l’aggregator collectera les informations.
Corformance packs
Un conformance pack est un ensemble de règles et d’actions de remédiation. À l’instar des règles, AWS fournit un certain nombre de packs. Ils sont découpés en deux catégories, ‘Operational Best Practices’ et ‘Security Best Practices’ et certains sont spécifiques à des services AWS, d'autres à des standards de sécurité. Comme précédemment, vous trouverez la liste complète dans la section Liens.
Conclusion
Avoir cette vue d’ensemble de son infrastructure est primordial pour prévenir tous désagréments opérationnels, financiers et surtout sécuritaires. AWS Config est un élément de réponse, mais cela n’est pas (et ne doit pas être) le seul. Il faut le voir comme un complément à d’autres services AWS pour vous accompagner vers une compréhension globale de votre architecture. Je ne peux que vous recommander l’usage de ce service si cela correspond à vos besoins !