Configure GCP Cloud Deploy Custom Target Types

The gcp:clouddeploy/customTargetType:CustomTargetType resource, part of the Pulumi GCP provider, defines a reusable custom target type that extends Cloud Deploy to support deployment systems beyond GKE and Cloud Run. This guide focuses on three capabilities: custom action configuration, Skaffold module sourcing from Git, GCS, and Cloud Build, and metadata organization.

Custom target types reference Skaffold configuration stored in external sources and require Cloud Deploy service accounts with appropriate permissions. The examples are intentionally small. Combine them with your own Target resources, delivery pipelines, and IAM configuration.

Define a custom target type with annotations and labels

Teams extending Cloud Deploy to non-standard deployment targets start by defining a custom target type that specifies render and deploy actions.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const custom_target_type = new gcp.clouddeploy.CustomTargetType("custom-target-type", {
    location: "us-central1",
    name: "my-custom-target-type",
    description: "My custom target type",
    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",
    },
    customActions: {
        renderAction: "renderAction",
        deployAction: "deployAction",
    },
});
import pulumi
import pulumi_gcp as gcp

custom_target_type = gcp.clouddeploy.CustomTargetType("custom-target-type",
    location="us-central1",
    name="my-custom-target-type",
    description="My custom target type",
    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",
    },
    custom_actions={
        "render_action": "renderAction",
        "deploy_action": "deployAction",
    })
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.NewCustomTargetType(ctx, "custom-target-type", &clouddeploy.CustomTargetTypeArgs{
			Location:    pulumi.String("us-central1"),
			Name:        pulumi.String("my-custom-target-type"),
			Description: pulumi.String("My custom target type"),
			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"),
			},
			CustomActions: &clouddeploy.CustomTargetTypeCustomActionsArgs{
				RenderAction: pulumi.String("renderAction"),
				DeployAction: pulumi.String("deployAction"),
			},
		})
		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 custom_target_type = new Gcp.CloudDeploy.CustomTargetType("custom-target-type", new()
    {
        Location = "us-central1",
        Name = "my-custom-target-type",
        Description = "My custom target type",
        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" },
        },
        CustomActions = new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsArgs
        {
            RenderAction = "renderAction",
            DeployAction = "deployAction",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.clouddeploy.CustomTargetType;
import com.pulumi.gcp.clouddeploy.CustomTargetTypeArgs;
import com.pulumi.gcp.clouddeploy.inputs.CustomTargetTypeCustomActionsArgs;
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 custom_target_type = new CustomTargetType("custom-target-type", CustomTargetTypeArgs.builder()
            .location("us-central1")
            .name("my-custom-target-type")
            .description("My custom target type")
            .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")
            ))
            .customActions(CustomTargetTypeCustomActionsArgs.builder()
                .renderAction("renderAction")
                .deployAction("deployAction")
                .build())
            .build());

    }
}
resources:
  custom-target-type:
    type: gcp:clouddeploy:CustomTargetType
    properties:
      location: us-central1
      name: my-custom-target-type
      description: My custom target type
      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
      customActions:
        renderAction: renderAction
        deployAction: deployAction

The customActions property defines the contract between Cloud Deploy and your deployment system. The renderAction and deployAction properties are string references to Skaffold custom actions that implement your deployment logic. Annotations and labels provide metadata for organization and filtering; annotations are user-only, while labels are visible to both users and Cloud Deploy.

Reference Skaffold configuration from a Git repository

When custom deployment logic lives in version control, you can point Cloud Deploy to Skaffold modules stored in Git repositories.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const custom_target_type = new gcp.clouddeploy.CustomTargetType("custom-target-type", {
    location: "us-central1",
    name: "my-custom-target-type",
    description: "My custom target type",
    customActions: {
        renderAction: "renderAction",
        deployAction: "deployAction",
        includeSkaffoldModules: [{
            configs: ["my-config"],
            git: {
                repo: "http://github.com/example/example-repo.git",
                path: "configs/skaffold.yaml",
                ref: "main",
            },
        }],
    },
});
import pulumi
import pulumi_gcp as gcp

custom_target_type = gcp.clouddeploy.CustomTargetType("custom-target-type",
    location="us-central1",
    name="my-custom-target-type",
    description="My custom target type",
    custom_actions={
        "render_action": "renderAction",
        "deploy_action": "deployAction",
        "include_skaffold_modules": [{
            "configs": ["my-config"],
            "git": {
                "repo": "http://github.com/example/example-repo.git",
                "path": "configs/skaffold.yaml",
                "ref": "main",
            },
        }],
    })
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.NewCustomTargetType(ctx, "custom-target-type", &clouddeploy.CustomTargetTypeArgs{
			Location:    pulumi.String("us-central1"),
			Name:        pulumi.String("my-custom-target-type"),
			Description: pulumi.String("My custom target type"),
			CustomActions: &clouddeploy.CustomTargetTypeCustomActionsArgs{
				RenderAction: pulumi.String("renderAction"),
				DeployAction: pulumi.String("deployAction"),
				IncludeSkaffoldModules: clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArray{
					&clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs{
						Configs: pulumi.StringArray{
							pulumi.String("my-config"),
						},
						Git: &clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleGitArgs{
							Repo: pulumi.String("http://github.com/example/example-repo.git"),
							Path: pulumi.String("configs/skaffold.yaml"),
							Ref:  pulumi.String("main"),
						},
					},
				},
			},
		})
		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 custom_target_type = new Gcp.CloudDeploy.CustomTargetType("custom-target-type", new()
    {
        Location = "us-central1",
        Name = "my-custom-target-type",
        Description = "My custom target type",
        CustomActions = new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsArgs
        {
            RenderAction = "renderAction",
            DeployAction = "deployAction",
            IncludeSkaffoldModules = new[]
            {
                new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs
                {
                    Configs = new[]
                    {
                        "my-config",
                    },
                    Git = new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsIncludeSkaffoldModuleGitArgs
                    {
                        Repo = "http://github.com/example/example-repo.git",
                        Path = "configs/skaffold.yaml",
                        Ref = "main",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.clouddeploy.CustomTargetType;
import com.pulumi.gcp.clouddeploy.CustomTargetTypeArgs;
import com.pulumi.gcp.clouddeploy.inputs.CustomTargetTypeCustomActionsArgs;
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 custom_target_type = new CustomTargetType("custom-target-type", CustomTargetTypeArgs.builder()
            .location("us-central1")
            .name("my-custom-target-type")
            .description("My custom target type")
            .customActions(CustomTargetTypeCustomActionsArgs.builder()
                .renderAction("renderAction")
                .deployAction("deployAction")
                .includeSkaffoldModules(CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs.builder()
                    .configs("my-config")
                    .git(CustomTargetTypeCustomActionsIncludeSkaffoldModuleGitArgs.builder()
                        .repo("http://github.com/example/example-repo.git")
                        .path("configs/skaffold.yaml")
                        .ref("main")
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  custom-target-type:
    type: gcp:clouddeploy:CustomTargetType
    properties:
      location: us-central1
      name: my-custom-target-type
      description: My custom target type
      customActions:
        renderAction: renderAction
        deployAction: deployAction
        includeSkaffoldModules:
          - configs:
              - my-config
            git:
              repo: http://github.com/example/example-repo.git
              path: configs/skaffold.yaml
              ref: main

The includeSkaffoldModules property loads external Skaffold configuration. The git block specifies the repository URL, file path, and branch or tag reference. The configs array lists which Skaffold module names to include from the referenced file. Cloud Deploy fetches the configuration at deployment time, so changes to the repository affect future deployments without updating the custom target type.

Load Skaffold modules from Cloud Storage

Organizations that store deployment artifacts in Cloud Storage can reference Skaffold configuration files directly from GCS buckets.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const custom_target_type = new gcp.clouddeploy.CustomTargetType("custom-target-type", {
    location: "us-central1",
    name: "my-custom-target-type",
    description: "My custom target type",
    customActions: {
        renderAction: "renderAction",
        deployAction: "deployAction",
        includeSkaffoldModules: [{
            configs: ["my-config"],
            googleCloudStorage: {
                source: "gs://example-bucket/dir/configs/*",
                path: "skaffold.yaml",
            },
        }],
    },
});
import pulumi
import pulumi_gcp as gcp

custom_target_type = gcp.clouddeploy.CustomTargetType("custom-target-type",
    location="us-central1",
    name="my-custom-target-type",
    description="My custom target type",
    custom_actions={
        "render_action": "renderAction",
        "deploy_action": "deployAction",
        "include_skaffold_modules": [{
            "configs": ["my-config"],
            "google_cloud_storage": {
                "source": "gs://example-bucket/dir/configs/*",
                "path": "skaffold.yaml",
            },
        }],
    })
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.NewCustomTargetType(ctx, "custom-target-type", &clouddeploy.CustomTargetTypeArgs{
			Location:    pulumi.String("us-central1"),
			Name:        pulumi.String("my-custom-target-type"),
			Description: pulumi.String("My custom target type"),
			CustomActions: &clouddeploy.CustomTargetTypeCustomActionsArgs{
				RenderAction: pulumi.String("renderAction"),
				DeployAction: pulumi.String("deployAction"),
				IncludeSkaffoldModules: clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArray{
					&clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs{
						Configs: pulumi.StringArray{
							pulumi.String("my-config"),
						},
						GoogleCloudStorage: &clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleGoogleCloudStorageArgs{
							Source: pulumi.String("gs://example-bucket/dir/configs/*"),
							Path:   pulumi.String("skaffold.yaml"),
						},
					},
				},
			},
		})
		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 custom_target_type = new Gcp.CloudDeploy.CustomTargetType("custom-target-type", new()
    {
        Location = "us-central1",
        Name = "my-custom-target-type",
        Description = "My custom target type",
        CustomActions = new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsArgs
        {
            RenderAction = "renderAction",
            DeployAction = "deployAction",
            IncludeSkaffoldModules = new[]
            {
                new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs
                {
                    Configs = new[]
                    {
                        "my-config",
                    },
                    GoogleCloudStorage = new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsIncludeSkaffoldModuleGoogleCloudStorageArgs
                    {
                        Source = "gs://example-bucket/dir/configs/*",
                        Path = "skaffold.yaml",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.clouddeploy.CustomTargetType;
import com.pulumi.gcp.clouddeploy.CustomTargetTypeArgs;
import com.pulumi.gcp.clouddeploy.inputs.CustomTargetTypeCustomActionsArgs;
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 custom_target_type = new CustomTargetType("custom-target-type", CustomTargetTypeArgs.builder()
            .location("us-central1")
            .name("my-custom-target-type")
            .description("My custom target type")
            .customActions(CustomTargetTypeCustomActionsArgs.builder()
                .renderAction("renderAction")
                .deployAction("deployAction")
                .includeSkaffoldModules(CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs.builder()
                    .configs("my-config")
                    .googleCloudStorage(CustomTargetTypeCustomActionsIncludeSkaffoldModuleGoogleCloudStorageArgs.builder()
                        .source("gs://example-bucket/dir/configs/*")
                        .path("skaffold.yaml")
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  custom-target-type:
    type: gcp:clouddeploy:CustomTargetType
    properties:
      location: us-central1
      name: my-custom-target-type
      description: My custom target type
      customActions:
        renderAction: renderAction
        deployAction: deployAction
        includeSkaffoldModules:
          - configs:
              - my-config
            googleCloudStorage:
              source: gs://example-bucket/dir/configs/*
              path: skaffold.yaml

The googleCloudStorage block replaces the git block when sourcing from GCS. The source property accepts GCS URIs with wildcards, and path specifies which file within the matched objects contains the Skaffold configuration. This approach works well for organizations that generate or archive Skaffold configuration as part of their build process.

Reference Skaffold modules from Cloud Build repositories

Teams using Cloud Build’s repository connections can reference Skaffold configuration from connected Git repositories.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const custom_target_type = new gcp.clouddeploy.CustomTargetType("custom-target-type", {
    location: "us-central1",
    name: "my-custom-target-type",
    description: "My custom target type",
    customActions: {
        renderAction: "renderAction",
        deployAction: "deployAction",
        includeSkaffoldModules: [{
            configs: ["my-config"],
            googleCloudBuildRepo: {
                repository: "projects/example/locations/us-central1/connections/git/repositories/example-repo",
                path: "configs/skaffold.yaml",
                ref: "main",
            },
        }],
    },
});
import pulumi
import pulumi_gcp as gcp

custom_target_type = gcp.clouddeploy.CustomTargetType("custom-target-type",
    location="us-central1",
    name="my-custom-target-type",
    description="My custom target type",
    custom_actions={
        "render_action": "renderAction",
        "deploy_action": "deployAction",
        "include_skaffold_modules": [{
            "configs": ["my-config"],
            "google_cloud_build_repo": {
                "repository": "projects/example/locations/us-central1/connections/git/repositories/example-repo",
                "path": "configs/skaffold.yaml",
                "ref": "main",
            },
        }],
    })
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.NewCustomTargetType(ctx, "custom-target-type", &clouddeploy.CustomTargetTypeArgs{
			Location:    pulumi.String("us-central1"),
			Name:        pulumi.String("my-custom-target-type"),
			Description: pulumi.String("My custom target type"),
			CustomActions: &clouddeploy.CustomTargetTypeCustomActionsArgs{
				RenderAction: pulumi.String("renderAction"),
				DeployAction: pulumi.String("deployAction"),
				IncludeSkaffoldModules: clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArray{
					&clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs{
						Configs: pulumi.StringArray{
							pulumi.String("my-config"),
						},
						GoogleCloudBuildRepo: &clouddeploy.CustomTargetTypeCustomActionsIncludeSkaffoldModuleGoogleCloudBuildRepoArgs{
							Repository: pulumi.String("projects/example/locations/us-central1/connections/git/repositories/example-repo"),
							Path:       pulumi.String("configs/skaffold.yaml"),
							Ref:        pulumi.String("main"),
						},
					},
				},
			},
		})
		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 custom_target_type = new Gcp.CloudDeploy.CustomTargetType("custom-target-type", new()
    {
        Location = "us-central1",
        Name = "my-custom-target-type",
        Description = "My custom target type",
        CustomActions = new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsArgs
        {
            RenderAction = "renderAction",
            DeployAction = "deployAction",
            IncludeSkaffoldModules = new[]
            {
                new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs
                {
                    Configs = new[]
                    {
                        "my-config",
                    },
                    GoogleCloudBuildRepo = new Gcp.CloudDeploy.Inputs.CustomTargetTypeCustomActionsIncludeSkaffoldModuleGoogleCloudBuildRepoArgs
                    {
                        Repository = "projects/example/locations/us-central1/connections/git/repositories/example-repo",
                        Path = "configs/skaffold.yaml",
                        Ref = "main",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.clouddeploy.CustomTargetType;
import com.pulumi.gcp.clouddeploy.CustomTargetTypeArgs;
import com.pulumi.gcp.clouddeploy.inputs.CustomTargetTypeCustomActionsArgs;
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 custom_target_type = new CustomTargetType("custom-target-type", CustomTargetTypeArgs.builder()
            .location("us-central1")
            .name("my-custom-target-type")
            .description("My custom target type")
            .customActions(CustomTargetTypeCustomActionsArgs.builder()
                .renderAction("renderAction")
                .deployAction("deployAction")
                .includeSkaffoldModules(CustomTargetTypeCustomActionsIncludeSkaffoldModuleArgs.builder()
                    .configs("my-config")
                    .googleCloudBuildRepo(CustomTargetTypeCustomActionsIncludeSkaffoldModuleGoogleCloudBuildRepoArgs.builder()
                        .repository("projects/example/locations/us-central1/connections/git/repositories/example-repo")
                        .path("configs/skaffold.yaml")
                        .ref("main")
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  custom-target-type:
    type: gcp:clouddeploy:CustomTargetType
    properties:
      location: us-central1
      name: my-custom-target-type
      description: My custom target type
      customActions:
        renderAction: renderAction
        deployAction: deployAction
        includeSkaffoldModules:
          - configs:
              - my-config
            googleCloudBuildRepo:
              repository: projects/example/locations/us-central1/connections/git/repositories/example-repo
              path: configs/skaffold.yaml
              ref: main

The googleCloudBuildRepo block uses Cloud Build’s repository connection format. The repository property references a Cloud Build connection by its full resource path, while path and ref work like the git block. This approach integrates with Cloud Build’s authentication and access control for private repositories.

Beyond these examples

These snippets focus on specific custom target type features: custom action definitions, Skaffold module sourcing from Git, GCS, and Cloud Build, and metadata organization with annotations and labels. They’re intentionally minimal rather than full deployment pipelines.

The examples may reference pre-existing infrastructure such as Cloud Deploy service accounts with appropriate permissions, and Git repositories, GCS buckets, or Cloud Build connections for Skaffold module examples. They focus on defining the custom target type rather than provisioning the surrounding infrastructure.

To keep things focused, common custom target type patterns are omitted, including:

  • Custom action implementation details (renderAction and deployAction are string references)
  • Target resource creation (CustomTargetType defines the type, not the target itself)
  • Delivery pipeline integration
  • IAM permissions for service accounts

These omissions are intentional: the goal is to illustrate how each custom target type feature is wired, not provide drop-in deployment modules. See the Cloud Deploy CustomTargetType resource reference for all available configuration options.

Let's configure GCP Cloud Deploy Custom Target Types

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Configuration & Immutability
What properties can't I change after creating a CustomTargetType?
The location, name, and project properties are immutable and cannot be modified after creation. Changes to these properties will require replacing the resource.
What are the required fields for a CustomTargetType?
You must specify location, name, and customActions. The customActions property requires both renderAction and deployAction.
What's the maximum length for the description field?
The description field has a maximum length of 255 characters.
Annotations & Labels
Why don't my annotations and labels match what's shown in GCP?
The annotations and labels fields are non-authoritative, meaning Pulumi only manages the annotations and labels present in your configuration. To see all annotations and labels on the resource (including those set by other clients or services), use the effectiveAnnotations and effectiveLabels output properties.
What are the formatting requirements for labels?
Labels must meet these constraints: keys and values can contain only lowercase letters, numeric characters, underscores, and dashes; all characters must use UTF-8 encoding; keys must start with a lowercase letter or international character; maximum of 64 labels per resource; both keys and values must be 128 bytes or less.
Skaffold Modules & Custom Actions
How do I include Skaffold modules from different sources?

You have three options for including Skaffold modules:

  1. Git repository - Use git with repo, path, and ref properties
  2. Google Cloud Storage - Use googleCloudStorage with source and path properties
  3. Google Cloud Build repository - Use googleCloudBuildRepo with repository, path, and ref properties

Using a different cloud?

Explore integration guides for other cloud providers: