So far we have setup two separate Git repositories. One Git repository for the application source code and one Git repository for the Kubernetes manifests (Helm chart in our example application).
In the previous section you have seen how to deploy new versions of your application by manually opening pull requests in the configuration repository.
We can fully automate this process by changing the Kubernetes manifests as part of the application pipeline. This means that instead of having a human changing both the application source code and the manifests, we will have our pipeline automatically update the manifests whenever the application source code is changed with the proper image tag.
Here is the pipeline that we will create.
Edit your Codefresh YAML to the following:
codefresh.yml
version: '1.0'
stages:
- checkout
- package
- verify
- gitops
steps:
main_clone:
title: Cloning main repository...
type: git-clone
repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}'
revision: '${{CF_REVISION}}'
stage: checkout
run_unit_tests:
title: Unit test
stage: package
image: 'maven:3.5.2-jdk-8-alpine'
commands:
- mvn -Dmaven.repo.local=/codefresh/volume/m2_repository test
build_my_image:
title: Building Docker Image
type: build
stage: package
image_name: <your docker username>/my-app-image
working_directory: ./
tags:
- "${{CF_SHORT_REVISION}}"
- latest
dockerfile: Dockerfile
registry: dockerhub
scan_image:
title: Container security scan
stage: verify
image: 'aquasec/trivy'
commands:
- trivy image docker.io/<your docker username>/my-app-image:${{CF_SHORT_REVISION}}
run_integration_tests:
title: Integration tests
stage: verify
image: maven:3.5.2-jdk-8-alpine
commands:
- mvn -Dmaven.repo.local=/codefresh/volume/m2_repository verify -Dserver.host=http://my-spring-app
services:
composition:
my-spring-app:
image: '${{build_my_image}}'
ports:
- 8080
readiness:
timeoutSeconds: 30
periodSeconds: 15
image: byrnedo/alpine-curl
commands:
- "curl http://my-spring-app:8080/"
clear_gitops_cache:
title: Clear any unpushed changes
stage: "gitops"
image: maven:3.5.2-jdk-8-alpine
commands:
- rm -rf /codefresh/volume/aws-gitops-app-manifests
clone_gitops:
title: cloning gitops repo
type: git-clone
arguments:
repo: '${{CF_REPO_OWNER}}/aws-gitops-app-manifests'
revision: 'main'
stage: "gitops"
when:
branch:
only:
- main
change_manifest:
title: "Update Helm values"
image: "mikefarah/yq:3"
commands:
- yq w -i simple-java-app/values.yaml image.tag ${{CF_SHORT_REVISION}}
- cat simple-java-app/values.yaml
working_directory: "${{clone_gitops}}"
stage: "gitops"
when:
branch:
only:
- main
commit_and_push:
title: Commit Helm values
type: git-commit
stage: "gitops"
arguments:
repo: '${{CF_REPO_OWNER}}/aws-gitops-app-manifests'
git: github
working_directory: '/codefresh/volume/aws-gitops-app-manifests'
commit_message: Updated Helm values
git_user_name: ${{CF_COMMIT_AUTHOR}}
git_user_email: <your email address>
when:
branch:
only:
- main
Remember to change the value of <your docker username>
to your own Dockerhub username and <your email address>
to your Github email address.
In a real application you should also use Codefresh variables instead of hardcoding everything in the pipeline
The new steps of this pipeline do the following.
Notice that for the deployment steps we use conditionals to restrict them only to the main branch because we don’t want to deploy to our “production” environment when a Pull request happens to an unrelated branch.
You can trigger this pipeline as before by making any simple change to the application repository (try changing again the hello world message again at the aws-gitops-app/src/main/java/sample/actuator/HelloWorldService.java
file). Once you commit and push
the pipeline will be automatically triggered.
It will then do the following:
At this point the Codefresh GitOps agent will perform the deployment automatically. After a few minutes if you visit the application again in your browser you will see the new application version deployed.