Building a Decentralised CI/CD System with GoCD and ArgoCD

We describe here a software development process that leverages a unique blend of centralized and decentralized continuous integration and continuous delivery (CI/CD) systems. The CI is centralized and facilitated by open-source GoCD software, while the CD systems are decentralized and environment-specific, utilizing ArgoCD. This combination allows us to leverage the strengths of both centralized and decentralized architectures, ensuring efficient, reliable, and flexible software delivery.

Centralized Continuous Integration with GoCD

GoCD, an open-source continuous integration system, forms the backbone of our CI process. It supports the modeling of complex workflows, including parallel and sequential execution, facilitating fast feedback and on-demand deployment. A unique feature of GoCD is its fan-in/fan-out dependency management, which smartly manages dependencies to avoid unnecessary builds​​.

When an application is onboarded onto our CI system, gocd pipeline files are created and committed to the same git repository housing the application’s source code. These files outline the necessary continuous integration checks, including unit tests, integration tests, and security tests such as Snyk SAST and DAST checks. If necessary, the pipeline file also contains steps to build and dockerize the code.

GoCD ensures the promotion of trusted artifacts by anchoring every pipeline instance to a specific changeset. This guarantees that the deployed binary has undergone rigorous testing and is ready for deployment​​.

Once the CI checks pass, GoCD commits the built code to docker repositories and prepares any specifications for the CD environments as required.

Decentralized Continuous Delivery with ArgoCD

The CD systems are decentralized and environment-specific. We use ArgoCD, a declarative, GitOps continuous delivery tool for Kubernetes, to manage these deployments​.

ArgoCD is deployed to different clusters such as dev, stag, and production. It consumes the artifacts output by the CI systems, including docker images, helm charts, or specification manifests, and deploys them to the respective environments.

ArgoCD is implemented as a Kubernetes controller, continuously monitoring running applications and comparing the current, live state against the desired target state (as specified in the Git repo)​2​. If the live state deviates from the target state, ArgoCD considers the application ‘OutOfSync’ and provides facilities to automatically or manually sync the live state back to the desired target state.

ArgoCD automates the deployment of the desired application states in the specified target environments. Kubernetes manifests can be specified in several ways: kustomize applications, helm charts, jsonnet files, a plain directory of YAML/json manifests, or any custom config management tool configured as a config management plugin​​.

A Basic Example

GoCD Pipeline Definition

A GoCD pipeline configuration is defined in XML format. Here is a simplified example:

xmlCopy code<pipeline name="my_pipeline">
    <materials>
        <git url="https://github.com/my-repo/my-project.git" />
    </materials>
    <stage name="build">
        <jobs>
            <job name="build">
                <tasks>
                    <exec command="make">
                        <arg>build</arg>
                    </exec>
                </tasks>
            </job>
        </jobs>
    </stage>
    <stage name="test">
        <jobs>
            <job name="test">
                <tasks>
                    <exec command="make">
                        <arg>test</arg>
                    </exec>
                </tasks>
            </job>
        </jobs>
    </stage>
</pipeline>

In this sample, the pipeline pulls from a Git repository and has two stages: build and test. Each stage contains a job that runs a specific task. The tasks are executed by running a make command with the respective argument.

ArgoCD Application Definition

ArgoCD applications are defined in YAML format. Here is a simplified example:

yamlCopy codeapiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/my-repo/my-project.git
    targetRevision: HEAD
    path: manifests/
  destination:
    server: https://kubernetes.default.svc
    namespace: my-app
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

This application definition tells ArgoCD to sync the contents of the manifests/ directory in the Git repository to a Kubernetes cluster. The syncPolicy is set to automated, which means ArgoCD will automatically apply changes from the Git repository to the cluster. The prune and selfHeal options mean that ArgoCD will remove resources that are not in the Git repository and will automatically fix any deviations from the desired state.

Final Thoughts

By using GoCD for centralized CI and ArgoCD for decentralized CD, we’ve created a robust CI/CD system that leverages the best of both worlds. This approach ensures efficient, reliable, and flexible software delivery, keeping our environments always consistent with the state that is described by the CI systems.

The decentralization of our CD system allows us to manage and deploy to multiple clusters, support complex application rollouts like blue/green and canary upgrades, and keep application environments always consistent with the state described by the CI systems​​.

In a world where agility and speed are paramount, our unique blend of centralized and decentralized CI/CD systems offers the right balance of control, flexibility, and efficiency.

Similar Posts