Securing and testing CI/CD pipelines – Securing and Testing Your CI/CD Pipeline-2

CI/CD pipelines are one of the essential features of modern DevOps, and they orchestrate all processes and combine all tools to deliver better software faster, but how would you secure them? You may want to ask the following questions:
• How do I scan a container image for vulnerabilities?
• How do I store and manage sensitive information and secrets securely?
• How do I ensure that my application is tested before deployment to production?
• How do I ensure that only tested and approved container images are deployed in production?

Throughout this chapter, we will try to answer these using best practices and tooling. For reference, look at the following workflow diagram:

Figure 13.1 – Secure CI/CD workflow

As depicted in the previous figure, we need to modify the CI pipeline to include an additional step for vulnerability scanning. We also require two CD pipelines, one for the Dev environment and another for Prod. To enhance reusability, we’ll restructure our GitHub Actions workflow. We’ll divide the workflows into parent and child workflows. Let’s begin by examining the CD workflow for the Dev environment to get an overview:
name: Dev Continuous Delivery Workflow
on:
push:
branches: [ dev ]
jobs:
create-environment-and-deploy-app:
name: Create Environment and Deploy App
uses: ./.github/workflows/create-cluster.yml
secrets: inherit
run-tests:
name: Run Integration Tests
needs: [create-environment-and-deploy-app]
uses: ./.github/workflows/run-tests.yml
secrets: inherit
binary-auth:
name: Attest Images
needs: [run-tests]
uses: ./.github/workflows/attest-images.yml
secrets: inherit
raise-pull-request:
name: Raise Pull Request
needs: [binary-auth]
uses: ./.github/workflows/raise-pr.yml
secrets: inherit

The workflow begins with a name, followed by a declaration of on push branches dev. This configuration ensures that the workflow triggers with every push to the dev branch. We define multiple jobs in sequence, each depending on the previous one using the needs attribute. Each job invokes a child workflow specified by the uses attribute, and it provides GitHub secrets to these child workflows by setting inherit for the secrets attribute.

The workflow accomplishes the following tasks:

  1. Sets up the Dev Kubernetes cluster, configures Argo CD and supporting tools to establish the environment, and deploys the sample Blog App.
  2. Executes integration tests on the deployed Blog App.
  3. If the tests pass, it utilizes binary authorization (more details to follow) to attest images, ensuring that only tested artifacts are allowed for deployment to production.
  4. Initiates a pull request for deployment to the Prod environment.

In a similar manner, we have the following Prod CD Workflow file:
name: Prod Continuous Delivery Workflow
on:
push:
branches: [ prod ]
jobs:
create-environment-and-deploy-app:
name: Create Environment and Deploy App
uses: ./.github/workflows/create-cluster.yml
secrets: inherit
run-tests:
name: Run Integration Tests
needs: [create-environment-and-deploy-app]
uses: ./.github/workflows/run-tests.yml
secrets: inherit

This workflow is similar to the Dev workflow but does not include the binary-auth and raise-pull-request steps, as they are unnecessary at this stage. To understand it better, let’s begin by examining the Dev workflow. The initial step of the Dev workflow involves creating the environment and deploying the application. However, before we proceed, let’s revisit the Blog App in the next section.

Leave a Reply

Your email address will not be published. Required fields are marked *



          Terms of Use | About Breannaworld | Privacy Policy | Cookies | Accessibility Help | Contact Breannaworld