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 🚀
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 :
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 :
⚠️ 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 :
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
Architecture simplifiée
Pour avoir un service fonctionnel a minima, nous allons déployer les ressources suivantes via Terraform :
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
}
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
}
resource "aws_config_configuration_recorder" "sandbox" {
name = "sandbox"
role_arn = aws_iam_role.aws_config.arn
}
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
]
}
resource "aws_config_configuration_recorder_status" "sandbox" {
name = aws_config_configuration_recorder.sandbox.name
is_enabled = true
depends_on = [
aws_config_delivery_channel.sandbox
]
}
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
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"
}
]
}
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 :
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]
}
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 :
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.
En quelques minutes et lignes de code, vous obtiendrez :
Aperçu de la conformité
Détails d’une règle
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).
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.
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.
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.
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 !