Skip to content

Latest commit

 

History

History
907 lines (682 loc) · 18.2 KB

DOCS.md

File metadata and controls

907 lines (682 loc) · 18.2 KB

drone-gke Usage

Use this plugin to deploy Docker images to Google Container Engine (GKE).

API Reference

The following parameters are used to configure this plugin:

image

type string

default ''

description reference to a drone-gke Docker image

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke:0.9
    # ...

namespace

type string

default ''

description Kubernetes namespace to operate in

notes sets the context for kubectl

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      namespace: my-app
      # ...

project

type string

default ''

description GCP project ID; owner of the GKE cluster

notes default inferred from the service account credentials provided via token

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      project: my-gcp-project
      # ...

zone

type string

default ''

description GCP zone where GKE cluster is located

notes required if region is not provided

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      zone: us-east1-b
      # ...

region

type string

default ''

description GCP region where GKE cluster is located

notes required if zone is not provided

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      region: us-west-1
      # ...

cluster

type string

default ''

description name of GKE cluster

notes required

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      cluster: prod
      # ...

namespace

type string

default ''

description name of Kubernetes Namespace where manifests will be applied

notes if not specified, resources will be applied to default Namespace; if specified and create_namespace is set to false, the Namespace resource must already exist within the cluster

example

# .drone.yml
---
pipeline:
  # ...
  deploy:
    image: nytimes/drone-gke
    cluster: prod
    namespace: petstore
    # ...

template

type string

default '.kube.yml'

description path to Kubernetes manifest template

notes rendered using the Go text/template package. If the file does not exist, set skip_template to true.

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      template: k8s/app.yaml
      # ...

skip_template

type bool

default false

description parse and apply the Kubernetes manifest template

notes turn off the use of the template, regardless if the file exists or not

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      template: k8s/app.yaml
      skip_template: true
      # ...

secret_template

type string

default '.kube.sec.yml'

description path to Kubernetes Secret resource manifest template

notes rendered using the Go text/template package. If the file does not exist, set skip_secret_template to true.

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      secret_template: my-templates/secrets.yaml
      # ...

skip_secret_template

type bool

default false

description parse and apply the Kubernetes Secret resource manifest template

notes turn off the use of the template, regardless if the file exists or not

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      secret_template: my-templates/secrets.yaml
      skip_secret_template: true
      # ...

wait_deployments

type []string

default []

description wait for the given deployments using kubectl rollout status ...

notes deployments can be specified as "<type>/<name>" as expected by kubectl. If just "<name>" is given it will be defaulted to "deployment/<name>".

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      wait_deployments:
      - deployment/app
      - statefulset/memcache
      - nginx
      # ...

wait_seconds

type int

default 0

description number of seconds to wait before failing the build

notes ignored if wait_deployments is not set

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      wait_seconds: 180
      wait_deployments:
      - deployment/app
      - statefulset/memcache
      - nginx
      # ...

wait_jobs

type []string

default []

description wait for the given jobs using kubectl wait --for=conditon=complete ...

notes deployments can be specified as "job/<name>" as expected by kubectl. If just "<name>" is given it will be defaulted to "job/<name>".

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-eks
    image: nytimes/drone-eks
    settings:
      wait_jobs:
      - job/migration
      - otherjob
      # ...

wait_jobs_seconds

type int

default 0

description number of seconds to wait for jobs to complete before failing the build

notes ignored if wait_jobs is not set

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-eks
    image: nytimes/drone-eks
    settings:
      wait_jobs_seconds: 180
      wait_jobs:
      - migration
      # ...

vars

type map[string]interface{}

default

{
  // from $DRONE_BUILD_NUMBER
  "BUILD_NUMBER": "",
  // from $DRONE_COMMIT
  "COMMIT": "",
  // from $DRONE_BRANCH
  "BRANCH": "",
  // from $DRONE_TAG
  "TAG": "",
  // from `project`
  "project": "",
  // from `zone`
  "zone": "",
  // from `cluster`
  "cluster": "",
  // from `namespace`
  "namespace": "",
}

description variables to use in template and secret_template

notes see "Available vars" for details

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      vars:
        app_name: echo
        app_image: gcr.io/google_containers/echoserver:1.4
        env: dev
      # ...

secrets

type map[string]string

default {}

description variables to use in secret_template; credentials for drone-gke

notes TOKEN is required; SECRET_ prefix is required - see "Using secrets" for details

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      # ...
    environment:
      # custom secrets; only available within `secret_template`
      SECRET_APP_API_KEY:
        from_secret: APP_API_KEY_DEV
      SECRET_BASE64_P12_CERT:
        from_secret: BASE64_P12_CERT_DEV
      # required by `drone-gke`; not available within templates
      TOKEN:
        from_secret: DRONE_GKE_SERVICE_ACCOUNT_KEY_DEV

expand_env_vars

type bool

default false

description expand environment variables for values in vars for reference

notes only available for vars of type string; use $${var_to_expand} instead of ${var_to_expand} (two $$) to escape drone's variable substitution

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    environment:
      # ;)
      PS1: 'C:${PWD//\//\\\\}>'
    settings:
      expand_env_vars: true
      vars:
        # CLOUD_SDK_VERSION (set by google/cloud-sdk) will be expanded
        message: "deployed using gcloud v$${CLOUD_SDK_VERSION}"
        # PS1 (set using standard drone `environment` field) will be expanded
        prompt: "cmd.exe $${PS1}"
        # HOSTNAME and PATH (set by shell) will not be expanded; the `hostnames` and `env` vars are set to non-string values
        hostnames:
        - example.com
        - blog.example.com
        - "$${HOSTNAME}"
        env:
          path: "$${PATH}"
      # ...

kubectl_version

type string

default ''

description version of kubectl executable to use

notes see Using "extra" kubectl versions for details

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      kubectl_version: "1.14"
      # ...

dry_run

type bool

default false

description do not apply the Kubernetes templates

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      dry_run: true
      # ...

server_side

type bool

default false

description Perform a Kubernetes server-side apply

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      server_side: true
      # ...

verbose

type bool

default false

description dump available vars and the generated Kubernetes template

notes excludes secrets

example

# .drone.yml
---
kind: pipeline
# ...
steps:
  - name: deploy-gke
    image: nytimes/drone-gke
    settings:
      verbose: true
      # ...

create_namespace

type bool

default true

description automatically create a Namespace resource when a namespace value is specified

notes depends on non-empty namespace value; the resource will always be applied to the cluster prior to any resources included in template / secret_template; may modify any existing Namespace resource configuration; the automatically created Namespace resource is not configurable (see source for more details);

example

# .drone.yml
---
pipeline:
  # ...
  deploy:
    image: nytimes/drone-gke
    namespace: petstore
    create_namespace: false
    # ...

Service Account Credentials

drone-gke requires a Google service account and uses its JSON credential file to authenticate.

This must be passed to the plugin under the target token. If provided in base64 format, the plugin will decode it internally.

The plugin infers the GCP project from the JSON credentials (token) and retrieves the GKE cluster credentials.

GUI

Simply copy the contents of the JSON credentials file and paste it directly in the input field (for example for a secret named GOOGLE_CREDENTIALS).

CLI

drone secret add \
  --event push \
  --event pull_request \
  --event tag \
  --event deployment \
  --repository org/repo \
  --name GOOGLE_CREDENTIALS \
  --value @gcp-project-name-key-id.json

Cluster Credentials

The plugin attempts to fetch credentials for authenticating to the cluster via kubectl.

If connecting to a regional cluster, you must provide the region parameter to the plugin and omit the zone parameter.

If connecting to a zonal cluster, you must provide the zone parameter to the plugin and omit the region parameter.

The zone and region parameters are mutually exclusive; providing both to the plugin for the same execution will result in an error.

Using secrets

drone-gke also supports creating Kubernetes secrets for you. These secrets should be passed from Drone secrets to the plugin as environment variables with targets with the prefix secret_. These secrets will be used as variables in the secret_template in their environment variable form (uppercased).

Kubernetes expects secrets to be base64 encoded, drone-gke does that for you. If you pass in a secret that is already base64 encoded, please apply the prefix secret_base64_ and the plugin will not re-encode them.

Available vars

These variables are always available to reference in any manifest, and cannot be overwritten by vars or secrets:

{
  "BRANCH": "main",
  "BUILD_NUMBER": "12",
  "COMMIT": "4923x0c3380413ec9288e3c0bfbf534b0f18fed1",
  "TAG": "",
  "cluster": "my-gke-cluster",
  "namespace": "",
  "project": "my-gcp-proj",
  "zone": "us-east1-a"
}

Expanding environment variables

It may be desired to reference an environment variable for use in the Kubernetes manifest. In order to do so in vars, the expand_env_vars must be set to true.

For example when using drone deploy org/repo 5 production -p IMAGE_VERSION=1.0, to get IMAGE_VERSION in vars:

expand_env_vars: true
vars:
  image: my-image:$${IMAGE_VERSION}

The equivalent command for Drone 1.0 and above would be: drone build promote org/repo 5 production -p IMAGE_VERSION=1.0

The plugin will expand the environment variable for the template variable.

To use $${IMAGE_VERSION} or $IMAGE_VERSION, see the Drone docs about preprocessing. ${IMAGE_VERSION} will be preprocessed to an empty string.

Using "extra" kubectl versions

tl;dr

To run drone-gke using a different version of kubectl than the default, set kubectl-version to the version you'd like to use.

For example, to use the 1.14 version of kubectl:

image: nytimes/drone-gke
settings:
  kubectl_version: "1.14"

This will configure the plugin to execute /google-cloud-sdk/bin/kubectl.1.14 instead of /google-cloud-sdk/bin/kubectl for all kubectl commands.

Background

Beginning with the 237.0.0 (2019-03-05) release of the gcloud SDK, "extra" kubectl versions are installed automatically when kubectl is installed via gcloud components install kubectl.

These "extra" versions are installed alongside the SDK's default kubectl version at /google-cloud-sdk/bin and are named using the following pattern:

kubectl.$clientVersionMajor.$clientVersionMinor

To list all of the "extra" kubectl versions available within a particular version of drone-gke, you can run the following:

# list "extra" kubectl versions available with nytimes/drone-gke
docker run \
  --rm \
  --interactive \
  --tty \
  --entrypoint '' \
  nytimes/drone-gke list-extra-kubectl-versions

Example reference usage

.drone.yml

Note particularly the gke: build step.

---
kind: pipeline
type: docker
name: default

steps:
  - name: build
    image: golang:1.14
    environment:
      GOPATH: /drone
      CGO_ENABLED: 0
    commands:
      - go get -t
      - go test -v -cover
      - go build -v -a
    when:
      event:
        - push
        - pull_request

  - name: gcr
    image: plugins/gcr
    settings:
      registry: us.gcr.io
      repo: my-gke-project/my-app
      tags:
      - ${DRONE_COMMIT}
    secrets: [google_credentials]
    when:
      event: push
      branch: main

  - name: gke
    image: nytimes/drone-gke
    environment:
      TOKEN:
        from_secret: GOOGLE_CREDENTIALS
      USER: root
      SECRET_API_TOKEN:
        from_secret: APP_API_KEY
      SECRET_BASE64_P12_CERT:
        from_secret: P12_CERT
    settings:
      zone: us-central1-a
      cluster: my-gke-cluster
      namespace: ${DRONE_BRANCH}
      expand_env_vars: true
      vars:
        app: my-app
        env: dev
        image: us.gcr.io/my-gke-project/my-app:${DRONE_COMMIT}
        user: $${USER}
    when:
      event: push
      branch: main

.kube.yml

Note the three Kubernetes yml resource manifests separated by ---.

---
apiVersion: apps/v1
kind: Deployment

metadata:
  name: {{.app}}-{{.env}}

spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: {{.app}}
        env: {{.env}}
    spec:
      containers:
        - name: app
          image: {{.image}}
          ports:
            - containerPort: 8000
          env:
            - name: APP_NAME
              value: {{.app}}
            - name: USER
              value: {{.user}}
            - name: APP_API_KEY
              valueFrom:
                secretKeyRef:
                  name: {{.app}}-{{.env}}
                  key: app-api-key
---
apiVersion: v1
kind: Service

metadata:
  name: {{.app}}-{{.env}}

spec:
  type: NodePort
  selector:
    app: {{.app}}
    env: {{.env}}
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8000
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress

metadata:
  name: {{.app}}-{{.env}}

spec:
  backend:
    serviceName: {{.app}}-{{.env}}
    servicePort: 80

.kube.sec.yml

Note that the templated output will not be dumped when debugging.

---
apiVersion: v1
kind: Secret

metadata:
  name: {{.app}}-{{.env}}

type: Opaque

data:
  app-api-key: {{.SECRET_APP_API_KEY}}
  p12-cert: {{.SECRET_BASE64_P12_CERT}}