2026-03-26 05:32:52 +02:00

8.9 KiB

name, description, user-invocable
name description user-invocable
dot-ai-port-setup Set up Port integrations to sync Kubernetes resources and GitHub Actions to Port.io true

Setup Port Integrations

Set up Port integrations to sync Kubernetes resources and GitHub Actions to Port.io.

Prerequisites

Check the following and instruct the user to install/configure if missing:

  • kubectl - installed and configured with cluster access
  • helm - installed (for checking chart versions)
  • gh - GitHub CLI installed and authenticated
  • Environment variables set:
    • PORT_CLIENT_ID
    • PORT_CLIENT_SECRET

General Guidelines

  • Always check latest versions of third-party tools (Helm charts, GitHub Actions, etc.) before creating manifests. Use helm search repo or check the official documentation.
  • Consult Port MCP tools when in doubt - use them to explore existing blueprints, entities, actions, and integrations.
  • Validate each step before moving to the next - verify resources are created, synced, and working as expected.
  • User actions vs automated: Some steps require user action (marked with "User action required") - present these as instructions, then STOP and wait for user confirmation before proceeding to the next step.

Step 0: Discover Environment

Before starting, discover what tools are available and gather configuration:

  1. GitOps Tool: Check for ArgoCD (argocd namespace) or Flux (flux-system namespace)
  2. ESO: Check for External Secrets Operator CRD and available ClusterSecretStores
  3. Manifest directory: Ask the user where manifests should be stored (e.g., apps/, manifests/, k8s/)
GitOps Tool Deployment Method Self-Service Actions
ArgoCD ArgoCD Application manifests in Git Commit YAML to Git → ArgoCD syncs
Flux Flux HelmRelease/Kustomization in Git Commit YAML to Git → Flux syncs
Neither Manifests in Git + kubectl apply Commit YAML to Git → kubectl apply
ESO Status Secrets Method
Installed with ClusterSecretStore Use ExternalSecret to pull from secret manager
Not installed Create Secret directly with kubectl create secret

Note: Always store manifests in Git for auditability, regardless of GitOps availability.

GitOps Workflow Rules

IMPORTANT: When ArgoCD or Flux is detected, NEVER run kubectl apply on application manifests.

Instead, follow this workflow:

  1. Write manifests to Git - Create the YAML files in the manifest directory
  2. Commit and push - The GitOps tool will detect changes and sync automatically
  3. Verify sync status - Use kubectl get applications -n argocd (ArgoCD) or flux get all (Flux)

For GitOps resources (ArgoCD Applications, Flux Kustomizations/HelmReleases):

  • Discover the deployment pattern by examining existing resources in the cluster
  • Add new manifests to the appropriate watched directory so GitOps syncs them automatically

For Secrets without ESO:

  • Use kubectl create secret directly (secrets cannot be stored unencrypted in Git)

Part 1: Kubernetes Exporter

Step 1: Create Port Credentials Secret

Create a Secret named port-credentials in the port-k8s-exporter namespace with keys PORT_CLIENT_ID and PORT_CLIENT_SECRET.

  • With ESO: Create an ExternalSecret referencing the available ClusterSecretStore
  • Without ESO: Create the Secret directly with kubectl create secret

Step 2: Deploy the K8s Exporter

Deploy the port-k8s-exporter Helm chart from https://port-labs.github.io/helm-charts.

Key Helm values:

  • secret.useExistingSecret: true and secret.name: port-credentials
  • overwriteConfigurationOnRestart: true (forces use of configMap config)
  • stateKey and extraEnv[].CLUSTER_NAME set to cluster identifier
  • configMap.config with resource mappings (see Step 4)

Deployment method based on discovery:

  • ArgoCD: Create ArgoCD Application manifest
  • Flux: Create HelmRepository + HelmRelease manifests
  • Neither: Run helm install then commit values to Git

Step 3: Create Blueprints in Port

Default blueprints (always created by the exporter):

  • cluster (Port concept, not a K8s resource)
  • namespace (from namespaces)
  • workload (from deployments, daemonsets, statefulsets)

Discover and recommend:

  1. Run kubectl api-resources to list all available resources
  2. Exclude resources already covered by defaults (namespaces, deployments, daemonsets, statefulsets)
  3. Present findings to the user with recommendations
  4. Let user select which additional resources to track

Create selected blueprints using Port MCP tools. All blueprints should have:

  • Relation to namespace blueprint
  • creationTimestamp property

Step 4: Configure Resource Mappings

In the Helm values configMap.config, define mappings for the resources selected in Step 3.

For nested resources (arrays inside a resource spec), use itemsToParse:

- kind: your.api/v1/yourresource
  selector:
    query: "true"
  port:
    itemsToParse: .spec.items
    entity:
      mappings:
        - identifier: .item.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME
          blueprint: '"child-blueprint"'
          properties:
            name: .item.name
          relations:
            Parent: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME

Step 5: Configure Blueprint Relations

Analyze exported resources and establish relations:

  • Examine ownerReferences to link child → parent resources
  • Use selector labels to connect Services → Workloads
  • Link Ingress/HTTPRoute → Services via backend references

For each relation:

  1. Add the relation to the blueprint in Port
  2. Add the corresponding JQ mapping in the exporter config

Part 2: GitHub Integration

Sync GitHub workflows, workflow runs, and pull requests to Port.

Step 1: Install Port's GitHub App (User action required)

  1. Go to Port's Data Sources: https://app.port.io/settings/data-sources
  2. Click "+ Data source" → select "GitHub"
  3. Install the GitHub App on your account/organization
  4. Select repositories to sync
  5. Ensure permissions for: actions, checks, pull requests, repository metadata

Step 2: Create GitHub Blueprints

Create blueprints for githubWorkflow, githubWorkflowRun, and githubPullRequest (if not exists) using Port MCP tools. Inspect integration kinds to determine appropriate properties.

Step 3: Configure GitHub Integration Mapping

Use Port REST API to update the integration config with mappings for pull-request, workflow, and workflow-run kinds.

Step 4: Trigger Integration Resync

After creating blueprints, trigger a resync so the integration populates them with data. Use the Port API:

# Get access token
curl -s -X POST 'https://api.getport.io/v1/auth/access_token' \
  -H 'Content-Type: application/json' \
  -d '{"clientId": "'"$PORT_CLIENT_ID"'", "clientSecret": "'"$PORT_CLIENT_SECRET"'"}' \
  | jq -r '.accessToken' > ./port_access_token.txt

# Trigger resync (replace INTEGRATION_ID with actual ID)
curl -s -X PATCH 'https://api.getport.io/v1/integration/INTEGRATION_ID' \
  -H "Authorization: Bearer $(cat ./port_access_token.txt)" \
  -H 'Content-Type: application/json' \
  -d '{}'

# Cleanup
rm -f ./port_access_token.txt

Get the integration ID from mcp__port-vscode-eu__list_integrations.


Part 3: Self-Service Actions for CRDs

Create Port self-service actions that trigger GitHub workflows to manage CRD manifests.

Step 0: Configure GitHub Repository Secrets

Use gh secret set to add required secrets:

  • PORT_CLIENT_ID - Port client ID
  • PORT_CLIENT_SECRET - Port client secret
  • KUBE_CONFIG - (Only for non-GitOps) Base64-encoded kubeconfig

Step 1: Create GitHub Workflows

Create workflow for each CRD with workflow_dispatch trigger accepting:

  • action (create/update/delete)
  • name, namespace
  • Resource-specific inputs
  • port_run_id

Workflow steps:

  1. Checkout repository
  2. Report "RUNNING" status to Port using port-labs/port-github-action@v1
  3. Create/update/delete manifest in the configured manifest directory
  4. Commit and push to Git
  5. Non-GitOps only: Run kubectl apply or kubectl delete
  6. Report "SUCCESS" or "FAILURE" to Port

Step 2: Create Port Self-Service Actions

Create 3 actions per CRD using Port MCP tools:

  • CREATE - Creates new resources (no entity context)
  • DAY-2 - Updates existing resources (has entity context)
  • DELETE - Deletes resources (has entity context)

Key template expressions:

  • {{ .inputs.fieldName }} - User input value
  • {{ .run.id }} - Port action run ID
  • {{ .entity.identifier }} - Entity identifier (for DAY-2/DELETE)
  • {{ .entity.identifier | split("-") | last }} - Extract resource name from identifier

For DAY-2 actions, pre-populate inputs with current entity values:

"default": {
  "jqQuery": ".entity.properties.someField // \"default_value\""
}