keptn-sandbox / argocd-service

0 stars 0 forks source link

ArgoCD integration #1

Open jetzlstorfer opened 3 years ago

jetzlstorfer commented 3 years ago

The default way for Keptn deployments currently is to use Helm for deployments. However, it would be great to have an integration with ArgoCD for deploying the applications, and have Keptn for orchestrating deployments, test, evaluation etc.

Therefore, it is needed that Keptn provides a Git repo that can be leveraged by ArgoCD. From the ArgoCD side, it is necessary to have an integration that sends back a cloud-event to Keptn indicating if the deployment did successfully finish or not. With this information, Keptn can then trigger the next task in a sequence.

High-level overview as presented at GitOpsDays 2021 image

Definition of done

A potential way to approach this issue (research):

  1. create a demo repo with a simple app
  2. investigate ArgoCD API and how to configure ArgoCD (especially the git and credentials) via the API
  3. configure ArgoCD to deploy simple app from demo repo (via the API, libraries or CLI only)
  4. make change in demo repo (e.g., change image tag or replicacount) and have ArgoCD sync these changes
  5. investigate how promotion/multi-stage deployments look in ArgoCD
  6. configure to execute a webhook once a deployment has started via the API
  7. configure to execute a webhook after a deployment has finished (successful or failed) via the API
agrimmer commented 2 years ago

We already have an integration with Argo CD. The tutorial is based on Keptn 0.7.x and can be found here https://tutorials.keptn.sh/tutorials/keptn-argo-cd-deployment-07/index.html?index=..%2F..keptn07x#8

TannerGabriel commented 2 years ago

Current status after doing some research and trying out a few different tools.

Used tools

ArgoCD notification service

Installation

Follow the official documentation for installing the notification service.

Keptn webhook configuration

The Keptn events normally sent using the Helm service will need to be sent using Webhooks, which are triggered by different ArgoCD events (e.g. sync running, sync finished, etc...).

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  trigger.sync-operation-change: |
    - when: app.status.operationState.phase in ['Running']
      send: [keptn-deployment-started]

  service.webhook.keptn: |
    url: URL
    headers:
    - name: x-token
      value: API_TOKEN
    - name: accept
      value: application/json
    - name: Content-Type
      value: application/cloudevents+json
    - name: Cache-Control
      value: no-cache

  template.keptn-deployment-started: |
    webhook:
      keptn:
        method: POST
        path: /api/controlPlane/v1/event
        body: |
          {
            "type": "sh.keptn.event.deployment.started",
            "contenttype": "application/json",
            "specversion": "0.2",
            "source": "test-event",
            "id": "f2b878d3-03c0-4e8f-bc3f-454bc1b5d80d",
            "shkeptncontext": "08735340-6f9e-4b32-97ff-3b6c292bc112",
            "data": {
              "project": "sockshop",
              "stage": "dev",
              "service": "carts",
              "testStrategy": "performance",
              "deploymentStrategy": "direct",
              "tag": "0.10.1",
              "image": "docker.io/keptnexamples/carts",
              "labels": {
                "testid": "12345",
                "buildId": "build17",
                "runby": "JohnDoe"
              },
              "deploymentURILocal": "http://carts.sockshop-staging.svc.cluster.local",
              "deploymentURIPublic":  "https://carts.sockshop-staging.my-domain.com"
            }
          }

The configuration can be added to the ArgoCD notification controller using the following command:

kubectl patch cm argocd-notifications-cm -n argocd --type merge --patch-file keptn_webhooks.yaml

Passing dynamic data to the webhook

Passing dynamic data into the webhook is needed since some parameters like the shkeptncontext need to be the same in both the deployment.started and deployment.finished event. The current documentation of the notification service only shows how to use dynamic data, which is already available in the ArgoCD sync. Searching for a workaround I found the --info parameter on the argocd app sync command, which lets you pass custom information to the Argo sync.

argocd app sync podtatohead --info type=sh.keptn.event.deployment.finished --info testStrategy=functional

Using the dynamic data

I first tried to access the info variables by accessing them the same way you would access internal Argo variables in a webhooks.

"id": "{{.app.status.operationState.operation.info.id}}",

This was not working since the info variable seems to be an array and not a map as I first thought. After talking to the developers about my use-case they were kind enough to implement a function that lets you get the parameter by name called sync.GetInfoItem.

Trigger a webhook manually

Webhooks can also be triggered manually for testing purposes. The only restriction here is that you cannot pass info parameters to the webhook (to my current knowledge), which results in only hard-coded webhooks being testable.

kubectl exec -n argocd -it argocd-notifications-controller --  /app/argocd-notifications template notify keptn-deployment-started podtatohead --recipient keptn:keptn-deployment-started

Note: Make sure to change the pod name before executing the command.

Restrictions / Challanges