Tasks

A Task (or a ClusterTask) is a collection of sequential
steps you would want to run as part of your continuous integration flow. A task
will run inside a container on your cluster.

A Task declares:

A Task is available within a namespace, and ClusterTask is available across
entire Kubernetes cluster.


ClusterTask

Similar to Task, but with a cluster scope.

In case of using a ClusterTask, the TaskRef kind should be added. The default
kind is Task which represents a namespaced Task

  1. apiVersion: tekton.dev/v1alpha1
  2. kind: Pipeline
  3. metadata:
  4. name: demo-pipeline
  5. namespace: default
  6. spec:
  7. tasks:
  8. - name: build-skaffold-web
  9. taskRef:
  10. name: build-push
  11. kind: ClusterTask
  12. params: ....

A Task functions exactly like a ClusterTask, and as such all references to
Task below are also describing ClusterTask.

Syntax

To define a configuration file for a Task resource, you can specify the
following fields:

  • Required:
    • [apiVersion][kubernetes-overview] - Specifies the API version, for example
      tekton.dev/v1alpha1.
    • [kind][kubernetes-overview] - Specify the Task resource object.
    • [metadata][kubernetes-overview] - Specifies data to uniquely identify the
      Task resource object, for example a name.
    • [spec][kubernetes-overview] - Specifies the configuration information for
      your Task resource object. Task steps must be defined through either of
      the following fields:
      • steps - Specifies one or more container images that you want
        to run in your Task.
  • Optional:

[kubernetes-overview]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields

The following example is a non-working sample where most of the possible
configuration fields are used:

  1. apiVersion: build.knative.dev/v1alpha1
  2. kind: Task
  3. metadata:
  4. name: example-task-name
  5. spec:
  6. serviceAccountName: task-auth-example
  7. inputs:
  8. resources:
  9. - name: workspace
  10. type: git
  11. params:
  12. - name: pathToDockerFile
  13. description: The path to the dockerfile to build
  14. default: /workspace/workspace/Dockerfile
  15. outputs:
  16. resources:
  17. - name: builtImage
  18. type: image
  19. steps:
  20. - name: ubuntu-example
  21. image: ubuntu
  22. args: ["ubuntu-build-example", "SECRETS-example.md"]
  23. - image: gcr.io/example-builders/build-example
  24. args: ["echo", "${inputs.resources.params.pathToDockerFile}"]
  25. - name: dockerfile-pushexample
  26. image: gcr.io/example-builders/push-example
  27. args: ["push", "${outputs.resources.builtImage.url}"]
  28. volumeMounts:
  29. - name: docker-socket-example
  30. mountPath: /var/run/docker.sock
  31. volumes:
  32. - name: example-volume
  33. emptyDir: {}

Steps

The steps field is required. You define one or more steps fields to define
the body of a Task.

Each steps in a Task must specify a container image that adheres to the
container contract. For each of the steps fields,
or container images that you define:

  • The container images are run and evaluated in order, starting from the top of
    the configuration file.
  • Each container image runs until completion or until the first failure is
    detected.

Inputs

A Task can declare the inputs it needs, which can be either or both of:

Parameters

Tasks can declare input parameters that must be supplied to the task during a
TaskRun. Some example use-cases of this include:

  • A Task that needs to know what compilation flags to use when building an
    application.
  • A Task that needs to know what to name a built artifact.

Parameters name are limited to alpha-numeric characters, - and _ and can
only start with alpha characters and _. For example, fooIs-Bar_ is a valid
parameter name, barIsBa$ or 0banana are not.

Usage

The following example shows how Tasks can be parameterized, and these parameters
can be passed to the Task from a TaskRun.

Input parameters in the form of ${inputs.params.foo} are replaced inside of
the steps (see also templating).

The following Task declares an input parameter called ‘flags’, and uses it in
the steps.args list.

  1. apiVersion: tekton.dev/v1alpha1
  2. kind: Task
  3. metadata:
  4. name: task-with-parameters
  5. spec:
  6. inputs:
  7. params:
  8. - name: flags
  9. value: -someflag
  10. steps:
  11. - name: build
  12. image: my-builder
  13. args: ["build", "--flags=${inputs.params.flags}"]

The following TaskRun supplies a value for flags:

  1. apiVersion: tekton.dev/v1alpha1
  2. kind: TaskRun
  3. metadata:
  4. name: run-with-parameters
  5. spec:
  6. taskRef:
  7. name: task-with-parameters
  8. inputs:
  9. params:
  10. - name: "flags"
  11. value: "foo=bar,baz=bat"

Input resources

Use input PipelineResources field to provide your Task with
data or context that is needed by your Task.

Input resources, like source code (git) or artifacts, are dumped at path
/workspace/task_resource_name within a mounted
volume and is available
to all steps of your Task. The path that the resources are mounted
at can be overridden with the targetPath value.

Outputs

Task definitions can include inputs and outputs
PipelineResource declarations. If specific set of resources
are only declared in output then a copy of resource to be uploaded or shared for
next Task is expected to be present under the path
/workspace/output/resource_name/.

  1. resources:
  2. outputs:
  3. name: storage-gcs
  4. type: gcs
  5. steps:
  6. - image: objectuser/run-java-jar #https://hub.docker.com/r/objectuser/run-java-jar/
  7. command: [jar]
  8. args:
  9. ["-cvf", "-o", "/workspace/output/storage-gcs/", "projectname.war", "*"]
  10. env:
  11. - name: "FOO"
  12. value: "world"

note: if the task is relying on output resource functionality then the
containers in the task steps field cannot mount anything in the path
/workspace/output.

In the following example Task tar-artifact resource is used both as input and
output so input resource is downloaded into directory customworkspace(as
specified in targetPath). Step untar extracts tar file into
tar-scratch-space directory , edit-tar adds a new file and last step
tar-it-up creates new tar file and places in /workspace/customworkspace/
directory. After execution of the Task steps, (new) tar file in directory
/workspace/customworkspace will be uploaded to the bucket defined in
tar-artifact resource definition.

  1. resources:
  2. inputs:
  3. name: tar-artifact
  4. targetPath: customworkspace
  5. outputs:
  6. name: tar-artifact
  7. steps:
  8. - name: untar
  9. image: ubuntu
  10. command: ["/bin/bash"]
  11. args: ['-c', 'mkdir -p /workspace/tar-scratch-space/ && tar -xvf /workspace/customworkspace/rules_docker-master.tar -C /workspace/tar-scratch-space/']
  12. - name: edit-tar
  13. image: ubuntu
  14. command: ["/bin/bash"]
  15. args: ['-c', 'echo crazy > /workspace/tar-scratch-space/rules_docker-master/crazy.txt']
  16. - name: tar-it-up
  17. image: ubuntu
  18. command: ["/bin/bash"]
  19. args: ['-c', 'cd /workspace/tar-scratch-space/ && tar -cvf /workspace/customworkspace/rules_docker-master.tar rules_docker-master']

Controlling where resources are mounted

Tasks can opitionally provide targetPath to initialize resource in specific
directory. If targetPath is set then resource will be initialized under
/workspace/targetPath. If targetPath is not specified then resource will be
initialized under /workspace. Following example demonstrates how git input
repository could be initialized in $GOPATH to run tests:

  1. apiVersion: tekton.dev/v1alpha1
  2. kind: Task
  3. metadata:
  4. name: task-with-input
  5. namespace: default
  6. spec:
  7. inputs:
  8. resources:
  9. - name: workspace
  10. type: git
  11. targetPath: go/src/github.com/tektoncd/pipeline
  12. steps:
  13. - name: unit-tests
  14. image: golang
  15. command: ["go"]
  16. args:
  17. - "test"
  18. - "./..."
  19. workingDir: "/workspace/go/src/github.com/tektoncd/pipeline"
  20. env:
  21. - name: GOPATH
  22. value: /workspace/go

Volumes

Specifies one or more
volumes that you want to
make available to your Task, including all the steps. Add volumes
to complement the volumes that are implicitly created for
input resources and output resources.

For example, use volumes to accomplish one of the following common tasks:

  • Mount a Kubernetes secret.
  • Create an emptyDir volume to act as a cache for use across multiple build
    steps. Consider using a persistent volume for inter-build caching.
  • Mount
    Kubernetes configmap
    as volume source.
  • Mount a host’s Docker socket to use a Dockerfile for container image builds.
    Note: Building a container image using docker build on-cluster is very
    unsafe
    . Use kaniko instead.
    This is used only for the purposes of demonstration.

Templating

Tasks support templating using values from all inputs and
outputs.

PipelineResources can be referenced in a Task spec like
this, where <name> is the Resource Name and <key> is a one of the resource’s
params:

  1. ${inputs.resources.<name>.<key>}

Or for an output resource:

  1. ${outputs.resources.<name>.<key>}

To access an input parameter, replace resources with params.

  1. ${inputs.params.<name>}

Templating Volumes

Task volume names and different
types of volumes
can be parameterized. Current support includes for widely used types of volumes
like configmap, secret and PersistentVolumeClaim. Here is an
example on how to use this in
Task definitions.

Examples

Use these code snippets to help you understand how to define your Tasks.

Tip: See the collection of simple
examples for
additional code samples.

Example Task

For example, a Task to encapsulate a Dockerfile build might look something
like this:

Note: Building a container image using docker build on-cluster is very
unsafe
. Use kaniko instead.
This is used only for the purposes of demonstration.

  1. spec:
  2. inputs:
  3. resources:
  4. - name: workspace
  5. type: git
  6. params:
  7. # These may be overridden, but provide sensible defaults.
  8. - name: directory
  9. description: The directory containing the build context.
  10. default: /workspace
  11. - name: dockerfileName
  12. description: The name of the Dockerfile
  13. default: Dockerfile
  14. outputs:
  15. resources:
  16. - name: builtImage
  17. type: image
  18. steps:
  19. - name: dockerfile-build
  20. image: gcr.io/cloud-builders/docker
  21. workingDir: "${inputs.params.directory}"
  22. args:
  23. [
  24. "build",
  25. "--no-cache",
  26. "--tag",
  27. "${outputs.resources.image}",
  28. "--file",
  29. "${inputs.params.dockerfileName}",
  30. ".",
  31. ]
  32. volumeMounts:
  33. - name: docker-socket
  34. mountPath: /var/run/docker.sock
  35. - name: dockerfile-push
  36. image: gcr.io/cloud-builders/docker
  37. args: ["push", "${outputs.resources.image}"]
  38. volumeMounts:
  39. - name: docker-socket
  40. mountPath: /var/run/docker.sock
  41. # As an implementation detail, this template mounts the host's daemon socket.
  42. volumes:
  43. - name: docker-socket
  44. hostPath:
  45. path: /var/run/docker.sock
  46. type: Socket

Using an extra volume

Mounting multiple volumes:

  1. spec:
  2. steps:
  3. - image: ubuntu
  4. entrypoint: ["bash"]
  5. args: ["-c", "curl https://foo.com > /var/my-volume"]
  6. volumeMounts:
  7. - name: my-volume
  8. mountPath: /var/my-volume
  9. - image: ubuntu
  10. args: ["cat", "/etc/my-volume"]
  11. volumeMounts:
  12. - name: my-volume
  13. mountPath: /etc/my-volume
  14. volumes:
  15. - name: my-volume
  16. emptyDir: {}

Using Kubernetes Configmap as Volume Source

  1. spec:
  2. inputs:
  3. params:
  4. - name: CFGNAME
  5. description: Name of config map
  6. - name: volumeName
  7. description: Name of volume
  8. steps:
  9. - image: ubuntu
  10. entrypoint: ["bash"]
  11. args: ["-c", "cat /var/configmap/test"]
  12. volumeMounts:
  13. - name: "${inputs.params.volumeName}"
  14. mountPath: /var/configmap
  15. volumes:
  16. - name: "${inputs.params.volumeName}"
  17. configMap:
  18. name: "${inputs.params.CFGNAME}"

Except as otherwise noted, the content of this page is licensed under the
Creative Commons Attribution 4.0 License,
and code samples are licensed under the
Apache 2.0 License.