Skip to main content

Dependencies

Real applications talk to other things — other services, and managed infrastructure like databases and queues. On DevsPortal you don't look up hostnames or copy connection strings into config. You declare what your Workload needs, and the platform resolves the address, injects it as an environment variable or file, and opens the right network path.

There are two kinds of dependency:

  • Endpoint dependencies — on another component's endpoint.
  • Resource dependencies — on a managed Resource (database, queue, cache, object store).
note

DevsPortal is built on the Control Plane Operator engine. The openchoreo.dev/v1alpha1 Workload resource and occ CLI below are unchanged engine internals.

Portal first, CLI second

The portal UI is the recommended path; the equivalent occ CLI commands follow for scripting.

Declaring dependencies in the portal

In the Create Component wizard (and when editing a component's workload later), the Service Details step lets you add dependencies alongside the component's own endpoints:

  • Endpoint dependency — pick a target component and one of its endpoints, choose the visibility to consume it at, and map the connection details onto environment-variable names.
  • Resource dependency — pick a Resource in the same project and map its outputs onto environment variables or file mounts. If the Resource doesn't exist yet, create it first from Create…Resource under Application Resources:

The Create… page — the Resource template sits under Application Resources

The portal writes the same spec.dependencies block documented below. The rest of this page is the full field reference for that block, whether you fill the form or author the YAML directly.

Endpoint dependencies

When your component consumes another component's endpoint, the platform resolves the target address, injects it into your container as environment variables, and configures the NetworkPolicy that allows the traffic. You never hardcode a service URL.

Declare them under spec.dependencies.endpoints:

apiVersion: openchoreo.dev/v1alpha1
kind: Workload
metadata:
name: storefront
namespace: fedshi
spec:
owner:
projectName: storefront
componentName: storefront
container:
image: registry.idp.fedshi.com/storefront/storefront:2.1.0
endpoints:
http:
type: HTTP
port: 3000
visibility: [external]
dependencies:
endpoints:
- component: cart-api
name: http
visibility: project
envBindings:
address: CART_API_URL

Here the storefront component depends on cart-api's http endpoint. The platform resolves the address and injects it as CART_API_URL. Your code reads that env var — it never needs to know the cluster DNS name.

Dependency fields

FieldRequiredDescription
componentYesName of the target component
nameYesName of the endpoint on that component
visibilityYesScope to consume at — project or namespace
projectNoTarget's project (defaults to your own project)
envBindingsYesMaps connection details to env var names

envBindings can inject any combination of: address (the full connection string), host, port, and basePath. address is the one you'll use most:

envBindings:
address: AUTH_SERVICE_URL # http://host:port/basePath (or host:port for gRPC/TCP/UDP)
host: AUTH_SERVICE_HOST
port: AUTH_SERVICE_PORT

Same-project vs cross-project

The visibility field decides the network scope, and the rule is symmetric: the target endpoint must declare a visibility equal to or broader than what you consume at.

Same project — use project visibility and omit project (it defaults to yours):

dependencies:
endpoints:
- component: cart-api
name: http
visibility: project
envBindings:
address: CART_API_URL

Different project in the same namespace — use namespace visibility and name the target's project:

dependencies:
endpoints:
- component: shared-auth
name: http
visibility: namespace
project: platform-services
envBindings:
address: AUTH_SERVICE_URL
host: AUTH_SERVICE_HOST
port: AUTH_SERVICE_PORT

For this to resolve, the shared-auth Workload must expose its endpoint with namespace (or broader) visibility:

# in the platform-services project
endpoints:
http:
type: HTTP
port: 8080
visibility: [namespace] # required for cross-project access
note

If a cross-project dependency fails with connection refused, the usual cause is that the target endpoint isn't exposed at a broad enough visibility. Ask the owning team to add namespace to its endpoint's visibility array. See Workloads and endpoints → visibility.

A single Workload can declare up to 50 endpoint dependencies.

Resource dependencies

A Resource is a managed piece of infrastructure — a Postgres database, a NATS queue, a Redis cache, an object-store bucket — provisioned from a platform-defined ResourceType. Your component consumes it by declaring a resource dependency and binding its outputs into your container.

Declare them under spec.dependencies.resources:

apiVersion: openchoreo.dev/v1alpha1
kind: Workload
metadata:
name: cart-api
namespace: fedshi
spec:
owner:
projectName: checkout
componentName: cart-api
container:
image: registry.idp.fedshi.com/checkout/cart-api:1.4.0
dependencies:
resources:
- ref: cart-postgres
envBindings:
host: DB_HOST
port: DB_PORT
username: DB_USER
password: DB_PASSWORD
database: DB_NAME

cart-api depends on the cart-postgres Resource. The platform reads that resource's resolved outputs and injects each as the named env var. Crucially, sensitive outputs (the password) arrive as a Secret reference — only the {name, key} pointer crosses the control plane; the credential itself is read from the data-plane Secret when the pod starts and never lands in a manifest or status.

Resource dependency fields

FieldRequiredDescription
refYesName of the target Resource (must be in the same project)
envBindingsNo*Maps a ResourceType output name → an env var name
fileBindingsNo*Maps a ResourceType output name → a container mount path

*An entry needs ref plus at least one of envBindings or fileBindings. You list only the outputs you actually use — others are ignored.

fileBindings mount an output as a file (useful for certificates and keys); the referenced output must be backed by a Secret or ConfigMap:

dependencies:
resources:
- ref: cart-mtls-creds
fileBindings:
ca-bundle: /etc/ssl/certs/ca-bundle.pem
client-cert: /etc/ssl/certs/client.crt
client-key: /etc/ssl/private/client.key

Deployment gating

The platform won't render your Deployment until every resource dependency reports Ready. You don't race a half-provisioned database — your pod simply waits until its dependencies exist, then starts with the connection details already in place.

Mixing both

Endpoint and resource dependencies coexist in one Workload, and the render gate waits for both:

dependencies:
endpoints:
- component: collab
name: ws
visibility: project
envBindings:
address: COLLAB_URL
resources:
- ref: cart-postgres
envBindings:
host: DB_HOST
port: DB_PORT
username: DB_USER
password: DB_PASSWORD
database: DB_NAME
- ref: cart-events
envBindings:
url: EVENTS_URL

Verifying what got injected

In the portal: open the component, check the Deploy tab to confirm the environment is Ready (deployment is gated on every resource dependency, so a Ready binding means the connection details resolved), and use the Logs tab to confirm the app connected.

Or with the occ CLI, confirm the variables landed by exec-ing into the running pod:

occ component exec cart-api -n fedshi -p checkout --env development -it -- env | grep -E 'CART|DB_'

You'll see resolved addresses, with secret-backed values loaded at pod-start rather than printed into the spec:

CART_API_URL=http://cart-api.<cell-namespace>.svc.cluster.local:8080
DB_HOST=postgres-cart.<cell-namespace>.svc.cluster.local
DB_PORT=5432
DB_USER=cart
DB_NAME=cart
DB_PASSWORD=<value loaded from Secret at pod-start>

What's next