Run hooks before and after deploying

This document describes how to run arbitrary programs or operations before and/or after you deploy.

You can configure Cloud Deploy and Skaffold to run actions to perform pre-deployment actions or post-deployment actions, or both. These programs, run in this way, are called "hooks." Predeploy and postdeploy hooks runs as a predeploy and postdeploy jobs on the rollout.

You can configure each hook to run in a specified Cloud Deploy execution environment, but if you're deploying to Google Kubernetes Engine you can optionally configure it to run on the GKE cluster where you're deploying your application.

Deploy hooks are assumed to be idempotent. If a given action is run more than once, there is no additional effect.

How do deploy hooks work?

The following describes the steps for configuring deploy hooks, and the Skaffold and Cloud Deploy process for running those hooks:

  1. You configure the skaffold.yaml used for a given release to include customActions that identify the container image or images to use to run the hooks, and the specific command or script to run on each container.

  2. You configure hooks in one or more stages in your delivery pipeline progression, each of which references one of the customActions you configured in skaffold.yaml.

  3. Before the rollout's deploy job runs, Skaffold runs any commands configured in skaffold.yaml that are referenced in a predeploy stanza in the pipeline progression.

    The predeploy hook always runs as the first job in the phase.

  4. After the rollout's deploy job runs, Cloud Deploy runs any commands configured in skaffold.yaml that are referenced in a postdeploy stanza in the pipeline progression.

Deploy hooks are run in the default Cloud Deploy execution environment, or in a specified alternate execution environment. For deployments to GKE and GKE Enterprise, you can optionally run the hooks on the same cluster where the application is being deployed.

Using deploy hooks with a canary deployment

When you configure deploy hooks for a canary deployment, there are several things to know:

  • In the delivery pipeline stage, configuration of the hook (predeploy and postdeploy) is under strategy.canary.canaryDeployment or strategy.canary.customCanaryDeployment.phaseConfigs, rather than under strategy.standard.

  • For an automated canary, predeploy hooks are executed before the deploy in the first phase only, and postdeploy hooks are executed after the deploy in the last phase (stable) only.

Configure actions in Skaffold

In your skaffold.yaml file, the customActions stanza takes one or more customActions stanzas, configured as follows:

customActions
- name: ACTION_NAME
  containers:
  - name: CONTAINER_NAME
    image: IMAGE
    command: [COMMANDS_TO_RUN]
    args: [LIST_OF_ARGS]

In this customerActions stanza:

  • ACTION_NAME

    Is a name for this action. This name can be anything you want, but must be unique within this skaffold.yaml. This is the name that will be referenced from the pre- and post-deploy actions defined in the delivery pipeline stage.

  • CONTAINER_NAME

    Is a name for the specific container. This name can be anything you want, but must be unique within this skaffold.yaml.

  • IMAGE

    Is the name of the container image in which your command will execute.

  • COMMANDS_TO_RUN

    Is a list of entrypoints to run on that container. "/bin/sh" is a typical command to specify here, to invoke a shell, and you would include the command to run in that shell in the args.

  • LIST_OF_ARGS

    Is a list of arguments to provide to the command. This is a comma-separated list, with each argument in quotation marks. If your COMMAND_TO_RUN is "/bin/sh", then one of the arguments here would be "-c", and another argument would be the entire command you want to run in the shell you're invoking.

    Here's an example:

    command: ["/bin/sh"]
    args: ["-c", `echo "This command ran!"`]
    

To learn more about Skaffold custom actions, see the Skaffold documentation.

Configure the pipeline to reference the actions

To finish configuring your deploy hooks, you configure the delivery pipeline to reference the custom actions you defined in your skaffold.yaml file. Pre- and post-deploy actions are configured in one or more specific stages in the pipeline progression.

The following is how you would configure pre-and post-deploy hooks in a pipeline stage when using a standard deployment strategy:

serialPipeline:
  stages:
  - targetId: hooks-staging
    profiles: []
    strategy:
      standard:
        predeploy:
          actions: ["PREDEPLOY-ACTION"]
        postdeploy:
          actions: ["POSTDEPLOY-ACTION"] 

In this yaml:

  • PREDEPLOY_ACTION

    Is the same as the ACTION_NAME that you used in your skaffold.yaml to define the custom action you want to run before deploying.

  • POSTDEPLOY_ACTION

    Is the same as the ACTION_NAME that you used in your skaffold.yaml to define the custom action you want to run after deploying.

You can specify more than one action for predeploy and postdeploy, separated by commas. When more than one action is specified, they execute serially, in the order they're specified. The job (predeploy or postdeploy) fails on the first action that fails, and the remaining actions aren't run.

By default, if you're running more than one container, in parallel, and a job fails, both containers are stopped. You can configure this behavior using the Skaffold custom action fail strategy.

Run the hooks on the application cluster

By default, deploy hooks run in the Cloud Deploy execution environment. You can also configure Skaffold to run those custom actions on the same cluster where your application is running. When you configure custom actions in skaffold.yaml and enable them on a pipeline stage, the action runs automatically in that target's cluster.

This ability is available for deployments to GKE and GKE Enterprise only, not for Cloud Run. Deployments to Cloud Run can only run hooks in the Cloud Deploy execution environment.

To run your hook on the cluster, include an executionMode.kubernetesCluster stanza in your skaffold.yaml configuration file, inside the customActions stanza for the specific custom action:

customActions
- name: ACTION_NAME
  containers:
  - name: CONTAINER_NAME
    image: IMAGE
    command: [COMMANDS_TO_RUN]
    args: [LIST_OF_ARGS]
  executionMode:
    kubernetesCluster: {}

The following is an example customActions stanza that includes executionMode to invoke the hook container on the application cluster:

customActions:
- name: predeploy-action
  containers:
  - name: predeploy-echo
    image: ubuntu
    command: ["/bin/sh"]
    args: ["-c", 'echo "this is a predeploy action"' ]
  executionMode:
    kubernetesCluster: {}

The executionMode stanza is optional, and if you omit it, Skaffold runs the custom action container in the Cloud Deploy execution environment.

Available environment variables

Cloud Deploy provides and populates the following environment variables in the execution environment, which you can use for your hooks:

  • ANTHOS_MEMBERSHIP

    For targets of type ANTHOS, the fully specified resource name of the Anthos membership.

  • CLOUD_RUN_LOCATION

    For targets of type RUN, the region the Cloud Run service is deployed in.

  • CLOUD_RUN_PROJECT

    For targets of type RUN, the project in which the Cloud Run service was created.

  • CLOUD_RUN_SERVICE

    For targets of type RUN, the name of the Cloud Run service deployed.

  • CLOUD_RUN_SERVICE_URLS

    For targets of type RUN, the URL or URLs (comma-separated list) that end users will use to access your service. You can find these in the Cloud Run service details for your service, in the Google Cloud console.

  • CLOUD_RUN_REVISION

    For targets of type RUN, the specific revision of the Cloud Run service.

  • GKE_CLUSTER

    For targets of type GKE, the fully specified resource name of the Google Kubernetes Engine cluster, for example projects/p/locations/us-central1/clusters/dev.

  • TARGET_TYPE

    The specific runtime type of the target. Either GKE, ANTHOS, or RUN. For custom targets, this won't be set.

  • CLOUD_DEPLOY_LOCATION

    The region containing the Cloud Deploy resources.

  • CLOUD_DEPLOY_DELIVERY_PIPELINE

    The ID of the delivery pipeline.

  • CLOUD_DEPLOY_TARGET

    The ID of the target.

  • CLOUD_DEPLOY_PROJECT

    The Google Cloud project containing the Cloud Deploy resources.

  • CLOUD_DEPLOY_RELEASE

    The ID of the release in which the hooks will run.

  • CLOUD_DEPLOY_ROLLOUT

    The ID of the rollout that contains the jobs for the hooks.

  • CLOUD_DEPLOY_JOB_RUN

    The ID of the job run that represents the current execution of the job.

  • CLOUD_DEPLOY_PHASE

    The phase in the rollout that contains the job for the hooks.

What's next