Skip to main contentCloud-Native Toolkit

Continuous Delivery with GitOps

Use GitOps to continuously deliver application changes

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. The deployment environment is a namespace in a container platform like Kubernetes or Red Hat OpenShift. Argo CD models a collection of applications as a project and uses a Git repository to store the application’s desired state. Argo CD is flexible in the structure of the application configuration represented in the Git repository.

Argo CD supports defining Kubernetes manifests in a number of ways:

  • helm charts
  • kustomize
  • ksonnet
  • jsonnet
  • plain directory of yaml/json manifests
  • custom plugins

Argo CD compares the actual state of the application in the cluster with the desired state defined in Git and determines if they are out of sync. When it detects the environment is out of sync, Argo CD can be configured to either send out a notification to kick off a separate reconciliation process or Argo CD can automatically synchronize the environments to ensure they match.

Configuring GitOps with Argo CD

Terminology:

Argo CD uses a number of terms to refer to the components

  • Application - A deployable unit

    In the context of the environment, an application is one Helm chart that contains one container image that was produced by one CI pipeline. While Helm charts and images could certainly be combined to make more sophisticated applications in more advanced scenarios, we will be using this simple definition here.

  • Project - A collection of applications that make up a solution

Set up the GitOps repo

Argo CD uses a Git repo to express the desired state of the Kubernetes environment. The basic setup uses one repository to represent one project. Within that repository, each application that makes up the project will be described in its own folder. The repository will also contain a branch for each destination (i.e. cluster and namespace) into which we want to deploy the applications.

  1. Create a new repo from the Argo CD Starter Kit. If you see a 404 error when you click on the link, you need to sign in to github.

  2. Clone the project to your machine

    git clone ${GIT_URL_GITOPS}
  3. navigate into the directory

    cd ${GIT_DIRECTORY}
  4. Create and push test branch

    git checkout -b test
    git push -u origin test

Hook the CI pipeline to the CD pipeline

The last stage in the CI pipeline updates a GitOps repository with the updated application metadata from the build. In order to do that, the CI pipeline needs to know which repository should be used and needs the credentials to push changes to that repository. As with other configuration within the pipeline, this is handled with config maps and secrets:

  • A secret named git-credentials holds the credentials the CI pipeline uses to access all the respositories in the Git host (e.g. GitHub, GitLab, BitBucket, etc). If you used the IGC CLI to register the pipeline then this secret has already been created.
  • A config map named gitops-repo holds the url and branch for the gitops repository.

Fortunately the IGC CLI provides a gitops command to simplify this step. Information on how to use the command as well as the alternative manual steps can be found in the IGC CLI gitops command section.

  1. Make sure to switch context to the project/namespace CI namespace

    oc project ${DEV_NAMESPACE}
  2. Run the gitops command to create the config map and secret in the CI namespace

    igc gitops

As of v2.0.0 of the Tekton tasks and the Jenkins pipelines, the CI pipeline will create a folder and the initial configuration for an application deployment if it doesn’t already exist. This means, there is no other manual configuration required to set up the repository.

Now run a new Pipeline and make sure a directory for the application is created on the gitops git repository. This is required before configuring ArgoCD.

Configure Release namespaces

ArgoCD will deploy the application into the “releases” namespace such as ${TEST_NAMESPACE} or ${STAGING_NAMESPACE}

  1. Creat a release namespace where ArgoCD will deploy the application

    oc new-project ${TEST_NAMESPACE}

The release namespaces need pull secrets for the application container images to be pull.

If you are using the OpenShift Image Registry then you need to give permission to the services accounts in the “release” namespaces to be able to pull images from the “development” namespaces.

  • Grant access to service accounts in the new test or staging namespace to pull the container image from the dev namespace

    oc policy add-role-to-group system:image-puller system:serviceaccounts:{TEST_NAMESPACE} -n {DEV_NAMESPACE}

Register the GitOps repo in ArgoCD

Now that the repository has been created, we need to tell ArgoCD where it is.

  • Log into ArgoCD

  • Click on the gear icon on the left menu to access the Settings options

    ArgoCD config

  • Select the Repositories option

  • Click either the Connect Repo using HTTPS or Connect Repo using SSH button at the top and provide the information for the GitOps repo you just created. For HTTPS you can use the access token you used when you ran igc gitops

Create a project in Argo CD

In Argo CD terms, each deployable component is an application and applications are grouped into projects. Projects are not required for Argo CD to be able to deploy applications, but it helps to organize applications and provide some restrictions on what can be done for applications that make up a project.

  1. Log into the Argo CD user interface

  2. Click on the gear icon on the left menu to access the Settings options

    Argo CD config
  3. Select the Projects option

  4. Press the New Project button at the top of the page

  5. Specify the properties for the new project

    • Name - Provide the name for the project
    • Description - A brief description of the project
    • Source - Press Add source and pick the Git repository from the list that was added previously
    • Destinations
      • Add https://kubernetes.default.svc for the cluster url and ${TEST_NAMESPACE} for the namespace
      • Add https://kubernetes.default.svc for the cluster url and ${STAGING_NAMESPACE} for the namespace
    • Press Create

    Note: Initially, the only cluster that is available is the one in which Argo CD is - https://kubernetes.default.svc. By adding the two destinations we have allowed the project to be deployed to both the ${TEST_NAMESPACE} and ${STAGING_NAMESPACE} namespaces within the current cluster.

Add an application in Argo CD for each application component

The last step in the process is to define the application(s) within Argo CD that should be managed. This consists of connecting the config within the Git repo to the cluster and namespace.

  1. Log into Argo CD user interface

  2. Press New Application and provide the following values:

    • application name - The name of the application. It is recommend to use the format of {namespace}-{image name}
    • project - The ArgoCD project with which the application should be included
    • sync-policy - The manner with which Argo CD will use to manage the deployed artifacts. Automatic is recommended
    • repository url - The Git url where the configuration is stored (restricted to git urls configured in the Argo Project)
    • revision - The Git branch where the configuration for this instance is stored
    • path - The path within the repository where the application config is located (should be the application name)
    • destination cluster - The cluster url for the deployment
    • destination namespace - The namespace where the application should be deployed (restricted to namespaces configured in the Argo Project)
  3. Repeat that step for each application and each environment

Managing secrets in Argo CD

The following provides the steps to handle protected information in a GitOps repository using the Argo CD Key Protect plugin. The plugin takes yaml configuration as input, looks up the credentials in Key Protect, and generates a secret in the cluster from the results.

Prepare the Key Protect instance

As the name suggests, the Argo CD Key Protect plugin leverages the capabilities of the Key Protect service to manage the protected information. The details for setting up and managing the Key Protect instance can be found in Secret management with Key Protect. From those instructions you can find the information required for the subsequent steps.

Create the secret configuration

The input to the plugin is a directory that contains one or more yaml “secret templates”. In this case the “secret template” provides the structure of the desired secret with placeholders for the values that will be pulled from the key management system.

  1. Create a directory to contain the secret configuration. The Argo CD Starter Kit repository has a template in templates/secrets-plugin that can be copied as a starting point

  2. Update the values in the yaml file for the secret that will be created

    apiVersion: keymanagement.ibm/v1
    kind: SecretTemplate
    metadata:
    name: mysecret
    annotations:
    key-manager: key-protect
    key-protect/instanceId: instance-id
    key-protect/region: us-east
    spec:
    • The metadata.annotations value is optional.

      • key-manager - the only value supported currently is key-protect
      • key-protect/instanceId - the instance id of the key protect instance. If not provided then the instance-id value from the key-protect-access secret will be used.
      • key-protect/region - the region where the key protect instance has been provisioned. If not provided then the region value from the key-protect-access secret will be used.
    • The metadata.name value given will be used as the name for the Secret that will be generated.

    • The information in spec.labels and spec.annotations will be copied over as the labels and annotations in the Secret that is generated

    • The spec.values section contains the information that should be provided in the data section of the generated Secret. There are three prossible ways the values can be provided:

      • value - the actual value can be provided directly as clear text. This would be appropriate for information that is not sensitive but is required in the secret
      • b64value - a base64 encoded value can be provided to the secret. This can be used for large values that might present formatting issues or for information that is not sensitive but that might be obfuscated a bit (like a username)
      • keyId - the id (not the name) of the Standard Key that has been stored in Key Protect. The value stored in Key Protect can be anything
  3. Commit the changes to the GitOps repository

Add the secret application in Argo CD

Once the configuration has been added to the GitOps repository, Argo CD needs to be configured to deploy the secrets.

  1. Log into Argo CD user interface

  2. Press New Application and provide the following values:

    • application name - The name of the application. It is recommend to use the format of {namespace}-{image name}
    • project - The project with which the application should be included
    • sync-policy - The manner with which Argo CD will use to manage the deployed artifacts. Automatic is recommended
    • repository url - The Git url where the configuration is stored
    • revision - The branch where the configuration for this instance is stored
    • path - The path within the repository where the application config is located (should be the application name)
    • destination cluster - The cluster url for the deployment
    • destination namespace - The namespace where the application should be deployed
    • Plugin - In the last section of the UI select Plugin from the dropdown Argo CD plugin
    • key-protect-secret - Click in the name field and select key-protect-secret from the dropdown Argo CD key protect secret
  3. Repeat that step for each secret application and environment

Configure another cluster as an Argo CD deployment target

Argo CD supports deploying applications into clusters other than the one into which it has been installed. To do that, the target cluster must first be registered with Argo CD. After that, the cluster api server can be selected as a deployment target within an application configuration. The following describes the steps required to add another cluster as a deployment target:

  1. Log in to the Argo CD CLI

    argocd login {GRPC_INGRESS_HOST} --grpc-web [--sso]

    where:

    • GRPC_INGRESS_HOST is the host name of the grpc endpoint. On
      this is the same as the UI host
    • --sso is an optional flag used when sso authentication is enabled. If not using SSO then you will be prompted for the username and password

    The grpc url and credentials can be retrieved from the igc credentials command

  2. Log into the target cluster from the command line

  3. Run the Argo CD command to list the available clusters

    argocd cluster add

    The currently selected cluster will be the one with the asterisk next to it. Copy the cluster id from the table

  4. Add the cluster to Argo CD

    argocd cluster add {CLUSTER ID}

    where:

    • {CLUSTER ID} is the id of the target cluster from the previous step
  5. Confirm the configuration by listing the known clusters

    argocd cluster list