Codefresh is an awesome platform for doing GitOps deployments to Kubernetes. Starting last year, the Codefresh team has been adding rich integrations with Argo CD and Argo Rollouts, GitOps observability dashboards, and more. Codefresh pipelines, in particular, have played an integral role in our customers’ progressive delivery workflows by allowing them to orchestrate all of the testing, analysis, and rollback activities that work in conjunction with Argo CD synchronization.
While it is quite common to have one or two primary pipelines that handle these large workflows, it can also be useful to trigger an occasional helper pipeline, based on events in Argo CD. For example, you might want to trigger a pipeline whenever an Argo CD application enters a failed or error state. Perhaps you’d like such a pipeline to gather a log bundle or open a ticket.
The goal of this article is to show you how you can use events in Argo CD to trigger pipelines in Codefresh.
Prerequisites
To follow along with this article, you should already have a Codefresh account and be using our GitOps Runtime to deploy your Argo CD Applications.
The Argo CD Notifications component is disabled by default. To enable it, add the following Helm values to your GitOps Runtime configuration:
... argo-cd: notifications: enabled: true secret: create: false ...
Configure Argo CD Notifications
First, let’s update the secret to add an API Key for authenticating to Codefresh. You can create an API Key in the Codefresh UI by navigating to the Settings area at the bottom-left, then User Settings, and then API Keys.
Now go ahead and create the secret:
runtime_ns="<the runtime ns>" codefresh_token="<the codefresh token>" kubectl apply -n $runtime_ns -f - << EOF apiVersion: v1 kind: Secret metadata: name: argocd-notifications-secret stringData: codefresh-token: $codefresh_token type: Opaque EOF
Once done, you should see a secret like this:
Next, let’s create a little example pipeline in Codefresh. This is the pipeline that we’ll be triggering from Argo CD Notifications. For illustrative purposes, we’ll have it print out all the “ARGOCD” variables that we’ll be passing in from the event in Argo CD.
version: "1.0" stages: - "test" steps: print_webhook_args: title: Print variables passed from Argo CD stage: "test" image: alpine commands: - env | grep ARGOCD
After you save the pipeline, click the Settings tab and then copy its PIPELINE ID. We’ll need this in a moment.
We’ll be performing all the rest of our configuration in the Helm values of our GitOps Runtime. Let’s go ahead and edit them.
... argo-cd: notifications: enabled: true secret: create: false notifiers: # First part of the webhook: URL endpoint + creds service.webhook.codefresh: | url: https://g.codefresh.io headers: - name: content-type value: application/json - name: charset value: utf-8 - name: Authorization value: $codefresh-token # this looks up the key in argocd-notifications-secret # Second part of the webhook: REST URL path + data to run the pipeline templates: template.codefresh-trigger-rollback-pipeline: | webhook: codefresh: method: POST path: /api/pipelines/run/myProject%2Example-ArgoCD-Notification ## the last section is the full name of your pipeline: <project_name>/<pipeline_name>, URL-encoded body: | { "variables": { "ARGOCD_APP_NAME": "{{.app.metadata.name}}", "ARGOCD_APP_URL": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", "ARGOCD_APP_STATUS": "{{.app.status.operationState.phase}}", "ARGOCD_SYNC_STATUS": "{{.app.status.sync.status}}", "ARGOCD_SYNC_REVISION": "{{.app.status.sync.revision}}", "ARGOCD_SYNC_START_TIME": "{{.app.status.operationState.startedAt}}", "ARGOCD_GIT_URL": "{{.app.spec.source.repoURL}}" } } triggers: # This trigger ties its specified Argo CD events to the webhook above trigger.sync-operation-change: | - when: app.status.operationState.phase in ['Error', 'Failed'] oncePer: app.status.sync.revision send: [codefresh-simple-test-pipeline] subscriptions: - recipients: - codefresh:"" triggers: - sync-operation-change
I’ll explain what’s going on in these code blocks. The first two blocks define our webhook which will communicate with Codefresh:
- service.webhook.codefresh – this service defines the base URL and credentials for connecting to Codefresh. It could be used by multiple templates that make different REST calls to Codefresh.
- template.codefresh-simple-test-pipeline – this template defines the specific REST URL (appended to the base URL) and data that we’ll use to tell Codefresh to run our specific pipeline. You can see that a large part of this data consists of ARGOCD_ variables that we’ll be able to use within the pipeline.
The third block of code, trigger.sync-operation-change ties some events in Argo CD to the webhook defined in the previous 2 blocks. The events we’re specifying here are Error and Failed sync events.
Finally, we’re adding a default subscription to all Argo CD Applications (subscriptions[0]
). You can also granularly define the apps that should get a notification subscription by adding the required annotation. Example:
-
notifications.argoproj.io/subscribe.sync-operation-change.codefresh: ""
Now apply the new configuration to the GitOps Runtime! Whew, we’re almost done. For the Argo CD Notification service to read the updated configuration, we’ll want to restart its pod. Since its pod is controlled by a deployment resource, we can just delete the pod, and the deployment will create a new one for us.
% kubectl get pods NAME READY STATUS RESTARTS AGE argocd-application-controller-0 1/1 Running 0 16d argocd-dex-server-6dc48777d4-gxrfg 1/1 Running 0 16d argocd-notifications-controller-6f8559c959-d949m 1/1 Running 0 5h53m argocd-redis-66b48966cb-cjgw9 1/1 Running 0 16d argocd-repo-server-7b579957d9-2srfq 1/1 Running 0 16d argocd-server-7fdb567cd4-nngbj 1/1 Running 0 16d cf-argocd-agent-fdfc56f7d-hn48x 1/1 Running 31 14d% kubectl -n $runtime_ns delete pod argocd-notifications-controller-6f8559c959-d949m pod "argocd-notifications-controller-6f8559c959-d949m" deleted
Now we’re ready to test!! To create the failure event we’ve defined, we just need to break a manifest in one of the Git repos that Argo CD is syncing. I chose a manifest in one of my teammate’s repositories… doh, sorry Brandon!
This should be enough to trigger our pipeline in Codefresh!
Be Happy!
Now go check the output from your awesome new pipeline, which was just triggered by a failed sync event in Argo CD!
Wow, that looks great. Look at all the rich Argo CD sync information that our pipeline can now access as variables – totally worth the setup effort. And I’m sure Brandon would agree!