Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Checkov : scanner l'infrastructure as code

Par mis à jour le

Améliorer cette page

Checkov est le scanner open source d'infrastructure as code (IaC) maintenu par Prisma Cloud (Palo Alto Networks), sous licence Apache 2.0. Il lit vos fichiers Terraform, Kubernetes, Dockerfile, Ansible ou CloudFormation et signale les mauvaises configurations avant qu'elles soient déployées : bucket public, SSH ouvert au monde, conteneur privilégié. Cette leçon s'adresse à un DevOps qui veut le brancher en CI sans se noyer dans ses résultats.

Tout est mesuré sur Checkov 3.3.22 : 25 échecs sur quatre ressources Terraform, 22 sur un seul Deployment, et des secrets en clair qui passent sans alerte dans chacun des quatre fichiers d'exemple. Savoir ce que Checkov ne voit pas compte autant que savoir lire ce qu'il trouve.

  • Installer Checkov en version épinglée et lancer un premier scan
  • Lire un résultat et séparer les vrais risques des règles de confort
  • Repérer les angles morts, secrets compris, avant de s'y fier
  • Faire échouer un job CI sur les règles choisies, pas sur la sévérité
  • Gérer les faux positifs et écrire une règle maison qui se charge
  • Produire la preuve de SOCLE-INT-VER-2, l'analyse de configuration IaC

Checkov est un analyseur statique (SAST) spécialisé dans l'infrastructure as code : il lit le code, sans rien déployer ni interroger un cloud. Chaque règle (un « check ») porte un identifiant stable, comme CKV_AWS_24, et vérifie une bonne pratique précise. Il peut aussi relier des ressources entre elles grâce à une analyse en graphe : les règles préfixées CKV2_ regardent par exemple si un bucket S3 a un blocage d'accès public déclaré dans une autre ressource.

La commande checkov --list de la version 3.3.22 recense 1361 identifiants de règles distincts. Le chiffre de « plus de 800 » qui circule encore date des versions 2. La répartition montre où porte l'effort : Terraform écrase tout le reste, et un framework plus récent comme GitHub Actions n'a qu'une poignée de règles.

FrameworkRègles (Checkov 3.3.22)
Terraform1144
ARM / Bicep (Azure)173 / 167
CloudFormation139
Kubernetes119
Ansible29
Dockerfile28
OpenAPI21
Secrets18
GitHub Actions8
GitLab CI3

Une même règle peut servir plusieurs formats, d'où une somme supérieure au total. Pour les pipelines CI, ces chiffres disent l'essentiel : un workflow GitHub Actions se vérifie mieux avec des outils dédiés comme zizmor, vu dans la leçon sur la confiance implicite des pipelines.

Un rapport Checkov vert ne prouve pas qu'une infrastructure est sûre. Il prouve que le code ne contient aucune des configurations que ses règles connaissent. Trois limites reviennent dans toute la leçon. Il ne voit que le code, pas l'état réel du cloud ni ce qu'un opérateur a modifié à la main. Il ne lit pas les vulnérabilités des paquets d'une image, travail de Trivy. Et sa détection de secrets, mesurée plus bas, laisse passer les mots de passe ordinaires.

Checkov est un paquet Python : on l'installe avec pipx pour l'isoler du reste du système, en fixant la version. L'image Docker officielle évite d'installer Python, et se fige par digest : depuis l'incident de Trivy en 2026, un scanner se traite comme toute dépendance, jamais en latest.

Fenêtre de terminal
# Installation isolée, version figée
pipx install "checkov==3.3.22"
checkov --version
# 3.3.22
# Ou sans Python, par l'image figée par digest
docker run --rm -v "$PWD":/src -w /src \
bridgecrew/checkov:3.3.22@sha256:617c76e3f9b1f7907ebca9abb6b9d746844edcb48e9bd775e4692c69c1c6ac47 \
-d . --compact --quiet

La sortie de checkov --version doit afficher exactement la version demandée. Le paquet Homebrew existe aussi sur macOS, mais il suit la dernière version publiée, ce qui ne convient pas à une CI reproductible.

Le plus simple pour comprendre Checkov est de lui donner un fichier dont on connaît les fautes. Celui-ci est valide pour Terraform : terraform validate l'accepte. Il contient pourtant quatre erreurs classiques, marquées en commentaire, et un mot de passe en clair.

terraform/main.tf
# ❌ Bucket S3 avec accès public
resource "aws_s3_bucket" "bad_bucket" {
bucket = "factures-clients-prod"
acl = "public-read" # Problème : bucket accessible publiquement
}
# ❌ Instance EC2 sans IMDSv2
resource "aws_instance" "bad_instance" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
# Pas de metadata_options : IMDSv1 reste actif, exploitable par SSRF
}
# ❌ Security Group SSH ouvert au monde
resource "aws_security_group" "bad_sg" {
name = "allow-all-ssh"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Problème : SSH ouvert à Internet
}
}
# ❌ RDS accessible publiquement avec mot de passe en clair
resource "aws_db_instance" "bad_rds" {
identifier = "facturation"
engine = "mysql"
instance_class = "db.t3.micro"
username = "admin"
password = "SuperSecret123!" # Problème : secret dans le code
publicly_accessible = true # Problème : BDD exposée à Internet
}

Deux options rendent la sortie lisible dans un terminal. --compact retire l'extrait de code affiché sous chaque résultat, et --quiet masque les règles réussies : sans elle, Checkov liste aussi chaque contrôle passé. Le scan sort avec le code 1 dès qu'une règle échoue, ce qui suffit à faire échouer un job CI.

Fenêtre de terminal
$ checkov -d terraform --compact --quiet
terraform scan results:
Passed checks: 14, Failed checks: 25, Skipped checks: 0
Check: CKV_AWS_79: "Ensure Instance Metadata Service Version 1 is not enabled"
FAILED for resource: aws_instance.bad_instance
File: /main.tf:8-12
Check: CKV_AWS_24: "Ensure no security groups allow ingress from 0.0.0.0:0 to port 22"
FAILED for resource: aws_security_group.bad_sg
File: /main.tf:15-23
Check: CKV_AWS_17: "Ensure all data stored in RDS is not publicly accessible"
FAILED for resource: aws_db_instance.bad_rds
File: /main.tf:26-33
Check: CKV_AWS_20: "S3 Bucket has an ACL defined which allows public READ access."
FAILED for resource: aws_s3_bucket.bad_bucket
File: /main.tf:2-5
...
$ echo $?
1

Les quatre erreurs visées sont trouvées, chacune par une règle nommée. Chaque bloc porte aussi une ligne Guide: vers la page de remédiation de Prisma Cloud, retirée ici pour la lisibilité.

Lire un résultat : risque réel ou règle de confort ?

Section intitulée « Lire un résultat : risque réel ou règle de confort ? »

Sur 25 échecs, quatre seulement correspondent aux fautes visées. Les 21 autres sont des bonnes pratiques que ce fichier n'aborde pas : réplication inter-régions du bucket (CKV_AWS_144), Multi-AZ de la base (CKV_AWS_157), journalisation, cycle de vie. Elles ne se valent pas : un bucket public expose des données aujourd'hui, une réplication absente coûte seulement en cas de sinistre régional. Le travail de lecture consiste à classer, pas à tout corriger.

RègleCe qu'elle vérifieRisque si on l'ignore
CKV_AWS_20ACL public-read sur un bucketDonnées lisibles par tout Internet
CKV_AWS_24SSH ouvert depuis 0.0.0.0/0Force brute, accès non autorisé
CKV_AWS_17publicly_accessible = true sur RDSBase exposée directement
CKV_AWS_79IMDSv1 actif sur EC2Vol des identifiants de l'instance par SSRF
CKV_AWS_144Réplication inter-régionsPerte en cas de panne régionale, pas d'exposition

Le mot de passe en clair de la base, lui, ne déclenche aucune règle. La détection de secrets cherche des formats connus et des chaînes à forte entropie : SuperSecret123! ne ressemble à aucun des deux. C'est le premier angle mort à retenir.

Kubernetes, Dockerfile, Ansible : ce que les règles voient

Section intitulée « Kubernetes, Dockerfile, Ansible : ce que les règles voient »

Les autres formats suivent le même principe, avec un piège commun : un nombre élevé de règles réussies ne dit rien de la sécurité du fichier. Checkov applique tout son jeu de règles à chaque ressource, y compris les contrôles du plan de contrôle Kubernetes qui n'ont aucun sens pour un Deployment.

Ce manifeste cumule les configurations qui offrent à un conteneur un accès complet à son nœud : réseau et processus de l'hôte partagés, mode privilégié, racine du système de fichiers montée. Il porte aussi un secret en variable d'environnement.

k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: insecure-app
namespace: default # ❌ Utiliser le namespace default
spec:
replicas: 1
selector:
matchLabels:
app: insecure-app
template:
metadata:
labels:
app: insecure-app
spec:
hostNetwork: true # ❌ Partage le réseau du host
hostPID: true # ❌ Voit les processus du host
containers:
- name: app
image: nginx:latest # ❌ Tag "latest" non reproductible
securityContext:
privileged: true # ❌ Conteneur privilégié = root sur le host
env:
- name: DB_PASSWORD
value: "secret123" # ❌ Secret dans les variables d'env
volumeMounts:
- mountPath: /host
name: host-volume
volumes:
- name: host-volume
hostPath:
path: / # ❌ Monte la racine du host

Le scan remonte 22 échecs pour 67 réussites, et les plus graves sont bien là. Attention aux identifiants : hostPID déclenche CKV_K8S_17, pas CKV_K8S_1, qui porte le même intitulé mais ne vise que les anciennes PodSecurityPolicy, retirées de Kubernetes.

Fenêtre de terminal
$ checkov -f k8s/deployment.yaml --compact --quiet
kubernetes scan results:
Passed checks: 67, Failed checks: 22, Skipped checks: 0
Check: CKV_K8S_17: "Containers should not share the host process ID namespace"
Check: CKV_K8S_19: "Containers should not share the host network namespace"
Check: CKV_K8S_16: "Container should not be privileged"
Check: CKV_K8S_14: "Image Tag should be fixed - not latest or blank"
Check: CKV_K8S_43: "Image should use digest"
...

Deux fautes du manifeste ne déclenchent pourtant aucune règle. Le montage hostPath de la racine / passe : la seule règle proche, CKV_K8S_27, ne vise que le socket Docker. Et DB_PASSWORD en clair dans env.value passe aussi : CKV_K8S_35 ne concerne que les secrets Kubernetes injectés en variables. Ces deux angles morts relèvent d'un contrôleur d'admission et des Pod Security Standards (les trois niveaux de restriction que Kubernetes sait imposer aux pods), vus dans le module sur les conteneurs.

Les règles Dockerfile portent sur des choix de construction : image de base flottante, instruction ADD, absence d'utilisateur non-root. Ce fichier en réunit plusieurs, et cache une clé d'API dans un ENV, lisible par quiconque récupère l'image.

docker/Dockerfile
# ❌ Tag "latest" : version non reproductible
FROM python:latest
# ❌ MAINTAINER déprécié (utiliser LABEL)
MAINTAINER dev@example.com
WORKDIR /app
# ❌ ADD peut extraire des archives et télécharger depuis Internet
ADD https://example.com/config.tar.gz /app/
ADD . /app/
RUN pip install -r requirements.txt
# ❌ Expose le port SSH
EXPOSE 22 80
# ❌ Secret dans une variable d'environnement (visible dans l'image)
ENV API_KEY=sk-secret-12345
# ❌ Pas de USER ni de HEALTHCHECK
CMD ["python", "app.py"]

Le scan donne 7 échecs. Les règles d'absence, comme CKV_DOCKER_3 qui exige un USER, visent le fichier entier (Dockerfile. sans suffixe), faute de ligne à désigner.

Fenêtre de terminal
$ checkov -f docker/Dockerfile --compact --quiet
dockerfile scan results:
Passed checks: 26, Failed checks: 7, Skipped checks: 0
Check: CKV_DOCKER_7: "Ensure the base image uses a non latest version tag"
Check: CKV_DOCKER_6: "Ensure that LABEL maintainer is used instead of MAINTAINER (deprecated)"
Check: CKV_DOCKER_4: "Ensure that COPY is used instead of ADD in Dockerfiles"
Check: CKV_DOCKER_4: "Ensure that COPY is used instead of ADD in Dockerfiles"
Check: CKV_DOCKER_1: "Ensure port 22 is not exposed"
Check: CKV_DOCKER_2: "Ensure that HEALTHCHECK instructions have been added to container images"
Check: CKV_DOCKER_3: "Ensure that a user for the container has been created"

La clé API_KEY=sk-secret-12345 n'apparaît nulle part. CKV_DOCKER_7 ne se déclenche que sur latest : un tag versionné sans digest, comme python:3.14, le satisfait. La leçon sur les bonnes pratiques Dockerfile couvre ce que ces règles laissent de côté.

Le jeu de règles Ansible est court, 29 règles, centrées sur les options qui désactivent une vérification. Ce playbook en contient deux, force et validate_certs, plus un mode: "0777" et deux secrets en variables.

ansible/playbook.yml
---
- name: Configuration serveur web
hosts: webservers
become: true
vars:
# ❌ Mot de passe en clair dans le code
db_password: "SuperSecret123!"
api_key: "sk-1234567890abcdef"
tasks:
- name: Install packages with force
ansible.builtin.apt:
name: nginx
state: present
force: true # ❌ Contourne la vérification de signature
- name: Download file
ansible.builtin.get_url:
url: https://example.com/config.tar.gz
dest: /tmp/config.tar.gz
validate_certs: false # ❌ Désactive la validation TLS
- name: Set insecure permissions
ansible.builtin.file:
path: /etc/app/config
mode: "0777" # ❌ Permissions trop permissives

Le scan produit deux rapports pour un seul fichier : ansible pour les modules et secrets pour le texte. La détection de secrets tourne sur tout fichier qu'elle sait lire, quel que soit le framework.

Fenêtre de terminal
$ checkov -f ansible/playbook.yml --compact --quiet
secrets scan results:
Passed checks: 0, Failed checks: 1, Skipped checks: 0
Check: CKV_SECRET_6: "Base64 High Entropy String"
File: /ansible/playbook.yml:8-9
ansible scan results:
Passed checks: 2, Failed checks: 2, Skipped checks: 0
Check: CKV_ANSIBLE_6: "Ensure that the force parameter is not used, as it disables signature validation ..."
Check: CKV_ANSIBLE_2: "Ensure that certificate validation isn't disabled with get_url"

Seule l'api_key, chaîne aléatoire, est trouvée. Le db_password passe, et le mode: "0777" aussi : aucune des 29 règles Ansible ne lit la valeur d'une permission. Ce contrôle reste à la relecture de code, ou à une règle maison comme celles de la fin de cette leçon.

Checkov embarque 18 règles de secrets : formats connus (CKV_SECRET_2 pour une clé AWS AKIA…, CKV_SECRET_13 pour une clé privée, CKV_SECRET_14 pour Slack) et deux règles d'entropie, en base64 (CKV_SECRET_6) et en hexadécimal (CKV_SECRET_19). Ce mécanisme rate deux catégories, mesurées sur la version 3.3.22.

La première est le mot de passe humain : SuperSecret123!, secret123 ou sk-secret-12345 n'ont ni format connu ni entropie suffisante, et aucun des quatre fichiers précédents ne les a signalés. La seconde est plus surprenante : par défaut, Checkov ne lit les secrets que dans certains types de fichiers. Une vraie clé AWS dans un credentials.ini, ou un jeton GitHub dans un .env, passe sans alerte.

Fenêtre de terminal
$ checkov -d sec --framework secrets --compact --quiet
# aucun résultat : .ini et .env ne sont pas lus
$ checkov -d sec --framework secrets --compact --quiet --enable-secret-scan-all-files
Passed checks: 0, Failed checks: 3, Skipped checks: 0
Check: CKV_SECRET_6: "Base64 High Entropy String"
File: /.env:1-2
Check: CKV_SECRET_2: "AWS Access Key"
File: /credentials.ini:1-2
Check: CKV_SECRET_2: "AWS Access Key"
File: /credentials.ini:2-3

Le même contenu renommé en config.yaml est trouvé sans l'option. La conclusion pratique : Checkov ne remplace pas un détecteur de secrets dédié comme gitleaks, lancé en pré-commit et en CI, vu dans la leçon sur les secrets en CI/CD.

Checkov sort en code 1 dès qu'une règle échoue et en code 0 sinon : sur un vieux projet, le premier job casse donc à coup sûr. Trois options règlent ce comportement, et elles ont été mesurées sur le Dockerfile précédent.

OptionEffetCode de sortie mesuré
aucuneÉchec dès une règle en faute1
--soft-failRapport complet, jamais d'échec0
--soft-fail-on CKV_DOCKER_2,CKV_DOCKER_3Ces deux règles ne bloquent plus, les autres si1 (5 autres échecs)
--soft-fail --hard-fail-on CKV_DOCKER_8Seule la règle listée bloque0 (elle passe)

Le couple --soft-fail et --hard-fail-on est le plus utile pour démarrer : on bloque sur une liste courte de règles graves, comme CKV_AWS_20, CKV_AWS_24 ou CKV_K8S_16, et on laisse le reste en rapport. On allonge la liste à mesure que la dette baisse.

L'action officielle bridgecrewio/checkov-action exécute Checkov dans son image officielle. Elle se fige sur le SHA de son commit, comme toute action : sa version v12.3128.0 exécute Checkov 3.3.22. Le rapport SARIF (format standard de résultats d'analyse) part dans l'onglet Code Scanning du dépôt, même quand le scan échoue, grâce à if: always().

.github/workflows/checkov.yml
name: checkov
on:
pull_request:
paths:
- "infra/**"
permissions: {}
jobs:
checkov:
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Scanner l'IaC
uses: bridgecrewio/checkov-action@cc0e17d456ef1713bbfd963ebac19dc776775cb2 # v12.3128.0
with:
directory: infra/
framework: terraform
output_format: cli,sarif
output_file_path: console,results.sarif
- name: Publier dans Code Scanning
if: always()
uses: github/codeql-action/upload-sarif@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
with:
sarif_file: results.sarif

Ce workflow passe actionlint, zizmor 1.30.0 et poutine 1.1.6 sans aucun constat. Une limite reste à connaître : l'action désigne son image par tag (ghcr.io/bridgecrewio/checkov:3.3.22), pas par digest. Pour une garantie complète, on lance l'image figée par digest dans un pas run.

Une règle peut être fausse dans votre contexte : un bucket qui héberge un site public doit être public. Checkov offre trois mécanismes, du plus ciblé au plus large. Le premier, la suppression en ligne, est le seul qui reste attaché au code et passe en revue avec lui.

Chaque format a sa syntaxe de commentaire, toujours suivie d'une justification. Les trois formes suivantes ont été vérifiées : chaque scan compte la règle en Skipped checks: 1 ou 2 au lieu d'un échec.

resource "aws_s3_bucket" "site" {
# checkov:skip=CKV_AWS_20: site statique public par conception
bucket = "site-vitrine"
acl = "public-read"
}
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: recette
annotations:
checkov.io/skip1: CKV_K8S_40=UID imposé par l'image de test
spec:
containers:
- name: app
image: nginx:1.29.1@sha256:8adbdcb969e2676478ee2c7ad333956f0c8e0e4c5a7463f4611d7a2e7a7ff5dc
# checkov:skip=CKV_DOCKER_2: la sonde de santé est portée par le manifeste Kubernetes
FROM ubuntu:24.04@sha256:008173c23f95b170204355c12626cb5a965d779a7e1283b09e9cffbb1bf33ca3
# checkov:skip=CKV_DOCKER_4: l'archive doit être décompressée à la copie
ADD app.tar.gz /opt/app/
RUN useradd --uid 1000 --create-home appuser
USER appuser

Sur Kubernetes, l'annotation se numérote (skip1, skip2…) pour en poser plusieurs. En ligne de commande, --skip-check CKV_AWS_20,CKV_AWS_21 retire des règles pour tout le scan, sans trace dans le code : à réserver aux règles que l'équipe juge hors sujet partout.

Sur un projet existant, --create-baseline enregistre les échecs du moment dans un fichier .checkov.baseline, posé dans le dossier scanné. Les scans suivants avec --baseline ne signalent plus que les nouveaux échecs. Mesuré : après ajout d'un Security Group RDP ouvert au Terraform de départ, le scan avec baseline ne remonte que ses 3 échecs, au lieu de 28.

Fenêtre de terminal
checkov -d terraform --create-baseline
checkov -d terraform --baseline terraform/.checkov.baseline --compact --quiet

La baseline fige une dette, elle ne la règle pas. On la versionne, et on la régénère seulement quand des corrections l'ont réduite.

Plutôt que de répéter les options, un fichier .checkov.yaml posé dans le dossier courant est chargé automatiquement, sans option. Mesuré : avec skip-check: [CKV_DOCKER_2, CKV_DOCKER_3] dans ce fichier, un simple checkov -d . tombe de 7 à 5 échecs. C'est pratique et piégeux à la fois, comme le trivy.yaml de la leçon précédente : un fichier oublié dans un dépôt filtre en silence le rapport.

.checkov.yaml
directory:
- infra
framework:
- terraform
- kubernetes
- dockerfile
skip-check:
- CKV_AWS_144 # réplication inter-régions : hors budget, décision du 2026-10-01
compact: true
quiet: true

Chaque clé reprend une option de la ligne de commande sans le double tiret. La commande checkov -d . --skip-check CKV_DOCKER_7 --create-config .checkov.yaml écrit ce fichier à partir des options du moment, et --show-config affiche la configuration réellement appliquée. Évitez la clé check: : renseignée, elle limite le scan aux seules règles listées.

Checkov écrit plusieurs formats en un passage : cli, json, sarif, junitxml, csv et cyclonedx, entre autres. Le comportement de --output-file-path change selon ce qu'on lui donne, et c'est mesuré : une liste de chemins, un par format, écrit des fichiers ; un seul chemin pour plusieurs formats est traité comme un dossier, rempli de results_json.json et results_sarif.sarif.

Fenêtre de terminal
# Un fichier par format : console pour le cli, checkov.xml pour JUnit
checkov -d infra -o cli -o junitxml --output-file-path console,checkov.xml
# Un dossier pour plusieurs formats
checkov -d infra -o sarif -o json --output-file-path rapports

Le bloc summary du JSON suffit pour suivre un projet dans le temps. Son champ parsing_errors mérite l'attention : un fichier que Checkov n'a pas su lire n'est pas analysé, et ne compte pas comme un échec.

{
"passed": 26,
"failed": 7,
"skipped": 0,
"parsing_errors": 0,
"resource_count": 1,
"checkov_version": "3.3.22"
}

Les règles intégrées ignorent vos conventions internes : étiquette de centre de coût obligatoire, types d'instance autorisés. Checkov accepte des règles en YAML pour un attribut à vérifier, et en Python pour une logique plus riche. Les deux se chargent avec --external-checks-dir.

Le format YAML décrit une condition sur un attribut. Celle-ci exige une étiquette cost-center sur chaque bucket S3 ; sur le Terraform de départ, elle échoue sur aws_s3_bucket.bad_bucket, qui n'en porte pas.

policies/s3_cost_center.yaml
metadata:
id: "CKV2_ACME_1"
name: "Ensure S3 buckets carry a cost-center tag"
category: "GENERAL_SECURITY"
definition:
cond_type: "attribute"
resource_types:
- "aws_s3_bucket"
attribute: "tags.cost-center"
operator: "exists"
Fenêtre de terminal
checkov -d terraform --external-checks-dir policies --check CKV2_ACME_1

Une règle Python hérite d'une classe de base et renvoie PASSED ou FAILED. Celle-ci refuse les types d'instance hors liste. Un détail décide de tout, mesuré sur la version 3.3.22 : sans fichier __init__.py dans le dossier, la règle n'est pas chargée, et Checkov ne le dit pas. Le scan rend alors zéro résultat, qu'on prend facilement pour un succès.

checks/ec2_instance_type.py
from checkov.common.models.enums import CheckCategories, CheckResult
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
class EC2InstanceTypeCheck(BaseResourceCheck):
def __init__(self):
super().__init__(
name="Ensure EC2 instances use approved instance types",
id="CKV_ACME_1",
categories=[CheckCategories.GENERAL_SECURITY],
supported_resources=["aws_instance"],
)
def scan_resource_conf(self, conf):
# Types autorisés dans votre organisation
autorises = ["t3.micro", "t3.small", "t3.medium"]
instance_type = conf.get("instance_type", [None])[0]
if instance_type in autorises:
return CheckResult.PASSED
return CheckResult.FAILED
check = EC2InstanceTypeCheck()
Fenêtre de terminal
touch checks/__init__.py # sans lui, la règle est ignorée en silence
checkov -d terraform --external-checks-dir checks --check CKV_ACME_1
# Passed checks: 1 (t3.micro) ; une instance m5.4xlarge donne FAILED

Préfixez les identifiants par le nom de l'organisation (CKV_ACME_) pour éviter toute collision avec une future règle officielle. Testez chaque règle sur un fichier conforme et un fichier fautif : une règle qui ne voit jamais d'échec n'a peut-être jamais été chargée.

  • Checkov lit le code d'infrastructure sans rien déployer : 1361 règles en 3.3.22, dont 1144 pour Terraform.
  • On l'installe épinglé : pipx install "checkov==3.3.22" ou l'image figée par digest.
  • --compact retire le code, --quiet retire les réussites ; le scan sort en code 1 au premier échec.
  • Un échec n'est pas un risque : on classe les résultats avant de corriger.
  • Les secrets ordinaires passent, et les fichiers .ini ou .env ne sont lus qu'avec --enable-secret-scan-all-files.
  • Sans clé d'API, pas de sévérité : on bloque avec --soft-fail et --hard-fail-on sur des règles nommées.
  • Un .checkov.yaml est chargé automatiquement, et une règle Python sans __init__.py est ignorée en silence.
  • La preuve attendue par SOCLE-INT-VER-2 est un rapport d'analyse de configuration IaC : le SARIF ou le JSON du job CI.

Vérifiez que l'essentiel de cette leçon est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Les questions ci-dessous reprennent les doutes les plus courants sur Checkov : comparaison avec Trivy, intégration en CI, faux positifs et règles maison, avec la même version épinglée que la leçon.

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn