Container image scanning with Trivy in AWS CDK
Tags: aws, docker, trivy, cdk
Published: 2023-09-19 12:20:21

## Overview

A Construct for AWS CDK, which uses **Trivy** to perform security diagnostics on **container images**, is published on Construct Hub.

---

## Trivy

[Trivy](https://aquasecurity.github.io/trivy) is a security tool that can perform vulnerability testing and diagnostics on a wide range of targets, including container images, file systems, and even AWS accounts.

In this article, I will use it to scan container images built from Dockerfile in AWS CDK.

---

## Advantages for this Construct

This Construct can do the following

- Scan container images with Trivy **in the CDK layer (in `cdk deploy`)**.
- Avoid unnecessary builds and **use assets from images built in CDK deploy**.
- **Stop application image push to ECR** when vulnerabilities are detected.

---

## image-scanner-with-trivy

The Construct I created this time has been published on Construct Hub under the name ["image-scanner-with-trivy"](https://constructs.dev/packages/image-scanner-with-trivy).

In addition, it is necessary to publish to npm in advance for Construct Hub publication, and the page as an npm package is shown below, see [this page](https://www.npmjs.com/package/image-scanner-with-trivy).

And while you're at it, take a look at [GitHub](https://github.com/go-to-k/image-scanner-with-trivy) if you like.

---

## How to use

### Install

First, install in the CDK repository.

```sh
npm install image-scanner-with-trivy
```

### Use Construct

`new ImageScannerWithTrivy` is the corresponding Construct.

```typescript
import { ImageScannerWithTrivy } 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, './'),
});

// Add properties you want for trivy options (ignoreUnfixed, severity, scanners, trivyIgnore, etc).
const imageScanner = new ImageScannerWithTrivy(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
});

// By adding `addDependency`, if the vulnerabilities are detected by `ImageScannerWithTrivy`, the following `ECRDeployment` will not be executed, deployment will fail.
const ecrDeployment = new ECRDeployment(this, 'DeployImage', {
  src: new DockerImageName(image.imageUri),
  dest: new DockerImageName(`${repository.repositoryUri}:latest`),
});

ecrDeployment.node.addDependency(imageScanner);
```

### Options

Various options for `trivy` can also be specified. See the API reference below. (scanners, severity, ignoreUnfixed, trivyIgnore, etc...)

[API reference](https://github.com/go-to-k/image-scanner-with-trivy/blob/main/API.md#properties--1)

Of course, you can use it without specifying them, and **"options that you want to work for a good CI/CD CDK deployment"** are specified internally by default.

For example, you can specify options like the following, which include Construct-specific options that are not used in `trivy` itself, but see the description in the API reference above for details.

```typescript
new ImageScannerWithTrivy(stack, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
  ignoreUnfixed: true,
  severity: [Severity.CRITICAL],
  scanners: [Scanners.VULN, Scanners.SECRET],
  exitCode: 1,
  exitOnEol: 1,
  trivyIgnore: ['CVE-2023-37920', 'CVE-2019-14697 exp:2023-01-01', 'generic-unwanted-rule'],
  memorySize: 4096,
  platform: 'linux/arm64',
});
```

### Stop image push on vulnerability detection

As shown in the example below, `ecrDeployment.node.addDependency(imageScannerWithTrivy)` will make `ECRDeployment` depends on `ImageScannerWithTrivy` so that `ImageScannerWithTrivy` is executed first. `ImageScannerWithTrivy` will **stop pushing images to the application ECR** if it detects a vulnerability.

```typescript
const imageScanner = new ImageScannerWithTrivy(this, 'ImageScannerWithTrivy', {
  imageUri: image.imageUri,
  repository: image.repository,
});

// By adding `addDependency`, if the vulnerabilities are detected by `ImageScannerWithTrivy`, the following `ECRDeployment` will not be executed, deployment will fail.
const ecrDeployment = new ECRDeployment(this, 'DeployImage', {
  src: new DockerImageName(image.imageUri),
  dest: new DockerImageName(`${repository.repositoryUri}:latest`),
});

ecrDeployment.node.addDependency(imageScanner);
```

---

## Published in Official Documents(Thanks!)

To my surprise, this library was featured on [the ecosystem page of Trivy's official documentation](https://aquasecurity.github.io/trivy/latest/ecosystem/ide/#image-scanner-with-trivy-community)!

---

## Dockle version

I used `Trivy` for this project, but I have also published [a library that uses Dockle](https://dev.to/aws-builders/container-image-scanning-with-dockle-in-aws-cdk-1bac), if you would like to use it!

---

## Finally

I wanted to do a synchronous container image scan in AWS CDK, so I created my own library.

Please feel free to use it if you like.