ArgoCD
Port's ArgoCD integration allows you to model ArgoCD resources in your software catalog and ingest data into them.
Overviewโ
This integration allows you to:
- Map and organize your desired ArgoCD resources and their metadata in Port (see supported resources below).
- Watch for ArgoCD object changes (create/update/delete) in real-time, and automatically apply the changes to your software catalog.
Supported resourcesโ
The resources that can be ingested from ArgoCD into Port are listed below. It is possible to reference any field that appears in the API responses linked below in the mapping configuration.
Prerequisitesโ
Generate an ArgoCD tokenโ
- 
Navigate to <serverURL>/settings/accounts/<user>. For example, if you access your ArgoCD athttps://localhost:8080, you should navigate tohttps://localhost:8080/settings/accounts/<user>
- 
The user should have apiKeycapabilities to allow generating authentication tokens for API access. If you don't have a user created yet, follow the guide on how to create a new ArgoCD user
- 
Newly created users may have limited scope to resources by default. For that reason, You will need to configure the RBAC policy for the new user by following this guide 
- 
Ensure that the policy definition grants enough permission to readresources such asapplications,clusters,projects,repositoriesetc.
- 
Under Tokens on your ArgoCD UI, Click Generate New to create a new token for the user or use the CLI: argocd account generate-token --account <username>
- 
Create an ArgoCD user with readonly permissions - Create an argocd-user.yamlfile with the below manifest to create a new userport-ocean-user
 Create user manifest (click to expand)apiVersion: v1
 kind: ConfigMap
 metadata:
 name: argocd-cm
 namespace: argocd
 labels:
 app.kubernetes.io/name: argocd-cm
 app.kubernetes.io/part-of: argocd
 data:
 # add an additional local user with apiKey and login capabilities
 # apiKey - allows generating API keys
 # login - allows to login using UI
 accounts.port-ocean-user: apiKey, login
 accounts.port-ocean-user.enabled: "true"- Apply the manifest with kubectlto create the user:
 kubectl apply -f argocd-user.yaml- Grant read only RBAC policy to the new user using the below manifest file (argocd-rbac-cm.yaml)
 RBAC policy to grant readonly role to the new user (click to expand)apiVersion: v1
 kind: ConfigMap
 metadata:
 name: argocd-rbac-cm
 namespace: argocd
 data:
 policy.default: role:readonly
 policy.csv: |
 p, role:read-only-role, applications, *, */*, allow
 p, role:read-only-role, clusters, get, *, allow
 p, role:read-only-role, repositories, get, *, allow
 p, role:read-only-role, projects, get, *, allow
 p, role:read-only-role, logs, get, *, allow
 g, port-ocean-user, role:read-only-role- Apply the argocd-rbac-cm.yamlmanifest withkubectl:
 kubectl apply -f argocd-rbac-cm.yaml- Go to your ArgoCD UI to generate a new token for the user or use the CLI
 argocd account generate-token --account <username>
- Create an 
Setupโ
Choose one of the following installation methods:
Not sure which method is right for your use case? Check the available installation methods.
- Self-hosted
- CI
Using this installation method means that the integration will be able to update Port in real time using webhooks.
Prerequisites
To install the integration, you need a Kubernetes cluster that the integration's container chart will be deployed to.
Please make sure that you have kubectl and helm installed on your machine, and that your kubectl CLI is connected to the Kubernetes cluster where you plan to install the integration.
If you are having trouble installing this integration, please refer to these troubleshooting steps.
For details about the available parameters for the installation, see the table below.
- Helm
- ArgoCD
To install the integration using Helm:
- 
Go to the Argocd data source page in your portal. 
- 
Select the Real-time and always onmethod:  
- 
A helmcommand will be displayed, with default values already filled out (e.g. your Port client ID, client secret, etc).
 Copy the command, replace the placeholders with your values, then run it in your terminal to install the integration.
BaseUrl & webhook configuration
integration.config.appHost is deprecated: Please use liveEvents.baseUrl for webhook URL settings instead.
In order for the Argocd integration to update the data in Port on real-time changes in Argocd, you need to specify the liveEvents.baseUrl parameter.
The liveEvents.baseUrl parameter should be set to the url of your Argocd integration instance. Your integration instance needs to have the option to setup webhooks via http requests/recieve http requests , so please configure your network accordingly.
To test webhooks or live event delivery to your local environment, expose your local pod or service to the internet using ngrok:
ngrok http http://localhost:8000
This will provide a public URL you can use for webhook configuration and external callbacks during development.
If liveEvents.baseUrl is not provided, the integration will continue to function correctly. In such a configuration, to retrieve the latest information from the target system, the scheduledResyncInterval parameter has to be set, or a manual resync will need to be triggered through Port's UI.
Scalable Mode for Large Integrations
If you are deploying the integration at scale and want to decouple the resync process from the live events process (recommended for large or high-throughput environments), you can enable scalable mode by adding the following flags to your Helm install command:
  --set workload.kind="CronJob"  \
  --set workload.cron.resyncTimeoutMinutes=60  \
  --set scheduledResyncInterval="'*/60 * * * *'"  \
  --set liveEvents.worker.enabled=true
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance of Port API will be used.
Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.
- If you use the EU region of Port (https://app.port.io), your API URL is https://api.port.io.
- If you use the US region of Port (https://app.us.port.io), your API URL is https://api.us.port.io.
To install the integration using ArgoCD:
- Create a values.yamlfile inargocd/my-ocean-argocd-integrationin your git repository with the content:
Remember to replace the placeholders for TOKEN and SERVER_URL, which represents your ArgoCD API token and server url respectively.
initializePortResources: true
scheduledResyncInterval: 120
integration:
  identifier: my-ocean-argocd-integration
  type: argocd
  eventListener:
    type: POLLING
  config:
    serverUrl: SERVER_URL
  secrets:
    token: TOKEN
- Install the my-ocean-argocd-integrationArgoCD Application by creating the followingmy-ocean-argocd-integration.yamlmanifest:
Remember to replace the placeholders for YOUR_PORT_CLIENT_ID YOUR_PORT_CLIENT_SECRET and YOUR_GIT_REPO_URL.
Multiple sources ArgoCD documentation can be found here.
ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-ocean-argocd-integration
  namespace: argocd
spec:
  destination:
    namespace: my-ocean-argocd-integration
    server: https://kubernetes.default.svc
  project: default
  sources:
  - repoURL: 'https://port-labs.github.io/helm-charts/'
    chart: port-ocean
    targetRevision: 0.1.18
    helm:
      valueFiles:
      - $values/argocd/my-ocean-argocd-integration/values.yaml
      parameters:
        - name: port.clientId
          value: YOUR_PORT_CLIENT_ID
        - name: port.clientSecret
          value: YOUR_PORT_CLIENT_SECRET
        - name: port.baseUrl
          value: https://api.getport.io
  - repoURL: YOUR_GIT_REPO_URL
    targetRevision: main
    ref: values
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance of Port API will be used.
Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.
- If you use the EU region of Port (https://app.port.io), your API URL is https://api.port.io.
- If you use the US region of Port (https://app.us.port.io), your API URL is https://api.us.port.io.
- Apply your application manifest with kubectl:
kubectl apply -f my-ocean-argocd-integration.yaml
This table summarizes the available parameters for the installation. Note the parameters specific to this integration, they are last in the table.
| Parameter | Description | Required | 
|---|---|---|
| port.clientId | Your port client id | โ | 
| port.clientSecret | Your port client secret | โ | 
| port.baseUrl | Your Port API URL - https://api.getport.iofor EU,https://api.us.getport.iofor US | โ | 
| initializePortResources | Default true, When set to true the integration will create default blueprints and the port App config Mapping | โ | 
| sendRawDataExamples | Enable sending raw data examples from the third party API to port for testing and managing the integration mapping. Default is true | โ | 
| integration.identifier | Change the identifier to describe your integration | โ | 
| integration.type | The integration type | โ | 
| integration.eventListener.type | The event listener type | โ | 
| integration.secrets.token | The ArgoCD API token, docs can be found here | โ | 
| integration.config.serverUrl | The ArgoCD server url | โ | 
| integration.config.ignoreServerError | Whether to ignore server errors when fetching data from ArgoCD. The default value is falsemeaning the integration will raise exceptions and fail the resync event | โ | 
| scheduledResyncInterval | The number of minutes between each resync | โ | 
This workflow/pipeline will run the ArgoCD integration once and then exit, this is useful for scheduled ingestion of data.
- GitHub
- Jenkins
- GitLab
Make sure to configure the following Github Secrets:
| Parameter | Description | Required | 
|---|---|---|
| OCEAN__INTEGRATION__CONFIG__TOKEN | The ArgoCD API token | โ | 
| OCEAN__INTEGRATION__CONFIG__SERVER_URL | The ArgoCD server URL | โ | 
| OCEAN__INTEGRATION__CONFIG__IGNORE_SERVER_ERROR | Whether to ignore server errors when fetching data from ArgoCD. The default value is falsemeaning the integration will raise exceptions and fail the resync event | โ | 
| OCEAN__INITIALIZE_PORT_RESOURCES | Default true, When set to false the integration will not create default blueprints and the port App config Mapping | โ | 
| OCEAN__INTEGRATION__IDENTIFIER | Change the identifier to describe your integration, if not set will use the default one | โ | 
| OCEAN__PORT__CLIENT_ID | Your port client id | โ | 
| OCEAN__PORT__CLIENT_SECRET | Your port client secret | โ | 
| OCEAN__PORT__BASE_URL | Your Port API URL - https://api.getport.iofor EU,https://api.us.getport.iofor US | โ | 
| OCEAN__SEND_RAW_DATA_EXAMPLES | Enable sending raw data examples from the third party API to port for testing and managing the integration mapping. Default is true | โ | 
Here is an example for argocd-integration.yml workflow file:
name: ArgoCD Exporter Workflow
on:
  workflow_dispatch:
  schedule:
    - cron: '0 */1 * * *' # Determines the scheduled interval for this workflow. This example runs every hour.
jobs:
  run-integration:
    runs-on: ubuntu-latest
    timeout-minutes: 30 # Set a time limit for the job
    steps:
      - uses: port-labs/ocean-sail@v1
        with:
          type: 'argocd'
          port_client_id: ${{ secrets.OCEAN__PORT__CLIENT_ID }}
          port_client_secret: ${{ secrets.OCEAN__PORT__CLIENT_SECRET }}
          port_base_url: https://api.getport.io
          config: |
            token: ${{ secrets.OCEAN__INTEGRATION__CONFIG__TOKEN }}
            server_url: ${{ OCEAN__INTEGRATION__CONFIG__SERVER_URL }}
            ignore_server_error: false
Your Jenkins agent should be able to run docker commands.
Make sure to configure the following Jenkins Credentials
of Secret Text type:
| Parameter | Description | Required | 
|---|---|---|
| OCEAN__INTEGRATION__CONFIG__TOKEN | The ArgoCD API token | โ | 
| OCEAN__INTEGRATION__CONFIG__SERVER_URL | The ArgoCD server URL | โ | 
| OCEAN__INTEGRATION__CONFIG__IGNORE_SERVER_ERROR | Whether to ignore server errors when fetching data from ArgoCD. The default value is falsemeaning the integration will raise exceptions and fail the resync event | โ | 
| OCEAN__INITIALIZE_PORT_RESOURCES | Default true, When set to false the integration will not create default blueprints and the port App config Mapping | โ | 
| OCEAN__INTEGRATION__IDENTIFIER | Change the identifier to describe your integration, if not set will use the default one | โ | 
| OCEAN__SEND_RAW_DATA_EXAMPLES | Enable sending raw data examples from the third party API to port for testing and managing the integration mapping. Default is true | โ | 
| OCEAN__PORT__CLIENT_ID | Your port client id | โ | 
| OCEAN__PORT__CLIENT_SECRET | Your port client secret | โ | 
| OCEAN__PORT__BASE_URL | Your Port API URL - https://api.getport.iofor EU,https://api.us.getport.iofor US | โ | 
Here is an example for Jenkinsfile groovy pipeline file:
pipeline {
    agent any
    stages {
        stage('Run ArgoCD Integration') {
            steps {
                script {
                    withCredentials([
                        string(credentialsId: 'OCEAN__INTEGRATION__CONFIG__TOKEN', variable: 'OCEAN__INTEGRATION__CONFIG__TOKEN'),
                        string(credentialsId: 'OCEAN__INTEGRATION__CONFIG__SERVER_URL', variable: 'OCEAN__INTEGRATION__CONFIG__SERVER_URL'),
                        string(credentialsId: 'OCEAN__PORT__CLIENT_ID', variable: 'OCEAN__PORT__CLIENT_ID'),
                        string(credentialsId: 'OCEAN__PORT__CLIENT_SECRET', variable: 'OCEAN__PORT__CLIENT_SECRET'),
                    ]) {
                        sh('''
                            #Set Docker image and run the container
                            integration_type="argocd"
                            version="latest"
                            image_name="ghcr.io/port-labs/port-ocean-${integration_type}:${version}"
                            docker run -i --rm --platform=linux/amd64 \
                                -e OCEAN__EVENT_LISTENER='{"type":"ONCE"}' \
                                -e OCEAN__INITIALIZE_PORT_RESOURCES=true \
                                -e OCEAN__SEND_RAW_DATA_EXAMPLES=true \
                                -e OCEAN__INTEGRATION__CONFIG__TOKEN=$OCEAN__INTEGRATION__CONFIG__TOKEN \
                                -e OCEAN__INTEGRATION__CONFIG__SERVER_URL=$OCEAN__INTEGRATION__CONFIG__SERVER_URL \
                                -e OCEAN__INTEGRATION__CONFIG__IGNORE_SERVER_ERROR=false \
                                -e OCEAN__PORT__CLIENT_ID=$OCEAN__PORT__CLIENT_ID \
                                -e OCEAN__PORT__CLIENT_SECRET=$OCEAN__PORT__CLIENT_SECRET \
                                -e OCEAN__PORT__BASE_URL='https://api.getport.io' \
                                $image_name
                            exit $?
                        ''')
                    }
                }
            }
        }
    }
}
Make sure to configure the following GitLab variables:
| Parameter | Description | Required | 
|---|---|---|
| OCEAN__INTEGRATION__CONFIG__TOKEN | The ArgoCD API token | โ | 
| OCEAN__INTEGRATION__CONFIG__SERVER_URL | The ArgoCD server URL | โ | 
| OCEAN__INTEGRATION__CONFIG__IGNORE_SERVER_ERROR | Whether to ignore server errors when fetching data from ArgoCD. The default value is falsemeaning the integration will raise exceptions and fail the resync event | โ | 
| OCEAN__INITIALIZE_PORT_RESOURCES | Default true, When set to false the integration will not create default blueprints and the port App config Mapping | โ | 
| OCEAN__SEND_RAW_DATA_EXAMPLES | Enable sending raw data examples from the third party API to port for testing and managing the integration mapping. Default is true | โ | 
| OCEAN__INTEGRATION__IDENTIFIER | Change the identifier to describe your integration, if not set will use the default one | โ | 
| OCEAN__PORT__CLIENT_ID | Your port client id | โ | 
| OCEAN__PORT__CLIENT_SECRET | Your port client secret | โ | 
| OCEAN__PORT__BASE_URL | Your Port API URL - https://api.getport.iofor EU,https://api.us.getport.iofor US | โ | 
Here is an example for .gitlab-ci.yml pipeline file:
default:
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  before_script:
    - docker info
    
variables:
  INTEGRATION_TYPE: argocd
  VERSION: latest
stages:
  - ingest
ingest_data:
  stage: ingest
  variables:
    IMAGE_NAME: ghcr.io/port-labs/port-ocean-$INTEGRATION_TYPE:$VERSION
  script:
    - |
      docker run -i --rm --platform=linux/amd64 \
        -e OCEAN__EVENT_LISTENER='{"type":"ONCE"}' \
        -e OCEAN__INITIALIZE_PORT_RESOURCES=true \
        -e OCEAN__SEND_RAW_DATA_EXAMPLES=true \
        -e OCEAN__INTEGRATION__CONFIG__TOKEN=$OCEAN__INTEGRATION__CONFIG__TOKEN \
        -e OCEAN__INTEGRATION__CONFIG__SERVER_URL=$OCEAN__INTEGRATION__CONFIG__SERVER_URL \
        -e OCEAN__INTEGRATION__CONFIG__IGNORE_SERVER_ERROR=false \
        -e OCEAN__PORT__CLIENT_ID=$OCEAN__PORT__CLIENT_ID \
        -e OCEAN__PORT__CLIENT_SECRET=$OCEAN__PORT__CLIENT_SECRET \
        -e OCEAN__PORT__BASE_URL='https://api.getport.io' \
        $IMAGE_NAME
  rules: # Run only when changes are made to the main branch
    - if: '$CI_COMMIT_BRANCH == "main"'
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance of Port API will be used.
Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.
- If you use the EU region of Port (https://app.port.io), your API URL is https://api.port.io.
- If you use the US region of Port (https://app.us.port.io), your API URL is https://api.us.port.io.
Configurationโ
Port integrations use a YAML mapping block to ingest data from the third-party api into Port.
The mapping makes use of the JQ JSON processor to select, modify, concatenate, transform and perform other operations on existing fields and values from the integration API.
Default mapping configurationโ
This is the default mapping configuration for this integration:
Default mapping configuration (Click to expand)
deleteDependentEntities: true
createMissingRelatedEntities: true
enableMergeEntity: true
resources:
- kind: cluster
  selector:
    query: 'true'
  port:
    entity:
      mappings:
        identifier: .name
        title: .name
        blueprint: '"argocdCluster"'
        properties:
          applicationsCount: .info.applicationsCount
          serverVersion: .serverVersion
          labels: .labels
          updatedAt: .connectionState.attemptedAt
          server: .server
- kind: cluster
  selector:
    query: 'true'
  port:
    entity:
      mappings:
        identifier: .name + "-" + .item | tostring
        title: .name + "-" + .item
        blueprint: '"argocdNamespace"'
        relations:
          cluster: .name
    itemsToParse: .namespaces
- kind: project
  selector:
    query: 'true'
  port:
    entity:
      mappings:
        identifier: .metadata.name
        title: .metadata.name
        blueprint: '"argocdProject"'
        properties:
          createdAt: .metadata.creationTimestamp
          description: .spec.description
- kind: application
  selector:
    query: 'true'
  port:
    entity:
      mappings:
        identifier: .metadata.uid
        title: .metadata.name
        blueprint: '"argocdApplication"'
        properties:
          gitRepo: .spec.source.repoURL
          gitPath: .spec.source.path
          destinationServer: .spec.destination.server
          revision: .status.sync.revision
          targetRevision: .spec.source.targetRevision
          syncStatus: .status.sync.status
          healthStatus: .status.health.status
          createdAt: .metadata.creationTimestamp
          labels: .metadata.labels
          annotations: .metadata.annotations
        relations:
          project: .spec.project
          namespace: .metadata.namespace
          environment:
            combinator: '"and"'
            rules:
            - operator: '"="'
              property: '"argoCluster"'
              value: .spec.destination.server
          cluster:
            combinator: '"and"'
            rules:
            - operator: '"="'
              property: '"server"'
              value: .spec.destination.server
- kind: application
  selector:
    query: 'true'
  port:
    entity:
      mappings:
        identifier: .metadata.uid + "-" + (.item.id | tostring)
        title: .metadata.name + "-" + (.item.id | tostring)
        blueprint: '"argocdDeploymentHistory"'
        properties:
          deployedAt: .item.deployedAt
          deployStartedAt: .item.deployStartedAt
          revision: .item.source.repoURL + "/commit/" + .item.revision
          initiatedBy: .item.initiatedBy.username
          repoURL: .item.source.repoURL
          sourcePath: .item.source.path
        relations:
          application: .metadata.uid
          anotherRelation: .item.source.repoURL
    itemsToParse: .status.history // []
Capabilitiesโ
Configure real-time updatesโ
Currently, the ArgoCD REST API lacks support for programmatic webhook creation. To set up a webhook configuration in ArgoCD for sending notifications to the Ocean integration, follow these steps:
- Install ArgoCD notifications manifest;
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/release-1.0/manifests/install.yaml
- Install ArgoCD triggers and templates manifest;
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/release-1.0/catalog/install.yaml
- Use kubectlto connect to the Kubernetes cluster where your ArgoCD instance is deployed;
kubectl config use-context <your-cluster-context>
- Set the current namespace to your ArgoCD namespace, use the following command;
kubectl config set-context --current --namespace=<your-namespace>
- 
Create a YAML file (e.g. argocd-webhook-config.yaml) that configures the webhook notification service. The example below shows how to set up a webhook to send real-time events whenever ArgoCD applications are updated. The YAML file includes the following components:- Notification service definition;
- Template for the webhook message body;
- Trigger definitions;
- Subscriptions to the notifications.
 Here's an example YAML. Make sure to replace <WEBHOOK_URL>with the actual URL of the ingress or service where the ocean integration will be deployed. By default, incoming webhook events are sent to/integration/webhookpath in Ocean so do not replace the path parameter.webhook manifest fileapiVersion: v1
 kind: ConfigMap
 metadata:
 name: argocd-notifications-cm
 data:
 trigger.on-sync-operation-change: |
 - description: Application syncing has updated
 send:
 - app-status-change
 when: app.status.operationState.phase in ['Error', 'Failed', 'Succeeded', 'Running']
 trigger.on-deployed: |
 - description: Application is synced and healthy
 send:
 - app-status-change
 when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
 trigger.on-health-degraded: |
 - description: Application has degraded
 send:
 - app-status-change
 when: app.status.health.status == 'Degraded'
 service.webhook.port-ocean: |
 url: <WEBHOOK_URL>
 headers:
 - name: Content-Type
 value: application/json
 template.app-status-change: |
 webhook:
 port-ocean:
 method: POST
 path: /integration/webhook
 body: |
 {
 "action": "upsert",
 "application_name": "{{.app.metadata.name}}"
 }
 subscriptions: |
 - recipients:
 - port-ocean
 triggers:
 - on-deployed
 - on-health-degraded
 - on-sync-operation-change
- 
Use kubectlto apply the YAML file to your cluster. Run the following command, replacing<your-namespace>with your ArgoCD namespace and<path-to-yaml-file>with the actual path to your YAML file:
kubectl apply -n <your-namespace> -f <path-to-yaml-file>
This command deploys the webhook notification configuration to your ArgoCD notification configmap (argocd-notifications-cm), allowing Ocean to receive real-time events.
Monitoring and sync statusโ
To learn more about how to monitor and check the sync status of your integration, see the relevant documentation.
Examplesโ
To view and test the integration's mapping against examples of the third-party API responses, use the jq playground in your data sources page. Find the integration in the list of data sources and click on it to open the playground.
Examples of blueprints and the relevant integration configurations can be found on the argocd examples page
Relevant Guidesโ
For relevant guides and examples, see the guides section.
Alternative installation via webhookโ
While the Ocean integration described above is the recommended installation method, you may prefer to use a webhook to ingest data from ArgoCD. If so, use the following instructions:
Webhook installation (click to expand)
In this example you are going to create a webhook integration between ArgoCD and Port, which will ingest application entities and map them to your ArgoCD projects.
Port configuration
Create the following blueprint definition:Project blueprint
{
  "identifier": "argocdProject",
  "description": "This blueprint represents an ArgoCD Project",
  "title": "ArgoCD Project",
  "icon": "Argo",
  "schema": {
    "properties": {
      "description": {
        "title": "Description",
        "description": "Project description",
        "type": "string",
        "icon": "DefaultProperty"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "relations": {}
}Application blueprint
{
  "identifier": "argocdApplication",
  "description": "This blueprint represents an ArgoCD Application",
  "title": "ArgoCD Application",
  "icon": "Argo",
  "schema": {
    "properties": {
      "gitRepo": {
        "type": "string",
        "format": "url",
        "icon": "Git",
        "title": "Repository URL",
        "description": "The URL of the Git repository containing the application source code"
      },
      "gitPath": {
        "type": "string",
        "title": "Path",
        "description": "The path within the Git repository where the application manifests are located"
      },
      "destinationServer": {
        "type": "string",
        "title": "Destination Server",
        "format": "url"
      },
      "namespace": {
        "type": "string",
        "title": "Namespace"
      },
      "syncStatus": {
        "type": "string",
        "title": "Sync Status",
        "enum": ["Synced", "OutOfSync", "Unknown"],
        "enumColors": {
          "Synced": "green",
          "OutOfSync": "red",
          "Unknown": "lightGray"
        },
        "description": "The sync status of the application"
      },
      "healthStatus": {
        "type": "string",
        "title": "Health Status",
        "enum": [
          "Healthy",
          "Missing",
          "Suspended",
          "Degraded",
          "Progressing",
          "Unknown"
        ],
        "enumColors": {
          "Healthy": "green",
          "Missing": "yellow",
          "Suspended": "purple",
          "Degraded": "red",
          "Progressing": "blue",
          "Unknown": "lightGray"
        },
        "description": "The health status of the application"
      },
      "createdAt": {
        "title": "Created At",
        "type": "string",
        "format": "date-time"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "relations": {
    "project": {
      "title": "Project",
      "target": "argocdProject",
      "required": false,
      "many": false
    }
  }
}
Create the following webhook configuration using Port UI Basic details tab - fill the following details: Integration configuration tab - fill the following JQ mapping: Click Save at the bottom of the page.Application webhook configuration
ArgoCD Application Mapper;argocd_application_mapper;A webhook configuration to map ArgoCD applications to Port;Argo;[
  {
    "blueprint": "argocdApplication",
    "filter": "true",
    "entity": {
      "identifier": ".body.uid | tostring",
      "title": ".body.name | tostring",
      "properties": {
        "gitRepo": ".body.git_repo",
        "gitPath": ".body.git_path",
        "destinationServer": ".body.destination_server",
        "namespace": ".body.namespace",
        "syncStatus": ".body.sync_status",
        "healthStatus": ".body.health_status",
        "createdAt": ".body.created_at"
      },
      "relations": {
        "project": ".body.project"
      }
    }
  }
]
Create a webhook in ArgoCD
To set up a webhook configuration in ArgoCD for sending notifications to Port, follow these steps:
Prerequisite
- You have access to a Kubernetes cluster where ArgoCD is deployed.
- You have kubectlinstalled and configured to access your cluster.
Steps
- Install ArgoCD notifications manifest;
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/release-1.0/manifests/install.yaml
- Install ArgoCD triggers and templates manifest;
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/release-1.0/catalog/install.yaml
- Use kubectlto connect to the Kubernetes cluster where your ArgoCD instance is deployed;
kubectl config use-context <your-cluster-context>
- Set the current namespace to your ArgoCD namespace, use the following command;
kubectl config set-context --current --namespace=<your-namespace>
- 
Create a YAML file (e.g. argocd-webhook-config.yaml) that configures the webhook notification service. The example below shows how to set up a webhook to send real-time events whenever ArgoCD applications are updated. The YAML file includes the following components:- Notification service definition;
- Template for the webhook message body;
- Trigger definitions;
- Subscriptions to the notifications.
 Here's an example YAML. Make sure to replace <YOUR_WEBHOOK_URL>with the value ofurlkey you received after creating the webhook configuration.webhook manifest fileapiVersion: v1
 kind: ConfigMap
 metadata:
 name: argocd-notifications-cm
 data:
 trigger.on-sync-operation-change: |
 - description: Application syncing has updated
 send:
 - app-status-change
 when: app.status.operationState.phase in ['Error', 'Failed', 'Succeeded', 'Running']
 trigger.on-deployed: |
 - description: Application is synced and healthy
 send:
 - app-status-change
 when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
 trigger.on-health-degraded: |
 - description: Application has degraded
 send:
 - app-status-change
 when: app.status.health.status == 'Degraded'
 service.webhook.port-webhook: |
 url: <YOUR_WEBHOOK_URL>
 headers:
 - name: Content-Type
 value: application/json
 template.app-status-change: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "sync_status": "{{.app.status.sync.status}}",
 "health_status": "{{.app.status.health.status}}",
 "git_repo": "{{.app.spec.source.repoURL}}",
 "git_path": "{{.app.spec.source.path}}",
 "destination_server": "{{.app.spec.destination.server}}",
 "created_at": "{{.app.metadata.creationTimestamp}}",
 "project": "{{.app.spec.project}}"
 }
 subscriptions: |
 - recipients:
 - port-webhook
 triggers:
 - on-deployed
 - on-health-degraded
 - on-sync-operation-change
- 
Use kubectlto apply the YAML file to your cluster. Run the following command, replacing<your-namespace>with your ArgoCD namespace and<path-to-yaml-file>with the actual path to your YAML file:
kubectl apply -n <your-namespace> -f <path-to-yaml-file>
This command deploys the webhook notification configuration to your ArgoCD notification configmap (argocd-notifications-cm), allowing Port to receive real-time events.
Done! any change that happens to your applications in ArgoCD will trigger a webhook event to the webhook URL provided by Port. Port will parse the events according to the mapping and update the catalog entities accordingly.
Argocd Events
In this example you are going to create a webhook integration between ArgoCD and Port, which will ingest all events entities and map them to your ArgoCD applications.
Port configuration
Create the following blueprint definition:Events blueprint
{
  "identifier": "argocdEvent",
  "description": "This blueprint represents ArgoCD events",
  "title": "ArgoCD Events",
  "icon": "Argo",
  "schema": {
    "properties": {
      "event": {
        "type": "string",
        "title": "Event Name"
      },
      "namespace": {
        "type": "string",
        "title": "Namespace"
      },
      "description": {
        "type": "string",
        "title": "Description"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "application": {
      "title": "Application",
      "target": "argocdApplication",
      "required": false,
      "many": false
    }
  }
}
Create the following webhook configuration using Port UI Basic details tab - fill the following details: Integration configuration tab - fill the following JQ mapping: Click Save at the bottom of the page.Application webhook configuration
ArgoCD Event Mapper;argocd_event_mapper;A webhook configuration to map ArgoCD events to Port;Argo;[
  {
    "blueprint": "argocdEvent",
    "filter": "true",
    "entity": {
      "identifier": ".body.app_name + \"-\" + .body.event_name | tostring",
      "title": ".body.event_name | tostring",
      "properties": {
        "event": ".body.event_name",
        "namespace": ".body.namespace",
        "description": ".body.description"
      },
      "relations": {
        "application": ".body.uid"
      }
    }
  }
]
Create a webhook in ArgoCD
To set up a webhook configuration in ArgoCD for sending notifications to Port, follow these steps:
Prerequisite
- You have access to a Kubernetes cluster where ArgoCD is deployed.
- You have kubectlinstalled and configured to access your cluster.
Steps
- Install ArgoCD notifications manifest;
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/release-1.0/manifests/install.yaml
- Install ArgoCD triggers and templates manifest;
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/release-1.0/catalog/install.yaml
- Use kubectlto connect to the Kubernetes cluster where your ArgoCD instance is deployed;
kubectl config use-context <your-cluster-context>
- Set the current namespace to your ArgoCD namespace, use the following command;
kubectl config set-context --current --namespace=<your-namespace>
- 
Create a YAML file (e.g. argocd-events-config.yaml) that configures the webhook notification service. The example below shows how to set up a webhook to send real-time events from ArgoCD. The YAML file includes the following components:- Notification service definition;
- Template for the webhook message body;
- Trigger definitions;
- Subscriptions to the notifications.
 Here's an example YAML. Make sure to replace <YOUR_WEBHOOK_URL>with the value ofurlkey you received after creating the webhook configuration.event manifest fileapiVersion: v1
 kind: ConfigMap
 metadata:
 name: argocd-notifications-cm
 data:
 trigger.on-created: |
 - description: Application is created
 send:
 - app-created
 when: true
 oncePer: app.metadata.name
 trigger.on-sync-running: |
 - description: Application is being synced
 send:
 - app-sync-running
 when: app.status.operationState.phase in ['Running']
 trigger.on-sync-succeeded: |
 - description: Application syncing has succeeded
 send:
 - app-sync-succeeded
 when: app.status.operationState.phase in ['Succeeded']
 trigger.on-sync-failed: |
 - description: Application syncing has failed
 send:
 - app-sync-failed
 when: app.status.operationState.phase in ['Error', 'Failed']
 trigger.on-sync-status-unknown: |
 - description: Application status is Unknown
 send:
 - app-sync-status-unknown
 when: app.status.sync.status == 'Unknown'
 trigger.on-deployed: |
 - description: Application is synced and healthy
 send:
 - app-deployed
 when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
 trigger.on-health-degraded: |
 - description: Application has degraded
 send:
 - app-health-degraded
 when: app.status.health.status == 'Degraded'
 trigger.on-deleted: |
 - description: Application is deleted
 send:
 - app-deleted
 when: app.metadata.deletionTimestamp != nil
 oncePer: app.metadata.name
 service.webhook.port-webhook: |
 url: YOUR_WEBHOOK_URL
 headers:
 - name: Content-Type
 value: application/json
 template.app-created: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-created",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application is created"
 }
 template.app-sync-succeeded: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-sync-succeeded",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application syncing has succeeded"
 }
 template.app-sync-running: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-sync-running",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application is being synced"
 }
 template.app-sync-failed: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-sync-failed",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application syncing has failed"
 }
 template.app-health-degraded: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-health-degraded",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application has degraded"
 }
 template.app-deployed: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-deployed",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application is synced healthy"
 }
 template.app-sync-status-unknown: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-sync-status-unknown",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application status is Unknown"
 }
 template.app-deleted: |
 webhook:
 port-webhook:
 method: POST
 body: |
 {
 "uid": "{{.app.metadata.uid}}",
 "event_name": "on-deleted",
 "app_name": "{{.app.metadata.name}}",
 "namespace": "{{.app.metadata.namespace}}",
 "description": "Application deleted"
 }
 subscriptions: |
 - recipients:
 - port-webhook
 triggers:
 - on-created
 - on-deployed
 - on-health-degraded
 - on-sync-failed
 - on-sync-status-unknown
 - on-sync-succeeded
 - on-sync-running
 - on-deleted
- 
Use kubectlto apply the YAML file to your cluster. Run the following command, replacing<your-namespace>with your ArgoCD namespace and<path-to-yaml-file>with the actual path to your YAML file:
kubectl apply -n <your-namespace> -f <path-to-yaml-file>
This command deploys the webhook notification configuration to your ArgoCD notification configmap (argocd-notifications-cm), allowing Port to receive real-time events.
Done! any change that happens to your applications in ArgoCD will trigger a webhook event to the webhook URL provided by Port. Port will parse the events according to the mapping and update the catalog entities accordingly.