The gcp:clouddeploy/target:Target resource, part of the Pulumi GCP provider, defines a Cloud Deploy target: the destination where your application deploys, whether that’s a GKE cluster, Cloud Run location, or multiple targets orchestrated together. This guide focuses on three capabilities: GKE cluster targets, Cloud Run service targets, and multi-target orchestration.
Targets reference existing infrastructure that must be created separately: GKE clusters, Cloud Run locations, or other targets. The examples are intentionally small. Combine them with your own clusters, delivery pipelines, and release configurations.
Deploy to a GKE cluster
Most Cloud Deploy pipelines start by defining a target that points to a GKE cluster where your application will run.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const primary = new gcp.clouddeploy.Target("primary", {
location: "us-west1",
name: "target",
deployParameters: {
deployParameterKey: "deployParameterValue",
},
description: "basic description",
gke: {
cluster: "projects/my-project-name/locations/us-west1/clusters/example-cluster-name",
},
project: "my-project-name",
requireApproval: false,
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.Target("primary",
location="us-west1",
name="target",
deploy_parameters={
"deployParameterKey": "deployParameterValue",
},
description="basic description",
gke={
"cluster": "projects/my-project-name/locations/us-west1/clusters/example-cluster-name",
},
project="my-project-name",
require_approval=False,
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.NewTarget(ctx, "primary", &clouddeploy.TargetArgs{
Location: pulumi.String("us-west1"),
Name: pulumi.String("target"),
DeployParameters: pulumi.StringMap{
"deployParameterKey": pulumi.String("deployParameterValue"),
},
Description: pulumi.String("basic description"),
Gke: &clouddeploy.TargetGkeArgs{
Cluster: pulumi.String("projects/my-project-name/locations/us-west1/clusters/example-cluster-name"),
},
Project: pulumi.String("my-project-name"),
RequireApproval: pulumi.Bool(false),
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.Target("primary", new()
{
Location = "us-west1",
Name = "target",
DeployParameters =
{
{ "deployParameterKey", "deployParameterValue" },
},
Description = "basic description",
Gke = new Gcp.CloudDeploy.Inputs.TargetGkeArgs
{
Cluster = "projects/my-project-name/locations/us-west1/clusters/example-cluster-name",
},
Project = "my-project-name",
RequireApproval = false,
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.Target;
import com.pulumi.gcp.clouddeploy.TargetArgs;
import com.pulumi.gcp.clouddeploy.inputs.TargetGkeArgs;
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 Target("primary", TargetArgs.builder()
.location("us-west1")
.name("target")
.deployParameters(Map.of("deployParameterKey", "deployParameterValue"))
.description("basic description")
.gke(TargetGkeArgs.builder()
.cluster("projects/my-project-name/locations/us-west1/clusters/example-cluster-name")
.build())
.project("my-project-name")
.requireApproval(false)
.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:Target
properties:
location: us-west1
name: target
deployParameters:
deployParameterKey: deployParameterValue
description: basic description
gke:
cluster: projects/my-project-name/locations/us-west1/clusters/example-cluster-name
project: my-project-name
requireApproval: false
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 gke property specifies the cluster reference in the format projects/{project}/locations/{location}/clusters/{cluster}. The requireApproval property controls whether deployments to this target need manual approval before proceeding. The location property determines which region manages the target resource itself.
Deploy to Cloud Run services
Teams deploying containerized applications to Cloud Run define targets that specify where services will be created or updated.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const primary = new gcp.clouddeploy.Target("primary", {
location: "us-west1",
name: "target",
deployParameters: {},
description: "basic description",
executionConfigs: [{
usages: [
"RENDER",
"DEPLOY",
],
executionTimeout: "3600s",
}],
project: "my-project-name",
requireApproval: false,
run: {
location: "projects/my-project-name/locations/us-west1",
},
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.Target("primary",
location="us-west1",
name="target",
deploy_parameters={},
description="basic description",
execution_configs=[{
"usages": [
"RENDER",
"DEPLOY",
],
"execution_timeout": "3600s",
}],
project="my-project-name",
require_approval=False,
run={
"location": "projects/my-project-name/locations/us-west1",
},
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.NewTarget(ctx, "primary", &clouddeploy.TargetArgs{
Location: pulumi.String("us-west1"),
Name: pulumi.String("target"),
DeployParameters: pulumi.StringMap{},
Description: pulumi.String("basic description"),
ExecutionConfigs: clouddeploy.TargetExecutionConfigArray{
&clouddeploy.TargetExecutionConfigArgs{
Usages: pulumi.StringArray{
pulumi.String("RENDER"),
pulumi.String("DEPLOY"),
},
ExecutionTimeout: pulumi.String("3600s"),
},
},
Project: pulumi.String("my-project-name"),
RequireApproval: pulumi.Bool(false),
Run: &clouddeploy.TargetRunArgs{
Location: pulumi.String("projects/my-project-name/locations/us-west1"),
},
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.Target("primary", new()
{
Location = "us-west1",
Name = "target",
DeployParameters = null,
Description = "basic description",
ExecutionConfigs = new[]
{
new Gcp.CloudDeploy.Inputs.TargetExecutionConfigArgs
{
Usages = new[]
{
"RENDER",
"DEPLOY",
},
ExecutionTimeout = "3600s",
},
},
Project = "my-project-name",
RequireApproval = false,
Run = new Gcp.CloudDeploy.Inputs.TargetRunArgs
{
Location = "projects/my-project-name/locations/us-west1",
},
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.Target;
import com.pulumi.gcp.clouddeploy.TargetArgs;
import com.pulumi.gcp.clouddeploy.inputs.TargetExecutionConfigArgs;
import com.pulumi.gcp.clouddeploy.inputs.TargetRunArgs;
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 Target("primary", TargetArgs.builder()
.location("us-west1")
.name("target")
.deployParameters(Map.ofEntries(
))
.description("basic description")
.executionConfigs(TargetExecutionConfigArgs.builder()
.usages(
"RENDER",
"DEPLOY")
.executionTimeout("3600s")
.build())
.project("my-project-name")
.requireApproval(false)
.run(TargetRunArgs.builder()
.location("projects/my-project-name/locations/us-west1")
.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:Target
properties:
location: us-west1
name: target
deployParameters: {}
description: basic description
executionConfigs:
- usages:
- RENDER
- DEPLOY
executionTimeout: 3600s
project: my-project-name
requireApproval: false
run:
location: projects/my-project-name/locations/us-west1
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 run property points to a Cloud Run location instead of a GKE cluster. The executionConfigs property defines how Cloud Deploy executes the render and deploy phases, including timeout limits. When you specify execution configs, you must include both RENDER and DEPLOY usages.
Orchestrate deployments across multiple targets
Complex deployments often need to roll out to multiple clusters or regions simultaneously.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const primary = new gcp.clouddeploy.Target("primary", {
location: "us-west1",
name: "target",
deployParameters: {},
description: "multi-target description",
executionConfigs: [{
usages: [
"RENDER",
"DEPLOY",
],
executionTimeout: "3600s",
}],
multiTarget: {
targetIds: [
"1",
"2",
],
},
project: "my-project-name",
requireApproval: false,
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.Target("primary",
location="us-west1",
name="target",
deploy_parameters={},
description="multi-target description",
execution_configs=[{
"usages": [
"RENDER",
"DEPLOY",
],
"execution_timeout": "3600s",
}],
multi_target={
"target_ids": [
"1",
"2",
],
},
project="my-project-name",
require_approval=False,
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.NewTarget(ctx, "primary", &clouddeploy.TargetArgs{
Location: pulumi.String("us-west1"),
Name: pulumi.String("target"),
DeployParameters: pulumi.StringMap{},
Description: pulumi.String("multi-target description"),
ExecutionConfigs: clouddeploy.TargetExecutionConfigArray{
&clouddeploy.TargetExecutionConfigArgs{
Usages: pulumi.StringArray{
pulumi.String("RENDER"),
pulumi.String("DEPLOY"),
},
ExecutionTimeout: pulumi.String("3600s"),
},
},
MultiTarget: &clouddeploy.TargetMultiTargetArgs{
TargetIds: pulumi.StringArray{
pulumi.String("1"),
pulumi.String("2"),
},
},
Project: pulumi.String("my-project-name"),
RequireApproval: pulumi.Bool(false),
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.Target("primary", new()
{
Location = "us-west1",
Name = "target",
DeployParameters = null,
Description = "multi-target description",
ExecutionConfigs = new[]
{
new Gcp.CloudDeploy.Inputs.TargetExecutionConfigArgs
{
Usages = new[]
{
"RENDER",
"DEPLOY",
},
ExecutionTimeout = "3600s",
},
},
MultiTarget = new Gcp.CloudDeploy.Inputs.TargetMultiTargetArgs
{
TargetIds = new[]
{
"1",
"2",
},
},
Project = "my-project-name",
RequireApproval = false,
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.Target;
import com.pulumi.gcp.clouddeploy.TargetArgs;
import com.pulumi.gcp.clouddeploy.inputs.TargetExecutionConfigArgs;
import com.pulumi.gcp.clouddeploy.inputs.TargetMultiTargetArgs;
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 Target("primary", TargetArgs.builder()
.location("us-west1")
.name("target")
.deployParameters(Map.ofEntries(
))
.description("multi-target description")
.executionConfigs(TargetExecutionConfigArgs.builder()
.usages(
"RENDER",
"DEPLOY")
.executionTimeout("3600s")
.build())
.multiTarget(TargetMultiTargetArgs.builder()
.targetIds(
"1",
"2")
.build())
.project("my-project-name")
.requireApproval(false)
.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:Target
properties:
location: us-west1
name: target
deployParameters: {}
description: multi-target description
executionConfigs:
- usages:
- RENDER
- DEPLOY
executionTimeout: 3600s
multiTarget:
targetIds:
- '1'
- '2'
project: my-project-name
requireApproval: false
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 multiTarget property lists child target IDs that receive the deployment in parallel. Each referenced target must be defined separately as its own Target resource. Multi-targets coordinate the rollout but don’t specify infrastructure directly; the child targets define the actual GKE clusters or Cloud Run locations.
Beyond these examples
These snippets focus on specific target-level features: GKE, Cloud Run, and multi-target deployment destinations, and execution configuration and approval requirements. They’re intentionally minimal rather than full deployment pipelines.
The examples reference pre-existing infrastructure such as GKE clusters or Cloud Run locations, and child targets for multi-target configuration. They focus on configuring the target rather than provisioning the underlying compute resources.
To keep things focused, common target patterns are omitted, including:
- Anthos Cluster and Custom Target configurations
- Associated entities for Gateway API canary deployments
- Deploy parameters for runtime configuration
- Annotations and labels for metadata
These omissions are intentional: the goal is to illustrate how each target type is wired, not provide drop-in deployment modules. See the Cloud Deploy Target resource reference for all available configuration options.
Let's configure GCP Cloud Deploy Targets
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Target Configuration & Types
RENDER and DEPLOY in the executionConfigs usages array. Each usage value can only appear once, and using the same value multiple times causes an error.gke), Cloud Run (run), multiple targets (multiTarget), Anthos clusters (anthosCluster), and custom targets (customTarget).gke property with a cluster reference in the format projects/PROJECT/locations/LOCATION/clusters/CLUSTER_NAME.run property with a location in the format projects/PROJECT/locations/LOCATION.multiTarget property with a targetIds array containing the IDs of the targets you want to deploy to.Naming & Constraints
location, name, and project properties are immutable and cannot be modified after target creation. Changing these values requires replacing the resource.a-z?, meaning they can contain lowercase letters, numbers, and hyphens, must start with a letter, and end with a letter or number.^a-z?$ with a maximum length of 63 characters.Labels & Annotations
annotations and labels fields are non-authoritative and only manage values present in your configuration. To see all annotations and labels on the resource (including those set by other clients), use effectiveAnnotations and effectiveLabels.Execution & Timeouts
3600s for one hour.Using a different cloud?
Explore integration guides for other cloud providers: