Trigger a Codefresh Pipeline from Argo CD

Trigger a Codefresh Pipeline from Argo CD

6 min read

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 Argo CD for GitOps-style deployments to Kubernetes.

Earlier this year, the Argo team released Argo CD Notifications, which is an official add-on tool for alerting on Argo CD state changes. In this article, we’ll be leveraging this tool to watch for an example event and trigger a corresponding pipeline in Codefresh.

If you haven’t already installed Argo CD Notifications, then I recommend you follow this quick installation guide from the documentation: https://argocd-notifications.readthedocs.io/en/stable/#getting-started. The installation consists primarily of applying 2 manifest files. Sometimes the documentation can lag behind the releases slightly, so I also recommend that you use the manifest files from the latest release, which can be found here: https://github.com/argoproj-labs/argocd-notifications/releases.

Configure Argo CD Notifications

Argo CD Notifications should be installed into the same namespace as Argo CD, which by default is called argocd. We’ll be configuring it via a Secret and a ConfigMap within this namespace.

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 edit the secret.

kubectl -n argocd edit secret argocd-notifications-secret

In your editor, scroll down to the bottom and add a stringData: section with a single key:value pair. Call the key codefresh-api-key. For its value, paste in your Codefresh API Key.

codefresh-api-key
Codefresh API Key

Save the Secret and exit.

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.

pipeline-settings
Pipeline Settings

We’ll be performing all the rest of our configuration via the ConfigMap I mentioned. Let’s go ahead and edit it.

kubectl edit -n argocd cm argocd-notifications-cm

If you followed the aforementioned install guide for Argo CD Notifications, then the data section of this ConfigMap will already contain lots of code. Copy the 3 code blocks from below, and append them to the end of your data section.

  # 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-api-key  # this looks up the key in argocd-notifications-secret

  # Second part of the webhook: REST URL path + data to run the pipeline
  template.codefresh-simple-test-pipeline: |
    webhook:
      codefresh:
        method: POST
        path: /api/builds/my-build-id
        body: |
          {
            "serviceId": "my-build-id",
            "type": "build",

            "trigger": "my-trigger-name",
            "repoOwner": "my-repo-account",
            "repoName": "my-repo-name",
            "branch": "master",

            "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}}"
            }
          }

  # 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]

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.

Before you save the ConfigMap, we need to make some changes. Replace all instances of my-build-id (there should be two) with the Pipeline ID that you copied previously (it was 6061fd6a9732973e2e6fde89 in the previous example screenshot).

If the pipeline you created earlier has a trigger, then we’ll need to update all 4 trigger-related values. If it doesn’t have a trigger (or if you want to ignore the trigger when you run the pipeline), then you can just delete these 4 lines.

            "trigger": "my-trigger-name",
            "repoOwner": "my-repo-account",
            "repoName": "my-repo-name",
            "branch": "master",

Here is a pipeline trigger that you can use as an example:

pipeline-trigger
Pipeline Trigger

For this example, you would update the trigger-related values like this:

            "trigger": "PushCommits",
            "repoOwner": "salesdemocf",
            "repoName": "argo-voting-app",
            "branch": "master",

 

Now save and exit the ConfigMap! Whew, we’re almost done. For the ArgoCD Notification service to read the updated ConfigMap, 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 argocd 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!

argocd-state
ArgoCD state

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!

freestyle-step
Freestyle step

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!

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Build your GitOps skills and credibility today with a GitOps Certification.

Get GitOps Certified

Ready to Get Started?
  • safer deployments
  • More frequent deployments
  • resilient deployments