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 vulnerability scans of Docker images on push to Yandex Container Registry using Terraform:
- Get your cloud ready.
- Set up your environment.
- Create the infrastructure.
- Push the Docker image.
- Check the result.
If you no longer need the resources you created, delete them.
Get your cloud ready
Sign up for Yandex Cloud and create a billing account:
- Navigate to the management console
and log in to Yandex Cloud or create a new account. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVEorTRIAL_ACTIVEstatus. If you do not have a billing account, create one and link a cloud to it.
If you have an active billing account, you can create or select a folder for your infrastructure on the cloud page
Learn more about clouds and folders here.
Required paid resources
The infrastructure support cost includes:
- Fee for storing a Docker image in the registry, a vulnerability scanner, and outgoing traffic (see Yandex Container Registry pricing).
- Fee for function calls (see Yandex Cloud Functions pricing).
Set up your environment
- Install and configure Docker.
Create the infrastructure
With Terraform
Terraform is distributed under the Business Source License
For more information about the provider resources, see the guides 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 your provider, step 1).
-
Prepare your infrastructure description files:
Ready-made configurationManually-
Clone the repository containing the configuration files.
git clone https://github.com/yandex-cloud-examples/yc-cr-image-scanning -
Navigate to the repository directory. It should now contain 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.
-
Create a configuration file named
image-auto-scan.tfin the folder: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.shfile 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.zipwith thehandler.shfile.
-
Learn more about the properties of resources in these Terraform provider guides:
-
-
In the
image-auto-scan.auto.tfvarsfile, 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 the resources:
-
In the terminal, navigate to the configuration file directory.
-
Make sure the configuration is correct using this command:
terraform validateIf the configuration is valid, you will get this message:
Success! The configuration is valid. -
Run this command:
terraform planYou will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
-
Apply the configuration changes:
terraform apply -
Type
yesand press Enter to confirm the changes.
-
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-dockerResult:
Credential helper is configured in '/home/<user>/.docker/config.json'The current user’s profile stores the settings.
Warning
The credential helper only works if you use Docker without
sudo. To learn how to configure Docker to run on behalf of the current user withoutsudo, see this Docker guide . -
Make sure Docker is configured.
The
/home/<user>/.docker/config.jsonconfiguration file should now contain this line:"cr.yandex": "yc" -
You can now use Docker, e.g., to push Docker images. You do not need to run the
docker logincommand for that.
OAuth token authentication is deprecated
This authentication method will no longer be supported. Consider using IAM tokens or API keys.
-
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.yandexResult:
Login Succeeded
-
-
Pull a Docker image from Docker Hub
:docker pull ubuntu:20.04Result:
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.04Result:
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-pushfunction 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-pushfunction. - 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 ID of a function, get the list of functions in the folder.
View the function execution log:
yc serverless function logs scan-on-pushResult:
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.tffile and delete your infrastructure description from it. -
Apply the changes:
-
In the terminal, navigate to the configuration file directory.
-
Make sure the configuration is correct using this command:
terraform validateIf the configuration is valid, you will get this message:
Success! The configuration is valid. -
Run this command:
terraform planYou will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
-
Apply the configuration changes:
terraform apply -
Type
yesand press Enter to confirm the changes.
-