The gcp:clouddeploy/deliveryPipeline:DeliveryPipeline resource, part of the Pulumi GCP provider, defines a Cloud Deploy delivery pipeline that orchestrates application releases through sequential deployment stages. This guide focuses on two capabilities: multi-stage pipeline configuration and stage-specific parameters.
Delivery pipelines reference Cloud Deploy Target resources (GKE clusters, Cloud Run services) and Skaffold profiles that define how to build and deploy your application. The examples are intentionally small. Combine them with your own Target resources and deployment configuration.
Define a multi-stage deployment pipeline
Cloud Deploy pipelines move code from development through staging to production in a controlled sequence.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const primary = new gcp.clouddeploy.DeliveryPipeline("primary", {
location: "us-west1",
name: "pipeline",
description: "basic description",
project: "my-project-name",
serialPipeline: {
stages: [
{
deployParameters: [{
values: {
deployParameterKey: "deployParameterValue",
},
matchTargetLabels: {},
}],
profiles: [
"example-profile-one",
"example-profile-two",
],
targetId: "example-target-one",
},
{
profiles: [],
targetId: "example-target-two",
},
],
},
annotations: {
my_first_annotation: "example-annotation-1",
my_second_annotation: "example-annotation-2",
},
labels: {
my_first_label: "example-label-1",
my_second_label: "example-label-2",
},
});
import pulumi
import pulumi_gcp as gcp
primary = gcp.clouddeploy.DeliveryPipeline("primary",
location="us-west1",
name="pipeline",
description="basic description",
project="my-project-name",
serial_pipeline={
"stages": [
{
"deploy_parameters": [{
"values": {
"deployParameterKey": "deployParameterValue",
},
"match_target_labels": {},
}],
"profiles": [
"example-profile-one",
"example-profile-two",
],
"target_id": "example-target-one",
},
{
"profiles": [],
"target_id": "example-target-two",
},
],
},
annotations={
"my_first_annotation": "example-annotation-1",
"my_second_annotation": "example-annotation-2",
},
labels={
"my_first_label": "example-label-1",
"my_second_label": "example-label-2",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/clouddeploy"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := clouddeploy.NewDeliveryPipeline(ctx, "primary", &clouddeploy.DeliveryPipelineArgs{
Location: pulumi.String("us-west1"),
Name: pulumi.String("pipeline"),
Description: pulumi.String("basic description"),
Project: pulumi.String("my-project-name"),
SerialPipeline: &clouddeploy.DeliveryPipelineSerialPipelineArgs{
Stages: clouddeploy.DeliveryPipelineSerialPipelineStageArray{
&clouddeploy.DeliveryPipelineSerialPipelineStageArgs{
DeployParameters: clouddeploy.DeliveryPipelineSerialPipelineStageDeployParameterArray{
&clouddeploy.DeliveryPipelineSerialPipelineStageDeployParameterArgs{
Values: pulumi.StringMap{
"deployParameterKey": pulumi.String("deployParameterValue"),
},
MatchTargetLabels: pulumi.StringMap{},
},
},
Profiles: pulumi.StringArray{
pulumi.String("example-profile-one"),
pulumi.String("example-profile-two"),
},
TargetId: pulumi.String("example-target-one"),
},
&clouddeploy.DeliveryPipelineSerialPipelineStageArgs{
Profiles: pulumi.StringArray{},
TargetId: pulumi.String("example-target-two"),
},
},
},
Annotations: pulumi.StringMap{
"my_first_annotation": pulumi.String("example-annotation-1"),
"my_second_annotation": pulumi.String("example-annotation-2"),
},
Labels: pulumi.StringMap{
"my_first_label": pulumi.String("example-label-1"),
"my_second_label": pulumi.String("example-label-2"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var primary = new Gcp.CloudDeploy.DeliveryPipeline("primary", new()
{
Location = "us-west1",
Name = "pipeline",
Description = "basic description",
Project = "my-project-name",
SerialPipeline = new Gcp.CloudDeploy.Inputs.DeliveryPipelineSerialPipelineArgs
{
Stages = new[]
{
new Gcp.CloudDeploy.Inputs.DeliveryPipelineSerialPipelineStageArgs
{
DeployParameters = new[]
{
new Gcp.CloudDeploy.Inputs.DeliveryPipelineSerialPipelineStageDeployParameterArgs
{
Values =
{
{ "deployParameterKey", "deployParameterValue" },
},
MatchTargetLabels = null,
},
},
Profiles = new[]
{
"example-profile-one",
"example-profile-two",
},
TargetId = "example-target-one",
},
new Gcp.CloudDeploy.Inputs.DeliveryPipelineSerialPipelineStageArgs
{
Profiles = new() { },
TargetId = "example-target-two",
},
},
},
Annotations =
{
{ "my_first_annotation", "example-annotation-1" },
{ "my_second_annotation", "example-annotation-2" },
},
Labels =
{
{ "my_first_label", "example-label-1" },
{ "my_second_label", "example-label-2" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.clouddeploy.DeliveryPipeline;
import com.pulumi.gcp.clouddeploy.DeliveryPipelineArgs;
import com.pulumi.gcp.clouddeploy.inputs.DeliveryPipelineSerialPipelineArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var primary = new DeliveryPipeline("primary", DeliveryPipelineArgs.builder()
.location("us-west1")
.name("pipeline")
.description("basic description")
.project("my-project-name")
.serialPipeline(DeliveryPipelineSerialPipelineArgs.builder()
.stages(
DeliveryPipelineSerialPipelineStageArgs.builder()
.deployParameters(DeliveryPipelineSerialPipelineStageDeployParameterArgs.builder()
.values(Map.of("deployParameterKey", "deployParameterValue"))
.matchTargetLabels(Map.ofEntries(
))
.build())
.profiles(
"example-profile-one",
"example-profile-two")
.targetId("example-target-one")
.build(),
DeliveryPipelineSerialPipelineStageArgs.builder()
.profiles()
.targetId("example-target-two")
.build())
.build())
.annotations(Map.ofEntries(
Map.entry("my_first_annotation", "example-annotation-1"),
Map.entry("my_second_annotation", "example-annotation-2")
))
.labels(Map.ofEntries(
Map.entry("my_first_label", "example-label-1"),
Map.entry("my_second_label", "example-label-2")
))
.build());
}
}
resources:
primary:
type: gcp:clouddeploy:DeliveryPipeline
properties:
location: us-west1
name: pipeline
description: basic description
project: my-project-name
serialPipeline:
stages:
- deployParameters:
- values:
deployParameterKey: deployParameterValue
matchTargetLabels: {}
profiles:
- example-profile-one
- example-profile-two
targetId: example-target-one
- profiles: []
targetId: example-target-two
annotations:
my_first_annotation: example-annotation-1
my_second_annotation: example-annotation-2
labels:
my_first_label: example-label-1
my_second_label: example-label-2
The serialPipeline property defines stages that execute in order. Each stage references a targetId (a Cloud Deploy Target resource) and optional profiles (Skaffold profile names). The deployParameters block passes key-value pairs to the deployment, allowing stage-specific configuration like feature flags or environment variables. The first stage shows both profiles and parameters; the second stage demonstrates a minimal configuration with just a target reference.
Beyond these examples
These snippets focus on specific pipeline-level features: sequential stage configuration, deploy parameters and profile selection, and annotations and labels for metadata. They’re intentionally minimal rather than full deployment workflows.
The examples reference pre-existing infrastructure such as Cloud Deploy Target resources (referenced by targetId) and Skaffold profiles (referenced in stages). They focus on configuring the pipeline rather than provisioning targets or build configuration.
To keep things focused, common pipeline patterns are omitted, including:
- Pipeline suspension (suspended property)
- Deployment verification strategies
- Stage-specific strategies (canary, custom)
- Approval requirements between stages
These omissions are intentional: the goal is to illustrate how pipeline stages are wired, not provide drop-in CI/CD modules. See the Cloud Deploy DeliveryPipeline resource reference for all available configuration options.
Let's configure GCP Cloud Deploy Delivery Pipelines
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Constraints
name must match the format a-z? (lowercase letters, numbers, and hyphens).description field has a maximum length of 255 characters.Immutability & Updates
location, name, and project properties are immutable and cannot be changed after creation.annotations and labels fields are non-authoritative and only manage values present in your configuration. To access all annotations and labels on the resource (including those set by other clients or services), use the effectiveAnnotations and effectiveLabels output properties.Pipeline Behavior
suspended is true, no new releases or rollouts can be created, but in-progress ones will complete.serialPipeline property defines a sequential set of stages for the delivery pipeline, specifying the order in which deployments progress through targets.Import & Management
projects/{{project}}/locations/{{location}}/deliveryPipelines/{{name}}, {{project}}/{{location}}/{{name}}, or {{location}}/{{name}}.Using a different cloud?
Explore integration guides for other cloud providers: