We recently learned of a new contribution to the ApplicationSet in the Argo CD project, specifically the Pull Request generator for GitLab and decided to take it for a spin. What makes this interesting is now dynamic review environments can be provisioned intuitively from the merge request (MR) using a GitOps workflow. The benefit is code reviewers or designers can quickly review any app changes to your Kubernetes cluster all from within the merge request.
In traditional testing workflows, you may have pushed your changes into a development environment, waiting for the QA and UX team to pull those changes into their environment for further review, and then received feedback based on your small change. At this point, time was wasted between various teams with environment coordination or adding bugs to the backlog of the new changes.
With the combination of a merge request and review environments, you can quickly spin up a test environment based on the changes of your feature branch. This means the QA or UX team can suggest improvements or changes during the code review process without wasting cycles.
The introduction of the ApplicationSet has given greater flexibility to Argo CD workflows such as:
- Allowing unprivileged cluster users to deploy applications (without namespace access)
- Deploying applications to multiple clusters at once
- Deploying many applications from a single monorepo
- And triggering review environments based on a pull request
Let's review the ApplicationSet and the GitLab Pull Request Generator
The Pull Request Generator will use the GitLab API to automatically discover new merge requests within a repository. Depending on the filter match of the MR, a review environment will then be generated.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: review-the-application
namespace: argocd
spec:
generators:
- pullRequest:
gitlab:
project: <project-id>
api: https://gitlab.com/
tokenRef:
secretName: <gitlab-token>
key: token
pullRequestState: opened
requeueAfterSeconds: 60
template:
metadata:
name: 'review-the-application-{{number}}'
spec:
source:
repoURL: <repository-with-manifest-files>
path: chart/
targetRevision: 'HEAD'
helm:
parameters:
- name: "image.repository"
value: "registry.gitlab.com/<group-and-project-path>/{{branch}}"
- name: "image.tag"
value: "{{head_sha}}"
- name: "service.url"
value: "the-application-{{number}}.<ip>.nip.io"
project: default
destination:
server: https://kubernetes.default.svc
namespace: dynamic-environments-with-argo-cd
Fields
project
: The GitLab Project IDapi
: URL of GitLab instancetokenRef
: The secret to monitor merge request changeslabels
: Provision review environments based on a GitLab labelpullRequestState
: Provision review environments based on MR states
Filter options include GitLab labels, merge request state (open, closed, merged), and branch match. Templating options include merge request ID, branch name, branch slug, head sha, and head short sha.
See the latest ApplicationSet documentation for additional details.
For this blog post, we explore using the Argo CD ApplicationSet to provision a “ReviewOps” environment based on merge request changes.
Prerequisites
The following tools are required for running this tutorial. Please install and/or configure them before getting started.
- Tools
- GitLab v15.0+
- Kubernetes cluster v1.21+
- Argo CD 2.5.0+
- CLI
- kubectl v1.21+
Explore the Source Code
First, let’s explore the source code for the tutorial.
This GitLab group is composed of the 2 following projects:
The Application
: contains the source code of a containerized application and its CI/CD pipelineThe Application Configuration
: contains the application configuration (Kubernetes Manifests) managed by Helm
Setting up GitLab
-
Create your GitLab Group and fork the The Application and The Application Configuration projects into it.
-
In
The Application Configuration
project, edit the**manifests/applicationset.yml**
as follows:
.spec.generators.pullRequest.gitlab.project
: The Project ID ofThe Application
.spec.template.spec.source.repoURL
: Git URL ofThe Application Configuration
.spec.template.spec.source.helm.parameters."image.repository"
: Point to image repository, for exampleregistry.gitlab.com/<Your_GitLab_Group>/the-application/{{branch}}
Note: keep the {{branch}} string as is and replace <Your_GitLab_Group> with the name of the group you created in step 1.
.spec.template.spec.source.helm.parameters."service.url"
: Templated withthe-application-{{number}}.<Your_Kube_Ingress_Base_Domain>
Note: keep the {{number}} string as is and replace <Your_Kube_Ingress_Base_Domain> with the base domain of your Kubernetes Cluster.
-
Define the following CI/CD variables at the group level:
ARGOCD_SERVER_URL
, the Argo CD server addressARGOCD_USERNAME
, the username of your Argo CD accountARGOCD_PASSWORD
, the password of your Argo CD accountKUBE_INGRESS_BASE_DOMAIN
, the base domain of your Kubernetes Cluster
-
Generate a Group access token to grant
read_api
andread_registry
access to this group and its sub-projects.Save the group access token somewhere safe. We will use it later.
Setting up Kubernetes
- Create a namespace called
dynamic-environments-with-argo-cd
.kubectl create namespace dynamic-environments-with-argo-cd
- Create a Kubernetes secret called
gitlab-token-dewac
to allow Argo CD to use the GitLab API.kubectl create secret generic gitlab-token-dewac -n argocd --from-literal=token=<Your_Access_Token>
- Create another Kubernetes secret called
gitlab-token-dewac
to allow Kubernetes to pull images from the GitLab Container Registry.kubectl create secret generic gitlab-token-dewac -n dynamic-environments-with-argo-cd --from-literal=token=<Your_Access_Token>
Setting up Argo CD
- Create the Argo CD ApplicationSet to generate an Argo CD Application associated with a merge request.
kubectl apply -f https://gitlab.com/<Your_GitLab_Group>/the-application-configuration/-/raw/main/manifests/applicationset.yaml
Update the source code
-
In
The Application
project, create a GitLab issue, then an associated branch and merge request. -
In Argo CD, a new application is provisioned called
review-the-application
based on the new merge request event. -
In
The Application
project, edit theindex.pug
and replacep Welcome to #{title}
withp Bienvenue à #{title}
. -
Commit into your recent branch which is going to trigger a pipeline run.
-
In the CI/CD > Pipelines, you will find the following pipeline running on your merge request:
where,
docker-build
: builds the container imagereviewops
: configures and deploys the container into the review environment using Argo CDstop-reviewops
: deletes the review environment
-
Once completed, the
review-the-application
application in Argo CD is now synced. -
From the merge request, click on the
View app
button to access to your application.The outcome should be as follows:
-
You have succesfully provisioned a dynamic review environment based on your merge request! Once the merge request is closed, the environment will be automatically cleaned up.
To sum up
Hopefully this tutorial has been helpful and has inspired your GitLab + Argo CD workflows with review environments.
We'd love to hear in the comments on how this is working for you, as well as your ideas on how we can make GitLab a better place for GitOps workflows.