Argo CD

An integration guide for Argo CD.

Introduction

This document provides step-by-step instructions for integrating your IDP software with ArgoCD. The integration can be achieved through two methods:

  1. Synchronous Method: Fetching data using a service account token.

  2. Asynchronous Method: Receiving data via webhooks.

Ideally for best performance and up to the date information you should have both methods enabled.

Before proceeding, ensure you have the following information:

  • Plugin Name: A unique identifier for your application.

  • BaseURL: The public URL of your ArgoCD server.

  • Account Token: A token with read permissions for ArgoCD.

  • Webhook Token: A token for receiving live changes via webhooks.

Method 1: Synchronous Data Fetching

Creating a Service Account in ArgoCD

To fetch data synchronously, you need to create a service account in ArgoCD with read permissions.

Steps:

  1. Create a Service Account:

  2. Set the Token in IDP Software:

    • After creating the service account and generating the token, enter this token in plugin configuration as the 'Account Token'.

Method 2: Asynchronous Data Fetching via Webhooks

Setting Up Notifications Service in ArgoCD

For asynchronous data fetching, configure the notifications service in ArgoCD.

Requirements:

  • ArgoCD version 2.10 or later: Use the built-in notifications controller.

  • Earlier versions of ArgoCD: Install the argocd-notifications helm chart.

Installation:

  • For ArgoCD 2.10 or later, refer to the Notifications Controller Documentation.

  • For earlier versions, use the Helm chart available at ArgoCD Notifications Documentation, with the chart details:

    chart      = "argocd-notifications"
    repository = "https://argoproj.github.io/argo-helm"
    version    = "1.8.1"

  • Configure values.yaml

    secret:
      create: true
      annotations: {}
      name: ""
      items:
        webhooks-token: <WEBHOOK_API_TOKEN_ON_https://web-env-dev.rely.io/settings>
    
    notifiers:
      service.webhook.sync-running:
        url: https://magneto.rely.io/api/v1/webhooks/argocd
        headers:
          - name: Content-Type
            value: application/json
          - name: Authorization
            value: Bearer $webhooks-token
    
    subscriptions:
      # subscription for on-sync-status-unknown trigger notifications
      - recipients:
        - sync-running
        triggers:
          - on-sync-running
          - on-sync-succeeded
          - on-sync-failed
          - on-sync-status-unknown
          - on-deployed
          - on-health-degraded
          - on-created
          - on-deleted
    
    templates:
      template.app-deleted: |
        webhook:
          sync-running:
            method: POST
            body: |
              {
                "type": "deleted",
                "metadata": {
                  "name": "{{.app.metadata.name}}",
                  "namespace": "{{.app.spec.destination.namespace}}",
                  "annotations": {{ toJson .app.metadata.annotations }},
                  "labels": {{ toJson .app.metadata.labels }},
                  "creationTimestamp": "{{.app.metadata.creationTimestamp}}"
                }
              }
      template.app-sync-running: |
        webhook:
          sync-running:
            method: POST
            body: |
    					 {
                "type": "generic",
                "metadata": {
                  "name": "{{.app.metadata.name}}",
                  "namespace": "{{.app.spec.destination.namespace}}",
                  "annotations": {{ toJson .app.metadata.annotations }},
                  "labels": {{ toJson .app.metadata.labels }},
                  "creationTimestamp": "{{.app.metadata.creationTimestamp}}",
                  "ownerReferences": {{ toJson .app.metadata.ownerReferences }}
                },
                "spec": {
                  "project": "{{.app.spec.project}}",
                  "source": {
                    "repoURL": "{{.app.spec.source.repoURL}}",
                    "path": "{{.app.spec.source.path}}",
                    "targetRevision": "{{.app.spec.source.targetRevision}}"
                  },
                  "destination": {
                    "server": "{{.app.spec.destination.server}}",
                    "namespace": "{{.app.spec.destination.namespace}}"
                  },
                  "syncPolicy": {{ toJson .app.spec.syncPolicy }}
                },
                "status": {
                  "conditions": {{ toJson .app.status.conditions | default "[]" }},
                  "health": {
                    "status": "{{.app.status.health.status}}",
                    "message": "{{.app.status.health.message}}"
                  },
                  "operationState": {
                    "finishedAt": "{{.app.status.operationState.finishedAt}}",
                    "startedAt": "{{.app.status.operationState.startedAt}}",
                    "message": "{{.app.status.operationState.message}}",
                    "phase": "{{.app.status.operationState.phase}}",
                    "syncResult": {
                      "revision": "{{.app.status.operationState.operation.sync.revision}}"
                    }
                  },
                  "sync": {
                    "status": "{{.app.status.sync.status}}"
                  }
                }
              }
    
    triggers:
      trigger.on-created: |
        - description: Application is created.
          send:
          - app-sync-running
          when: true
      trigger.on-deleted: |
        - description: Application is deleted.
          send:
          - app-deleted
          when: app.metadata.deletionTimestamp != nil
      trigger.on-deployed: |
        - description: Application is synced and healthy. Triggered once per commit.
          send:
          - app-sync-running
          when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
      trigger.on-health-degraded: |
        - description: Application has degraded
          send:
          - app-sync-running
          when: app.status.health.status == 'Degraded'
      trigger.on-sync-failed: |
        - description: Application syncing has failed
          send:
          - app-sync-running
          when: app.status.operationState.phase in ['Error', 'Failed']
      trigger.on-sync-running: |
        - description: Application syncing has succeeded
          send:
          - app-sync-running
          when: app.status.operationState.phase in ['Running']
      trigger.on-sync-status-unknown: |
        - description: Application status is 'Unknown'
          send:
          - app-sync-running
          when: app.status.sync.status == 'Unknown'
      trigger.on-sync-succeeded: |
        - description: Application syncing has succeeded
          send:
          - app-sync-running
          when: app.status.operationState.phase in ['Succeeded']
      defaultTriggers: |
        - on-sync-status-unknown

Last updated