Create a custom target

This document describes how to create a custom Cloud Deploy target type and use that custom target type as a target in a Cloud Deploy delivery pipeline.

The following is the high-level process for creating a custom target type and using it in your delivery pipeline:

  1. Create a containerized application or applications that include the functionality to deploy to your custom target, and that fulfill the Cloud Deploy requirements for custom target types.

  2. Define a custom action in skaffold.yaml that references that container and specifies the command or commands to run on it.

  3. Create a CustomTargetType definition referencing the custom action from the previous step, and register it as a Cloud Deploy resource.

  4. Define a new target with a customTarget property that identifies your new custom target type.

  5. Reference that target from your delivery pipeline progression.

  6. Create a release.

Each of these steps is described in detail in the rest of this document.

Create your containerized applications

The functionality to deploy to your custom target is defined in containerized applications, which you provide to Cloud Deploy by referencing them from your skaffold.yaml file. When your delivery pipeline includes a target that uses a custom target type, Cloud Deploy calls the custom-action containers defined for that custom target type, in Skaffold, to execute the render and deploy actions you've defined.

The behavior of your applications is up to you. However, it must consume the input environment variables provided by Cloud Deploy, and it must return the required outputs.

In most cases, you will create one container for your render action and one for your deploy action, for each custom target type you create. The render action is optional, but if you don't provide one, Cloud Deploy uses the default skaffold render.

Define your custom actions in Skaffold

With your custom-action container image or images in place, you reference them from your skaffold.yaml configuration file.

You configure each custom action for a custom target in a customActions stanza. For any custom target type, you create a custom action, in Skaffold, for render and one for deploy. The CustomTargetType definition identifies which custom action is used for render and which is used for deploy.

The following is the configuration for custom render and deploy actions in skaffold.yaml:

apiVersion: skaffold/v4beta7
kind: Config
customActions:
# custom render action
- name:
  containers:
  - name:
    image:
    command:
    args:
# custom deploy action
- name:
  containers:
  - name:
    image:
    command:
    args:

In this Skaffold configuration:

  • customActions.name

    Is an arbitrary name for the custom render or deploy action. The CustomTargetType definition references this name, in the renderAction property or the deployAction property.

  • The containers stanza includes your reference, plus commands to run that container.

    The containers stanza allows more than one container, but Google recommends you only use one.

  • customActions.containers.name

    Is an arbitrary name for the specific container you're using for this action. As a best practice, this container name should always be SHA qualified.

  • image

    Is the path to the container image.

  • command

    Is the command or commands to run on the container.

  • args

    Is a collection of arguments to the command.

See the Skaffold YAML reference for detailed documentation on the configuration properties used in customActions.

Define your custom target type

You define a custom target by first creating a custom target type, using the CustomTargetType configuration. You can create the CustomTargetType in the same file as your delivery pipeline definition, or with target definitions, or in a separate file.

The CustomTargetType definition is as follows:

# Custom target type config (preview)
apiVersion: deploy.cloud.google.com/v1
kind: CustomTargetType
metadata:
  name: [CUSTOM_TARGET_TYPE_NAME]
  annotations:
  labels:
description:
customActions:
  renderAction: [RENDER_ACTION_NAME]
  deployAction: [DEPLOY_ACTION_NAME]
  includeSkaffoldModules:

Where

  • CUSTOM_TARGET_TYPE_NAME

    Is an arbitrary name you give to this custom target type definition. This name is referenced in the target definition for any target that uses the custom target type you're defining.

  • RENDER_ACTION_NAME

    Is the name of the custom render action. This value is the customAction.name defined in skaffold.yaml for the render action.

  • DEPLOY_ACTION_NAME

    Is the name of the custom deploy action. This value is the customAction.name defined in skaffold.yaml for the deploy action.

  • includeSkaffoldModules

    Is an optional stanza to use if you're using remote Skaffold configs. The properties in this stanza are shown in the section Use remote Skaffold configs.

Use remote Skaffold configs

You can store Skaffold configs in a public Git repository, Cloud Storage bucket, or Cloud Build 2nd gen repository and reference those configs from your custom target type definition.

Using remote Skaffold configs means that the skaffold.yaml you provide at release time doesn't need to have the custom actions defined. This allows for sharing custom actions across your organization.

To use remote Skaffold configs:

  1. Create a Skaffold configuration with your custom action or actions.

  2. Store the configuration in a Git repository or in a Cloud Storage bucket.

  3. In your custom target type definition, add a customActions.includeSkaffoldModules stanza.

  4. Under includeSkaffoldModules, specify the following:

    • Optionally, one or more configs elements:

      - configs: ["name1", "name2"]

      The value of configs is a list of strings that match the metadata.name property on each Skaffold config to be included. If this is omitted, Cloud Deploy takes all of the configs in the specified path.

    • Either a googleCloudStorage, git, or googleCloudBuildRepo stanza.

      For Cloud Storage:

      googleCloudStorage:
        source: PATH_TO_GCS_BUCKET
        path: FILENAME
      

      For Git:

      git:
        repo: REPO_URL
        path: PATH_TO_FILE
        ref: BRANCH_NAME
      

      For Cloud Build Repositories (2nd gen):

       googleCloudBuildRepo:
        repository: PATH_TO_GCB_REPO
        path: PATH_TO_FILE
        ref: BRANCH_NAME
      

      Where:

      PATH_TO_GCS_BUCKET is the path to a Cloud Storage directory, ending with /*, where the Skaffold configs are stored. Skaffold downloads all the files in this directory then finds the relevant Skaffold file with the configs, based on the configured relative path.

      PATH_TO_GCB_REPO is the path to the Cloud Build 2nd gen repository where the Skaffold configs are stored. The path takes the following form: projects/{project}/locations/{location}/connections/{connection}/repositories/{repository}. Skaffold downloads all the files in this directory then finds the Skaffold file, based on the configured relative path.

      FILENAME is the name of the file that includes the Skaffold configs. This path: property is optional; if you don't specify it, Cloud Deploy assumes skaffold.yaml. If there's no skaffold.yaml, or if the filename you specify is not there, then the release creation fails.

      REPO_URL is the URL to the Git repository.

      PATH_TO_FILE is the path in that repository to the file containing the Skaffold configs.

      BRANCH_NAME is the name of the branch (for example, main) from which to take the Skaffold configs.

Example

The following custom target-type YAML is a customActions stanza with an includeSkaffoldModules stanza, pointing to Skaffold configs stored in a Cloud Storage bucket:

customActions:
  renderAction: my-custom-action
  deployAction: my-custom-action
  includeSkaffoldModules:
    - configs: ["myConfig"]
      googleCloudStorage:
        source: "gs://my-custom-target-bucket/my-custom/*"
        path: "skaffold.yaml

The following YAML is a Skaffold config, which the custom action shown is referencing:

apiVersion: skaffold/v4beta7
kind: Config
metadata:
  name: myConfig
customActions:
  - name: my-custom-action
    containers:
      - name: my-custom-container
        image: us-east1-docker.pkg.dev/abcdefg/foldername/myimage@sha256:c56fcf6e0a7637ddf0df3d56a0dd23bfce03ceca06a6fc527b0e0e7430e6e9f9

Register your custom target type

After you've configured the CustomTargetType, run the gcloud deploy apply command to register the CustomTargetType resource in a Google Cloud project:

gcloud deploy apply --file=[FILE] --project=[PROJECT] --region=[REGION]

Where:

FILE is the name of the file in which you've defined this custom target type.

PROJECT is the Google Cloud project in which to create this resource. The CustomTargetType must be in the same project as the Target resource that references it. You don't need to specify the project if you have set it as your default project for the Google Cloud CLI.

REGION is the region (for example, us-centra1) in which to create this resource. The CustomTargetType must be in the same region as the Target resource that references it. You don't need to specify the region if you have set it as your default region for the gcloud CLI.

With the CustomTargetType now created as a Cloud Deploy resource, you can now use it in a Target definition to create your custom target.

For more information on the CustomTargetType definition, see the Cloud Deploy configuration schema reference.

Define your target

The only difference between a target definition for a supported target type and a custom target definition is that the custom target definition includes a customTarget stanza. The syntax for a customTarget is as follows:

customTarget:
  customTargetType: [CUSTOM_TARGET_TYPE_NAME]

Where CUSTOM_TARGET_TYPE_NAME is the value from the name property defined in your custom target type configuration.

Add your target to the delivery pipeline

You can use a custom target in a delivery pipeline exactly as you would use a supported target type. That is, there is no difference in the delivery pipeline progression between targets of a supported target type and custom targets.

All targets in a delivery pipeline must use the same target type. For example, you can't have a delivery pipeline with some targets deploying to Google Kubernetes Engine and some custom targets.

As with supported target types, you can include deploy parameters in the pipeline stage.

Create a release

With your custom target type fully defined, and a target created to use that type, you can now create a release, in the normal way:

gcloud deploy releases create [RELEASE_NAME] \
  --project=[PROJECT_NAME] \
  --region=[REGION] \
  --delivery-pipeline=[PIPELINE_NAME]

Upon release creation your custom render action is executed for each target in your delivery pipeline, including processing deploy parameters configured on the release, targets, or the delivery pipeline. Cloud Deploy provides the deploy parameters as input to the custom render container.

View the output of your custom targets

If your custom action satisfies the requirements for custom targets, you can use Google Cloud console to view the rendered artifacts.

Follow these steps to view the output of your custom render action.

  1. In the Google Cloud console, navigate to the Cloud Deploy Delivery pipelines page to view your delivery pipeline.

    Open the Delivery pipelines page

  2. Click the name of your delivery pipeline.

    The pipeline visualization shows the app's deployment status, and your release is listed on the Releases tab under Delivery pipeline details.

  3. Click the release name.

    The Release details page is shown.

  4. Click the Artifacts tab.

  5. Under Target artifacts, click the arrow next to View artifacts.

    The rendered artifacts are listed, including the rendered skaffold.yaml and rendered manifest file generated by the custom renderer. And you can click the Storage location link next to each one to go to the Cloud Storage bucket to view those files.

    You can also click the View artifacts link to view those files by release, by target, or by phase, using the release inspector.

What's next