Skip to main content

Environments and Pipelines

A developer who runs occ component deploy --to staging is walking a path you laid down. Environments define the stages a release can land in, and a DeploymentPipeline defines how a release is allowed to move between them. Together they are the delivery structure of an organization — the part of the golden path that governs where and in what order code goes live. This page is how you author that structure.

note

DevsPortal is built on the Control Plane Operator engine. The Environment and DeploymentPipeline resources, the openchoreo.dev/v1alpha1 API group, and the occ CLI are unchanged engine internals. Examples target the Fedshi instance.

Portal first, CLI second

Start from the portal's self-service templates — Create… → Environment and Create… → Deployment Pipeline; the occ/YAML form below is for scripting, review, and GitOps.

Both resources have a template on the portal's Create… page, under Platform Resources:

The portal Create page, with the Environment and Deployment Pipeline templates under Platform Resources

What an Environment is

An Environment is a first-class stage in the delivery lifecycle — development, staging, production, or whatever your org uses. It is not just a label: an Environment maps to a data plane, which is the cluster where workloads for that stage actually run. That mapping is the Environment's main job. It also marks whether the stage is production, which downstream governance keys off.

Because the mapping is explicit, you can shape your topology however you need:

  • Point development and staging at one shared, smaller data plane and production at a dedicated, high-availability one.
  • Point a eu-production and a us-production Environment at two regional data planes for geographic distribution.
  • Give a regulated stage its own compliance-isolated data plane.

In the portal: open Create… and pick the Environment template ("Create a new environment for deploying components across your organization"). Name the stage, choose the data plane it maps to, and mark whether it's production, then create it.

Or with the occ CLI:

# development-environment.yaml
apiVersion: openchoreo.dev/v1alpha1
kind: Environment
metadata:
name: development
namespace: fedshi
annotations:
openchoreo.dev/display-name: "Development"
openchoreo.dev/description: "Shared development stage"
spec:
dataPlaneRef:
kind: ClusterDataPlane
name: default
isProduction: false
occ apply -f development-environment.yaml
occ environment list -n fedshi

Define one Environment resource per stage in the organization namespace. A production stage is identical except isProduction: true and (usually) a dataPlaneRef pointing at a dedicated data plane the platform admin registered.

tip

Which data planes exist, and what ClusterDataPlane / DataPlane names you can reference, is a platform-admin concern. Confirm the available planes before you write dataPlaneRef — see the platform-admin architecture and topology guide.

What a DeploymentPipeline is

A DeploymentPipeline declares the promotion paths between Environments — which stage a release can advance to from which. It is the org's delivery process expressed as data: declarative, reviewable, and the same for every team that binds to it.

In the portal: open Create… and pick the Deployment Pipeline template ("Create a new deployment pipeline that defines promotion paths between environments for component deployments"). Name it and wire the source-to-target promotion paths between the Environments you defined above, then create it.

Or with the occ CLI — the core field is promotionPaths, a list of source-to-target rules. A simple linear pipeline:

# default-pipeline.yaml
apiVersion: openchoreo.dev/v1alpha1
kind: DeploymentPipeline
metadata:
name: default
namespace: fedshi
annotations:
openchoreo.dev/display-name: "Default Pipeline"
openchoreo.dev/description: "development → staging → production"
spec:
promotionPaths:
- sourceEnvironmentRef:
name: development
targetEnvironmentRefs:
- name: staging
- sourceEnvironmentRef:
name: staging
targetEnvironmentRefs:
- name: production
occ apply -f default-pipeline.yaml
occ deploymentpipeline get default -n fedshi

A release deployed to the first environment can only be promoted to a target the pipeline allows. There is no "deploy straight to production" path unless you wrote one — the pipeline is itself a guardrail.

Parallel paths and richer topologies

targetEnvironmentRefs is a list, so a single source can fan out. This lets you model real delivery shapes:

spec:
promotionPaths:
- sourceEnvironmentRef:
name: development
targetEnvironmentRefs:
- name: qa
- name: preproduction # promote dev into either branch
- sourceEnvironmentRef:
name: qa
targetEnvironmentRefs:
- name: production
- sourceEnvironmentRef:
name: preproduction
targetEnvironmentRefs:
- name: production # two paths converge on production

Use parallel paths for fan-out (a release that must pass both QA and a pre-prod soak), regional rollouts (one source promoting to several regional productions), or different release classes that take different routes to prod.

How this shapes the developer's experience

Everything you define here surfaces directly in the developer's deploy and promote flow:

  • A project binds to one pipeline (Project.spec.deploymentPipelineRef), so a team inherits exactly the stages and paths you authored. Set this when you create the project.
  • A new release lands in the first environment in the pipeline (automatically when the component sets autoDeploy: true).
  • The console's Deploy tab renders one card per Environment, and the Promote button is only offered where a promotion path exists. occ component deploy --to <env> succeeds only for an allowed target.
  • The same immutable release moves up the chain — the byte-for-byte artifact validated in dev is what reaches production. Per-environment differences (replica counts, resource limits) come from environment overrides on the binding, not from rebuilding.

So the pipeline you write is, quite literally, the buttons the developer gets to press.

Gating promotions

A pipeline says which promotions are possible; it's often paired with policy that says who may perform a given hop and when. The common pattern is to let any developer promote up to staging but restrict the final hop into a production Environment:

  • RBAC + CEL conditions. Bind the team's developer role with a condition that forbids mutating release bindings in production, so only operators can ship the last hop. The exact mechanism is in Roles and access → conditions and the rationale in Governance and guardrails → promotion gates.
  • isProduction. Marking the production Environment lets conditions and policies key off "is this prod?" cleanly.

Because each promotion is just a binding to a named release, the whole flow is auditable (every hop is recorded) and reversible (rollback is deploying an earlier release) — without a change-advisory board.

Putting it together for a team

To stand up delivery for an organization:

  1. Define one Environment per stage, each with its dataPlaneRef and isProduction flag.
  2. Define one (or a few) DeploymentPipeline wiring those environments into promotion paths.
  3. Bind each project to the pipeline that fits its release process.
  4. Gate the production hop with RBAC conditions for teams that shouldn't self-promote to prod.

After that, developers deploy and promote within the structure with no further setup from you.

Reference

What's next