npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

image-scanner-with-trivy

v2.4.3

Published

Scan container images with Trivy in CDK deployment

Downloads

1,985

Readme

image-scanner-with-trivy

What is

This is an AWS CDK Construct that allows you to scan container images with Trivy in CDK deployment layer.

If it detects vulnerabilities, it can block deployments to ECS, Lambda, and other services, or prevent the image from being pushed to the application ECR. You can also choose to receive notifications without failing the deployment.

  • Block deployments on vulnerability detection — works with ECS, Lambda, application ECR push, or any construct
  • Notify without failing — get alerts via SNS without blocking deployment. Great for gradual adoption
  • Scan logs output — results go to CloudWatch Logs or S3
  • SBOM generation — output Software Bill of Materials in CycloneDX or SPDX format to S3 for compliance reporting
  • Works with any ECR image — not just images built in the same stack. Scan existing repository images too

This library is featured on the ecosystem page of Trivy's official documentation!

Why not ECR scanning?

ECR's basic scanning is asynchronous and does not block deployments. ECR Enhanced Scanning (Amazon Inspector) costs money per scan and still does not natively integrate with CloudFormation deployment flow.

This construct runs Trivy as a CloudFormation Custom Resource during cdk deploy. If vulnerabilities are found, CloudFormation rolls back automatically — no one can bypass the scan. It gives you synchronous, deployment-blocking scans at no additional cost.

Usage

Install

npm install image-scanner-with-trivy

CDK Code

Note: We recommend using ImageScannerWithTrivyV2. See the V2 Construct section for details and migration guide.

The following code is a minimal example that scans the image and blocks the ECS deployment if vulnerabilities are detected.

import { ImageScannerWithTrivyV2 } from 'image-scanner-with-trivy';

// Target image to scan
const image = new DockerImageAsset(this, 'DockerImage', {
  directory: resolve(__dirname, './'),
});

// Example of an ECS construct that uses the image
const ecs = new YourECSConstruct(this, 'YourECSConstruct', {
  dockerImage: image,
  // ...
});

// Scan the image before deploying to ECS
const imageScanner = new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // If vulnerabilities are detected, the ECS deployment will be blocked
  // Note: This option only works when `failOnVulnerability` is `true` (default).
  blockConstructs: [ecs],
});

Other Use Cases

For scanning the image and blocking ECRDeployment (copying images from DockerImageAsset ECR to another ECR repository) if vulnerabilities are detected:

import { ImageScannerWithTrivyV2 } from 'image-scanner-with-trivy';

const repository = new Repository(this, 'ImageRepository', {
  removalPolicy: RemovalPolicy.DESTROY,
  autoDeleteImages: true,
});

const image = new DockerImageAsset(this, 'DockerImage', {
  directory: resolve(__dirname, './'),
});

const ecrDeployment = new ECRDeployment(this, 'DeployImage', {
  src: new DockerImageName(image.imageUri),
  dest: new DockerImageName(`${repository.repositoryUri}:latest`),
});

const imageScanner = new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // If vulnerabilities are detected, the ECRDeployment will be blocked
  blockConstructs: [ecrDeployment],
});

Default Log Group

If you want to use a custom log group for the Scanner Lambda function's default log group, you can specify the defaultLogGroup option.

If you use ImageScannerWithTrivyV2 construct multiple times in the same stack, you have to set the same log group for defaultLogGroup for each construct. When you set different log groups for each construct, a warning message will be displayed.

import { ImageScannerWithTrivyV2 } from 'image-scanner-with-trivy';

const logGroup = new LogGroup(this, 'LogGroup');

new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // Specify the log group to use as the default log group for Scanner Lambda.
  defaultLogGroup: logGroup,
});

// NG example
// When multiple ImageScannerWithTrivyV2 constructs have different default log groups, a warning will be displayed.
new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivyWithAnotherDefaultLogGroup', {
  imageUri: anotherImage.imageUri,
  repository: anotherImage.repository,
  defaultLogGroup: new LogGroup(this, 'AnotherDefaultLogGroup'), // NG example - different log group from the previous construct
  // defaultLogGroup: logGroup, // OK example - use the same log group for all constructs
});

Scan Logs Output

If you output the scan logs to other than the default log group, you can specify the scanLogsOutput option.

This option is useful when you want to choose where to output the scan logs.

You can output scan logs to CloudWatch Logs or S3.

CloudWatch Logs

You can output scan logs to a specific CloudWatch Logs log group using ScanLogsOutput.cloudWatchLogs.

const scanLogsLogGroup = new LogGroup(this, 'ScanLogsLogGroup');

const imageScanner = new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // Use `ScanLogsOutput.cloudWatchLogs` method to specify the log group.
  scanLogsOutput: ScanLogsOutput.cloudWatchLogs({ logGroup: scanLogsLogGroup }),
});

Note on Large Scan Results: CloudWatch Logs has a limit of 1 MB per log event. If Trivy scan results exceed this limit, they will be automatically split into multiple log events. Each chunk will be prefixed with [part X/Y] to indicate the sequence, ensuring no data loss while staying within CloudWatch Logs quotas. For large scan results, we recommend using S3 output instead to avoid fragmentation and make it easier to view complete results.

S3

You can output scan logs to an S3 bucket using ScanLogsOutput.s3.

const scanLogsBucket = new Bucket(this, 'ScanLogsBucket');

const imageScanner = new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // Use `ScanLogsOutput.s3` method to specify the S3 bucket.
  scanLogsOutput: ScanLogsOutput.s3({
    bucket: scanLogsBucket,
    prefix: 'scan-logs/', // Optional: specify a prefix for S3 objects
  }),
});

Additionally, you can output SBOM (Software Bill of Materials) in various formats by specifying the sbomFormat option.

Available SBOM formats:

  • SbomFormat.CYCLONEDX - CycloneDX JSON format
  • SbomFormat.SPDX_JSON - SPDX JSON format
  • SbomFormat.SPDX - SPDX Tag-Value format (human-readable)

Important: SBOM generation is not a vulnerability scan. When sbomFormat is specified:

  • Trivy generates a Software Bill of Materials (SBOM) instead of performing a vulnerability scan
  • The scan will not fail regardless of the failOnVulnerability setting
  • SNS notifications (vulnsNotificationTopic) will not be sent since no vulnerabilities are detected
  • The SBOM file and stderr logs will be uploaded to S3
const scanLogsBucket = new Bucket(this, 'ScanLogsBucket');

const imageScanner = new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // Use `ScanLogsOutput.s3` method to specify the S3 bucket.
  scanLogsOutput: ScanLogsOutput.s3({
    bucket: scanLogsBucket,
    sbomFormat: SbomFormat.CYCLONEDX, // Optional: output SBOM in CycloneDX format
  }),
});

SNS Notification for Vulnerabilities

You can configure an SNS topic to receive notifications when vulnerabilities or EOL (End of Life) OS are detected.

The notification is sent regardless of the failOnVulnerability setting. This means you can receive notifications even when you don't want the deployment to fail.

const notificationTopic = new Topic(this, 'VulnerabilityNotificationTopic');

new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // Receive notifications for vulnerabilities and EOL detection
  vulnsNotificationTopic: notificationTopic,
  // You can choose not to fail the deployment while still receiving notifications
  failOnVulnerability: false,
});

You can specify an SNS topic associated with AWS Chatbot, as notifications are sent in AWS Chatbot message format.

Rollback Error Suppression

By default, the suppressErrorOnRollback property is set to true.

When image scanning fails, CloudFormation triggers a rollback and executes the previous version of the scanner Lambda. If this property is set to true, the previous version of the scanner Lambda will not throw an error, even if the image scanning for the previous version fails.

This allows the rollback to complete successfully, avoiding ROLLBACK_FAILED state when image scanning failures occur.

new ImageScannerWithTrivyV2(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  // Default is true - suppress errors during rollback to prevent ROLLBACK_FAILED
  suppressErrorOnRollback: true,
  // Set to false if you want rollback errors to be thrown
  suppressErrorOnRollback: false,
});

V2 Construct

What's changed in V2?

The ImageScannerWithTrivyV2 construct introduces several API improvements and new features while maintaining the same core functionality:

  1. Improved API Design

    • exitCode and exitOnEolfailOnVulnerability (boolean): More intuitive boolean property to control whether to fail on vulnerabilities or EOL
    • platformtargetImagePlatform: Uses the new TargetImagePlatform class for better type safety
  2. Improved Trivy Ignore Configuration

    • New TrivyIgnore class for more flexible ignore configuration
    • Support for both inline rules (TrivyIgnore.fromRules()) and file paths (TrivyIgnore.fromFilePath())
    • Support for both .trivyignore and .trivyignore.yaml formats
  3. Enhanced Log Management

    • defaultLogGroup property for Scanner Lambda's default log group
    • Simplified log configuration by consolidating previous separate properties
    • CloudWatch Logs output now supports separate log streams for stdout and stderr
  4. New Features

    • S3 support for scan logs output with SBOM format support (ScanLogsOutput.s3())
    • SNS notification support for vulnerabilities (vulnsNotificationTopic): Receive notifications even when you don't want the deployment to fail by setting failOnVulnerability: false
    • blockConstructs property to automatically block dependent constructs on vulnerability detection

Migration from V1 to V2

To migrate from V1 to V2, follow these steps:

Update the import statement:

// Before (V1)
import { ImageScannerWithTrivy } from 'image-scanner-with-trivy';

// After (V2)
import { ImageScannerWithTrivyV2 } from 'image-scanner-with-trivy';

Update to new properties:

// Before (V1)
new ImageScannerWithTrivy(this, 'Scanner', {
  imageUri: image.imageUri,
  repository: image.repository,
  exitCode: 1,  // or 0
  exitOnEol: 1, // or 0
  platform: 'linux/amd64',
  trivyIgnore: [
    'CVE-2021-12345',
    'CVE-2021-67890',
  ],
});

// After (V2)
new ImageScannerWithTrivyV2(this, 'Scanner', {
  imageUri: image.imageUri,
  repository: image.repository,
  failOnVulnerability: true, // or false
  // failOnEol behavior is now included in failOnVulnerability
  targetImagePlatform: TargetImagePlatform.LINUX_AMD64,
  trivyIgnore: TrivyIgnore.fromRules([
    'CVE-2021-12345',
    'CVE-2021-67890',
  ]),
});

Update log group configuration (if you were using custom log settings):

// Before (V1)
new ImageScannerWithTrivy(this, 'Scanner', {
  imageUri: image.imageUri,
  repository: image.repository,
  defaultLogGroupRetentionDays: RetentionDays.ONE_WEEK,
  defaultLogGroupRemovalPolicy: RemovalPolicy.DESTROY,
});

// After (V2)
// Create a custom log group with retention and removal policy
const logGroup = new LogGroup(this, 'DefaultLogGroup', {
  retention: RetentionDays.ONE_WEEK,
  removalPolicy: RemovalPolicy.DESTROY,
});

// Use `defaultLogGroup` for Scanner Lambda's default log group
new ImageScannerWithTrivyV2(this, 'Scanner', {
  imageUri: image.imageUri,
  repository: image.repository,
  defaultLogGroup: logGroup,
});

Update dependencies using blockConstructs (if you were using construct.node.addDependency() to block deployments):

// Before (V1)
const constructToBlock = new YourConstruct(this, 'YourConstruct');
const scanner = new ImageScannerWithTrivy(this, 'Scanner', {
  imageUri: image.imageUri,
  repository: image.repository,
});

// Manually add dependencies to block constructs on vulnerability detection
constructToBlock.node.addDependency(scanner);

// After (V2)
new ImageScannerWithTrivyV2(this, 'Scanner', {
  imageUri: image.imageUri,
  repository: image.repository,
  blockConstructs: [constructToBlock], // Automatically block the construct on vulnerability detection
});

// constructToBlock.node.addDependency(scanner); // No longer needed - blockConstructs handles this automatically

Important Notes on Migration

⚠️ CloudWatch Logs Considerations

When you migrate from V1 to V2, the following log behavior changes occur:

  1. Different Log Group: V2 uses a new internal Lambda function (with different UUID). As a result, scan logs will be output to a different log group than V1.

  2. Previous Log Group Retention: The V1 log group behavior after migration depends on your defaultLogGroupRemovalPolicy setting:

// V1 construct configuration
new ImageScannerWithTrivy(this, 'Scanner', {
  imageUri: image.imageUri,
  repository: image.repository,
  defaultLogGroupRemovalPolicy: RemovalPolicy.DESTROY, // or RETAIN (default)
});
  • If you set RemovalPolicy.DESTROY, the V1 log group will be deleted when you remove the V1 construct.
  • If you used the default (RemovalPolicy.RETAIN), the V1 log group will be retained in your AWS account. You'll need to manually delete it if desired, or keep it for log history.

If you want to preserve your V1 scan logs, make sure to use RemovalPolicy.RETAIN or back them up before migration.

API Reference

API Reference is here.