This will walk through integrating Anchore scanning into a Gitlab container image build pipeline. During the first step, a Docker image will be built from a Dockerfile. Following this, during the second step Anchore will scan the image, and depending on the result of the policy evaluation, proceed to the final step. During the final step, the built image will be published and reports will be generated.
Follow along with this blog post by using the GitLab repo here.
This approach differs from previous posts where an Anchore engine service has been accessible from the build pipeline.
Prerequisites
- Gitlab account
- Dockerfile to build container image
Build Image
In the first stage of the pipeline, we build a Docker image from a Dockerfile as defined in our .gitlab-ci.yml
container_build:
stage: build
image: docker:stable
services:
- docker:stable-dind
variables:
DOCKER_DRIVER: overlay2
script:
- docker_login
- docker pull "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}" || true
- docker build --cache-from "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}" -t "$IMAGE_NAME" .
- docker push "$IMAGE_NAME"
Scan Image with Anchore
In the second stage of the pipeline, we scan the built image with Anchore as defined in our .gitlab-ci.yml:
container_scan:
stage: scan
image:
name: anchore/anchore-engine:latest
entrypoint: [""]
services:
- name: anchore/engine-db-preload:latest
alias: anchore-db
variables:
GIT_STRATEGY: none
ANCHORE_HOST_ID: "localhost"
ANCHORE_ENDPOINT_HOSTNAME: "localhost"
ANCHORE_CLI_USER: "admin"
ANCHORE_CLI_PASS: "foobar"
ANCHORE_CLI_SSL_VERIFY: "n"
ANCHORE_FAIL_ON_POLICY: "true"
ANCHORE_TIMEOUT: 500
script:
- |
curl -o /tmp/anchore_ci_tools.py https://raw.githubusercontent.com/anchore/ci-tools/master/scripts/anchore_ci_tools.py
chmod +x /tmp/anchore_ci_tools.py
ln -s /tmp/anchore_ci_tools.py /usr/local/bin/anchore_ci_tools
- anchore_ci_tools --setup
- anchore-cli registry add "$CI_REGISTRY" gitlab-ci-token "$CI_JOB_TOKEN" --skip-validate
- anchore_ci_tools --analyze --report --image "$IMAGE_NAME" --timeout "$ANCHORE_TIMEOUT"
- |
if ; then
anchore-cli evaluate check "$IMAGE_NAME"
else
set +o pipefail
anchore-cli evaluate check "$IMAGE_NAME" | tee /dev/null
fi
artifacts:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}
paths:
- image-*-report.json
Publish image
In the final stage of the pipeline, we push the Docker image to a registry as defined in the .gitlab.yml:
container_publish:
stage: publish
image: docker:stable
services:
- docker:stable-dind
variables:
DOCKER_DRIVER: overlay2
GIT_STRATEGY: none
script:
- docker_login
- docker pull "$IMAGE_NAME"
- docker tag "$IMAGE_NAME" "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}"
- docker push "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}"
- |
if ; then
docker tag "$IMAGE_NAME" "${CI_REGISTRY_IMAGE}:latest"
docker push "${CI_REGISTRY_IMAGE}:latest"
fi
Example
It contains a very simple Nodejs application, which is published to a registry as a runnable docker container.
After the container is built, it is sent through an Anchore engine scan.
anchore/anchore-engine:latest
is used as the build container for the scan job.anchore/engine-preload-db:latest
is a postgres database, preloaded with the Anchore vulnerability data. This is used as a service in the scan job.- The default configuration for Anchore Engine is used on the build container.
- Scans use the default Anchore policy. Using customized policies will become an option at a future time.
- A timeout of 500s is used for this project, this value can be adjusted for whatever container is being scanned with the
ANCHORE_TIMEOUT
environment variable. Some containers take longer to scan than others.
To gate the container publish on a successful Anchore Engine scan, set the environment variable ANCHORE_FAIL_ON_POLICY='true'
. This will cause the pipeline to fail if a scan fails.
Reports Provided by Anchore
When Anchore scanning finishes, by default, the following reports are available as artifacts. Report generation is configurable in anchore_ci_tools.py with the --content & --report flags.
image-content-os-report.json
- all OS packages installed in the imageimage-content-npm-report.json
- all NPM modules installed in the imageimage-content-gem-report.json
- all Ruby gems installed in the imageimage-content-python-report.json
- all Python modules installed in the imageimage-content-java-report.json
- all Java modules installed in the imageimage-vuln-report.json
- all CVE's found in the imageimage-details-report.json
- image metadata utilized by Anchore Engineimage-policy-report.json
- details of the policy applied to the Anchore scan