Checkov on AWS User Guide
Overview
This image runs Checkov, the open source static analysis and policy-as-code scanner that finds security and compliance misconfigurations in infrastructure-as-code before it is ever deployed. It parses Terraform, CloudFormation, Kubernetes, Helm, Serverless, Bicep, ARM and Dockerfiles and reports where the declared infrastructure violates a policy, such as a storage bucket with no encryption, a security group open to the world, or a container running as root. The image is delivered ready to use: Checkov is installed in an isolated Python virtual environment with a wrapper on the system path, so the moment you connect over SSH you can run a real scan against thousands of built-in policies with no setup.
This is a headless command-line tool. There is no web interface, no daemon, no network port and no credential of any kind. Checkov's entire management surface is the checkov CLI plus SSH with your own key, so there is nothing to rotate and nothing to leak. Checkov 3.3.8 is installed in a dedicated virtual environment at /opt/checkov/venv, and a wrapper at /usr/local/bin/checkov puts checkov on the system path. The instance security group opens port 22 only.
A daily systemd timer, checkov-scan.timer, scans a drop-in target directory at /opt/checkov/scan-targets and appends its report to /var/log/checkov/scan.log, so you can leave infrastructure code in one place and have it re-checked automatically. Findings are Checkov working as designed: review each one, fix the code, or suppress it with an inline skip comment or a policy file.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Checkov. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes a few seconds after the instance state becomes Running and the status checks pass; the Checkov toolchain is ready by the time you can connect.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Checkov Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=checkov}]'
When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.
Step 3: Connect to Your Instance
Connect over SSH using your key pair and the login user for your operating system variant.
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i <key-name>.pem ubuntu@<public-ip>
There is no login credential to fetch: Checkov has none. The per-instance welcome note at /root/checkov-instance.txt records the installed version and the most useful commands; read it with sudo cat /root/checkov-instance.txt.
Step 4: Verify Checkov and Its Policy Set
Checkov is installed in a virtual environment at /opt/checkov/venv, and the checkov wrapper on the system path runs it. Confirm the installed version, which is pinned to Checkov 3.3.8 on this image:
checkov --version
Checkov ships thousands of built-in policies keyed CKV_* and CKV2_*. Count the built-in checks the shipped scanner loads:
checkov --list | grep -c CKV
You should see 3.3.8 for the version and several thousand policies listed, confirming the scanner and its policy set are loaded and ready.

Step 5: Prove Real Misconfiguration Detection
The best way to confirm the scanner works is to run it against a deliberately insecure configuration and watch it report the failed checks. The block below writes a small Terraform file with an S3 bucket that has no hardening and a security group open to the world, scans it, and prints the findings. Checkov exits non-zero when a policy fails, which is the signal a CI pipeline gates on, so the block ends cleanly after showing the report:
D=$(mktemp -d)
cat > "$D/insecure.tf" <<'EOF'
resource "aws_s3_bucket" "data" {
bucket = "cloudimg-demo-data"
}
resource "aws_security_group" "open" {
name = "open-to-world"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
EOF
checkov -d "$D" --compact --quiet || echo "checkov exited non-zero: the failing checks above are the expected result"
rm -rf "$D"
Each failed check names the policy id (for example CKV_AWS_24, the rule that a security group must not allow ingress from 0.0.0.0/0 to port 22), the resource it applies to, and the file and line. This is exactly the report you would fix or suppress before deploying the infrastructure.

Step 6: Scan a Clean Configuration
A configuration with no failing checks passes clean and Checkov exits zero. The block below writes an S3 bucket with versioning enabled and runs the versioning policy against it:
D=$(mktemp -d)
cat > "$D/main.tf" <<'EOF'
resource "aws_s3_bucket" "logs" {
bucket = "cloudimg-secure-logs"
}
resource "aws_s3_bucket_versioning" "logs" {
bucket = aws_s3_bucket.logs.id
versioning_configuration { status = "Enabled" }
}
EOF
checkov -d "$D" --check CKV_AWS_21 --compact --quiet
echo "exit code: $?"
rm -rf "$D"
You should see Passed checks: 1, Failed checks: 0 and exit code: 0. Scanning your own code is the same pattern: checkov -d /path/to/your/iac for a directory, or checkov -f main.tf for a single file.

Step 7: The Daily Scheduled Scan
The image ships a daily scheduled scan. The checkov-scan.timer systemd timer runs checkov -d /opt/checkov/scan-targets once a day and appends the report to /var/log/checkov/scan.log. Confirm the timer is active:
systemctl status checkov-scan.timer --no-pager
Drop your infrastructure code into /opt/checkov/scan-targets to have it scanned automatically, or run Checkov by hand against any path whenever you like. A finding is the scanner working as designed: review the report, fix the code, or suppress a reviewed finding with an inline # checkov:skip=CKV_...:reason comment or a .checkov.yaml policy file.

Step 8: Wire Checkov into CI
Checkov's non-zero exit on a policy failure is what makes it a merge gate. In a CI pipeline, run checkov -d . (or point it at a plan file with checkov -f plan.json) as a build step, and let the non-zero exit fail the build when a policy is violated. Use --check to run only specific policies, --skip-check to exclude ones you have accepted, and a .checkov.yaml file in your repository to codify the policy set for the whole team. Because the scanner and its policies are pinned on this image, every run is reproducible.
Support
This image is published and supported by cloudimg. Support covers running scans, interpreting findings, writing suppressions and custom policies, wiring Checkov into CI, and keeping your infrastructure code compliant. Contact cloudimg through the support channel listed on the AWS Marketplace listing.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.