Automatic Docker image scan on push using Terraform
Note
You can enable auto scans of Docker images for vulnerabilities on push to Yandex Container Registry in the vulnerability scanner settings without creating any Yandex Cloud Functions functions and triggers.
To configure automatic Docker image scans for vulnerabilities on push to Yandex Container Registry using Terraform:
- Prepare your cloud.
- Prepare the environment.
- Create an infrastructure.
- Push the Docker image.
- Check the result.
If you no longer need the resources you created, delete them.
Prepare your cloud
Sign up for Yandex Cloud and create a billing account:
- Go to the management console
and log in to Yandex Cloud or create an account if you do not have one yet. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one.
If you have an active billing account, you can go to the cloud page
Learn more about clouds and folders.
Required paid resources
The infrastructure support costs include:
- Fee for storing a Docker image in the registry, a vulnerability scanner, and outgoing traffic (see Yandex Container Registry pricing).
- Fee for invoking functions (see Yandex Cloud Functions pricing).
Prepare the environment
- Install and configure Docker.
Create an infrastructure
With Terraform
Terraform is distributed under the Business Source License
For more information about the provider resources, see the documentation on the Terraform
To create an infrastructure to automatically scan a Docker image on push using Terraform:
-
Specify the source for installing the Yandex Cloud provider (see Configure a provider, step 1).
-
Prepare files with the infrastructure description:
Ready-made configurationManually-
Clone the repository with configuration files.
git clone https://github.com/yandex-cloud-examples/yc-cr-image-scanning
-
Go to the directory with the repository. Make sure it contains the following files:
image-auto-scan.tf
: New infrastructure configuration.image-auto-scan.auto.tfvars
: User data file.function.zip
: ZIP archive with the function code.
-
Create a folder for configuration files.
-
In the directory, create a configuration file named
image-auto-scan.tf
:image-auto-scan.tf
# Declaring variables for custom parameters variable "zone" { type = string } variable "folder_id" { type = string } # Adding other variables locals { sa_scanner_name = "scanner" sa_invoker_name = "invoker" registry_name = "my-registry" function_name = "scan-on-push" trigger_name = "trigger-for-reg" } # Configuring a provider terraform { required_providers { yandex = { source = "yandex-cloud/yandex" version = ">= 0.47.0" } } } provider "yandex" { folder_id = var.folder_id } # Creating service accounts resource "yandex_iam_service_account" "scanner" { name = local.sa_scanner_name description = "SA for Container Registry" folder_id = var.folder_id } resource "yandex_iam_service_account" "invoker" { name = local.sa_invoker_name description = "SA for Cloud Functions" folder_id = var.folder_id } # Assigning roles to service accounts resource "yandex_resourcemanager_folder_iam_member" "sa-role-scanner" { folder_id = var.folder_id role = "container-registry.images.scanner" member = "serviceAccount:${yandex_iam_service_account.scanner.id}" } resource "yandex_resourcemanager_folder_iam_member" "sa-role-invoker" { folder_id = var.folder_id role = "functions.functionInvoker" member = "serviceAccount:${yandex_iam_service_account.invoker.id}" } # Creating a registry in Container Registry resource "yandex_container_registry" "my-reg" { name = local.registry_name folder_id = var.folder_id } # Creating a function resource "yandex_function" "test-function" { name = local.function_name user_hash = "my-first-function" runtime = "bash" entrypoint = "handler.sh" memory = "128" execution_timeout = "60" service_account_id = yandex_iam_service_account.scanner.id content { zip_filename = "function.zip" } } # Creating a trigger resource "yandex_function_trigger" "my-trigger" { name = local.trigger_name function { id = yandex_function.test-function.id service_account_id = yandex_iam_service_account.invoker.id } container_registry { registry_id = yandex_container_registry.my-reg.id create_image_tag = true batch_cutoff = "10" batch_size = "1" } }
-
Create a file with user data named
image-auto-scan.auto.tfvars
:image-auto-scan.auto.tfvars
zone = "<availability_zone>" folder_id = "<folder_ID>"
-
Prepare a ZIP archive with the function code.
-
Create the
handler.sh
file and paste the following code to it:handler.sh
Warning
DATA=$(cat | jq -sr '.[0].messages[0].details') ID=$(echo $DATA | jq -r '.image_id') NAME=$(echo $DATA | jq -r '.repository_name') TAG=$(echo $DATA | jq -r '.tag') yc container image scan --id ${ID} --async 1>&2
-
Create a ZIP archive named
function.zip
with thehandler.sh
file.
-
For more information about the parameters of resources used in Terraform, see the provider documentation:
-
-
In the
image-auto-scan.auto.tfvars
file, set the following user-defined properties:zone
: Availability zone to create the infrastructure in.folder_id
: ID of the folder to create the infrastructure in.
-
Create resources:
-
In the terminal, change to the folder where you edited the configuration file.
-
Make sure the configuration file is correct using the command:
terraform validate
If the configuration is correct, the following message is returned:
Success! The configuration is valid.
-
Run the command:
terraform plan
The terminal will display a list of resources with parameters. No changes are made at this step. If the configuration contains errors, Terraform will point them out.
-
Apply the configuration changes:
terraform apply
-
Confirm the changes: type
yes
in the terminal and press Enter.
-
Push the Docker image
-
Run Docker Desktop.
-
Log in to the registry under your username with:
Docker credential helperOAuth tokenIAM token-
Configure Docker to use
docker-credential-yc
:yc container registry configure-docker
Result:
Credential helper is configured in '/home/<user>/.docker/config.json'
Settings are saved in the current user's profile.
Warning
The credential helper only works if you use Docker without
sudo
. To learn how to configure Docker to run under the current user withoutsudo
, see the official Docker documentation . -
Make sure that Docker is configured.
The following line must appear in the
/home/<user>/.docker/config.json
configuration file:"cr.yandex": "yc"
-
You can now use Docker, for example, to push Docker images. You do not need to run the
docker login
command for that.
-
If you do not have an OAuth token yet, get one at this link
. -
Run this command:
echo <OAuth_token> | docker login --username oauth --password-stdin cr.yandex
Result:
Login Succeeded
-
-
Pull a Docker image from Docker Hub
:docker pull ubuntu:20.04
Result:
20.04: Pulling from library/ubuntu Digest: sha256:cf31af331f38d1d7158470e095b132acd126a7180a54f263d386da88******** Status: Image is up to date for ubuntu:20.04 docker.io/library/ubuntu:20.04
-
Assign a tag to the Docker image:
docker tag ubuntu:20.04 cr.yandex/<registry_ID>/ubuntu:20.04
-
Push the Docker image to Container Registry:
docker push cr.yandex/<registry_ID>/ubuntu:20.04
Result:
The push refers to repository [cr.yandex/crpu20rpdc2f********/ubuntu] 2f140462f3bc: Layer already exists 63c99163f472: Layer already exists ccdbb80308cc: Layer already exists 20.04: digest: sha256:86ac87f73641c920fb42cc9612d4fb57b5626b56ea2a19b894d0673f******** size: 943
Check the result
-
View the logs of the
scan-on-push
function and make sure it has executed.Management consoleCLI- In the management console
, select Cloud Functions. - Go to the Functions section and select the
scan-on-push
function. - In the window that opens, go to Logs and specify the time period. The default time period is one hour.
To find out the name or unique ID of a function, get a list of functions in the folder.
View the function execution log:
yc serverless function logs scan-on-push
Result:
2021-05-18 09:27:43 START RequestID: 34dc9533-ed6e-4468-b9f2-2aa0******** Version: b09i2s85a0c1******** 2021-05-18 09:27:43 END RequestID: 34dc9533-ed6e-4468-b9f2-2aa0******** 2021-05-18 09:27:43 REPORT RequestID: 34dc9533-ed6e-4468-b9f2-2aa0******** Duration: 538.610 ms Billed Duration: 538.700 ms Memory Size: 128 MB Max Memory Used: 13 MB 2021-05-18 09:29:25 START RequestID: 5b6a3779-dcc8-44ec-8ee2-2e7f******** Version: b09i2s85a0c1******** 2021-05-18 09:29:26 END RequestID: 5b6a3779-dcc8-44ec-8ee2-2e7f******** 2021-05-18 09:29:26 REPORT RequestID: 5b6a3779-dcc8-44ec-8ee2-2e7f******** Duration: 554.904 ms Billed Duration: 555.000 ms Memory Size: 128 MB Max Memory Used: 13 MB ...
- In the management console
-
Make sure that a new scan started when you pushed the Docker image.
Management consoleCLI- In the management console
, select the parent folder of the registry containing the Docker image. - Select Container Registry.
- Select the registry where you pushed your Docker image.
- Open the repository with the Docker image.
- Select the relevant Docker image and check the Date of last scan parameter value.
To view scans by Docker image, run the command:
yc container image list-scan-results --repository-name=<registry_ID>/<Docker_image_name>
Result:
+----------------------+----------------------+---------------------+--------+--------------------------------+ | ID | IMAGE | SCANNED AT | STATUS | VULNERABILITIES | +----------------------+----------------------+---------------------+--------+--------------------------------+ | crpu20rpdc2f******** | crpqmsqp5mtb******** | 2021-05-18 14:34:02 | READY | medium:6, low:13, negligible:3 | +----------------------+----------------------+---------------------+--------+--------------------------------+
- In the management console
How to delete the resources you created
To stop paying for the resources you created:
-
Open the
image-auto-scan.tf
configuration file and delete the description of the new infrastructure from it. -
Apply the changes:
-
In the terminal, change to the folder where you edited the configuration file.
-
Make sure the configuration file is correct using the command:
terraform validate
If the configuration is correct, the following message is returned:
Success! The configuration is valid.
-
Run the command:
terraform plan
The terminal will display a list of resources with parameters. No changes are made at this step. If the configuration contains errors, Terraform will point them out.
-
Apply the configuration changes:
terraform apply
-
Confirm the changes: type
yes
in the terminal and press Enter.
-