Kubernetes manifest task
Azure DevOps Services
Use a Kubernetes manifest task in a build or release pipeline to bake and deploy manifests to Kubernetes clusters.
Overview
The following list shows the key benefits of this task:
Artifact substitution: The deployment action takes as input a list of container images that you can specify along with their tags and digests. The same input is substituted into the nontemplatized manifest files before application to the cluster. This substitution ensures that the cluster nodes pull the right version of the image.
Manifest stability: The rollout status of the deployed Kubernetes objects is checked. The stability checks are incorporated to determine whether the task status is a success or a failure.
Traceability annotations: Annotations are added to the deployed Kubernetes objects to superimpose traceability information. The following annotations are supported:
- azure-pipelines/org
- azure-pipelines/project
- azure-pipelines/pipeline
- azure-pipelines/pipelineId
- azure-pipelines/execution
- azure-pipelines/executionuri
- azure-pipelines/jobName
Secret handling: The createSecret action lets Docker registry secrets be created using Docker registry service connections. It also lets generic secrets be created using either plain-text variables or secret variables. Before deployment to the cluster, you can use the secrets input along with the deploy action to augment the input manifest files with the appropriate imagePullSecrets value.
Bake manifest: The bake action of the task allows for baking templates into Kubernetes manifest files. The action uses tools such as Helm, Compose, and kustomize. With baking, these Kubernetes manifest files are usable for deployments to the cluster.
Deployment strategy: Choosing the canary strategy with the deploy action leads to creation of workloads having names suffixed with "-baseline" and "-canary". The task supports two methods of traffic splitting:
Service Mesh Interface: Service Mesh Interface (SMI) abstraction allows configuration with service mesh providers like Linkerd and Istio. The Kubernetes Manifest task maps SMI TrafficSplit objects to the stable, baseline, and canary services during the life cycle of the deployment strategy.
Canary deployments that are based on a service mesh and use this task are more accurate. This accuracy comes because service mesh providers enable the granular percentage-based split of traffic. The service mesh uses the service registry and sidecar containers that are injected into pods. This injection occurs alongside application containers to achieve the granular traffic split.
Kubernetes with no service mesh: In the absence of a service mesh, you might not get the exact percentage split you want at the request level. But you can possibly do canary deployments by using baseline and canary variants next to the stable variant.
The service sends requests to pods of all three workload variants as the selector-label constraints are met. Kubernetes Manifest honors these requests when creating baseline and canary variants. This routing behavior achieves the intended effect of routing only a portion of total requests to the canary.
Compare the baseline and canary workloads by using either a Manual Intervention task in release pipelines or a Delay task in YAML pipelines. Do the comparison before using the promote or reject action of the task.
Deploy action
Parameter | Description |
---|---|
action Action |
(Required) deploy |
kubernetesServiceConnection Kubernetes service connection |
(Required unless the task is used in a Kubernetes environment) The name of the Kubernetes service connection. |
namespace Namespace |
(Required unless the task is used in a Kubernetes environment) The namespace within the cluster to deploy to. |
manifests Manifests |
(Required) The path to the manifest files to be used for deployment. Each line represents a single path. A file-matching pattern is an acceptable value for each line. You can use to merge multiple YAML files into one. This can be useful when using this task in classic release pipelines. |
containers Containers |
(Optional) The fully qualified URL of the image to be used for substitutions on the manifest files. This input accepts the specification of multiple artifact substitutions in newline-separated form. Here's an example: containers: | contosodemo.azurecr.io/foo:test1 contosodemo.azurecr.io/bar:test2 In this example, all references to contosodemo.azurecr.io/foo and contosodemo.azurecr.io/bar are searched for in the image field of the input manifest files. For each match found, the tag test1 or test2 replaces the matched reference. |
imagePullSecrets Image pulls secrets |
(Optional) Multiline input where each line contains the name of a Docker registry secret that has already been set up within the cluster. Each secret name is added under imagePullSecrets for the workloads that are found in the input manifest files. |
strategy Strategy |
(Optional) The deployment strategy used while manifest files are applied on the cluster. Currently, canary is the only acceptable deployment strategy. |
trafficSplitMethod Traffic split method |
(Optional) Acceptable values are pod and smi. The default value is pod. For the value smi, the percentage traffic split is done at the request level by using a service mesh. A service mesh must be set up by a cluster admin. This task handles orchestration of SMI TrafficSplit objects. For the value pod, the percentage split isn't possible at the request level in the absence of a service mesh. Instead, the percentage input is used to calculate the replicas for baseline and canary. The calculation is a percentage of replicas that are specified in the input manifests for the stable variant. |
percentage Percentage |
(Required only if strategy is set to canary) The percentage that is used to compute the number of baseline-variant and canary-variant replicas of the workloads that are contained in manifest files. For the specified percentage input, calculate: (percentage × number of replicas) / 100 If the result isn't an integer, the mathematical floor of the result is used when baseline and canary variants are created. For example, assume the deployment hello-world is in the input manifest file and that the following lines are in the task input: replicas: 4 strategy: canary percentage: 25 In this case, the deployments hello-world-baseline and hello-world-canary are created with one replica each. The baseline variant is created with the same image and tag as the stable version, which is the four-replica variant before deployment. The canary variant is created with the image and tag corresponding to the newly deployed changes. |
baselineAndCanaryReplicas Baseline and canary replicas |
(Optional, and relevant only if trafficSplitMethod is set to smi) When you set trafficSplitMethod to smi, the percentage traffic split is controlled in the service mesh plane. But you can control the actual number of replicas for canary and baseline variants independently of the traffic split. For example, assume that the input deployment manifest specifies 30 replicas for the stable variant. Also assume that you specify the following input for the task: strategy: canary trafficSplitMethod: smi percentage: 20 baselineAndCanaryReplicas: 1 In this case, the stable variant receives 80% of the traffic, while the baseline and canary variants each receive half of the specified 20%. But baseline and canary variants don't receive three replicas each. They instead receive the specified number of replicas, which means they each receive one replica. |
rolloutStatusTimeout Timeout for rollout status |
(Optional) The length of time (in seconds) to wait before ending watch on rollout status. Default is 0 (don't wait). |
The following YAML code is an example of deploying to a Kubernetes namespace by using manifest files:
steps:
- task: KubernetesManifest@0
displayName: Deploy
inputs:
kubernetesServiceConnection: someK8sSC1
namespace: default
manifests: |
manifests/deployment.yml
manifests/service.yml
containers: |
foo/demo:$(tagVariable1)
bar/demo:$(tagVariable2)
imagePullSecrets: |
some-secret
some-other-secret
In the above example, the task tries to find matches for the images foo/demo
and bar/demo
in the image fields of manifest files. For each match found, the value of either tagVariable1
or tagVariable2
is appended as a tag to the image name. You can also specify digests in the containers input for artifact substitution.
Note
While you can author deploy, promote, and reject actions with YAML input related to deployment strategy, support for a Manual Intervention task is currently unavailable for build pipelines.
For release pipelines, we advise you to use actions and input related to deployment strategy in the following sequence:
- A deploy action specified with
strategy: canary
andpercentage: $(someValue)
. - A Manual Intervention task so that you can pause the pipeline and compare the baseline variant with the canary variant.
- A promote action that runs if a Manual Intervention task is resumed and a reject action that runs if a Manual Intervention task is rejected.
Promote and reject actions
Parameter | Description |
---|---|
action Action |
(Required) promote or reject |
kubernetesServiceConnection Kubernetes service connection |
(Required) The name of the Kubernetes service connection. |
namespace Namespace |
(Required) The namespace within the cluster to deploy to. |
manifests Manifests |
(Required) The path to the manifest files to be used for deployment. Each line represents a single path. A file-matching pattern is an acceptable value for each line. |
containers Containers |
(Optional) The fully qualified resource URL of the image to be used for substitutions on the manifest files. The URL contosodemo.azurecr.io/helloworld:test is an example. |
imagePullSecrets Image pull secrets |
(Optional) Multiline input where each line contains the name of a Docker registry secret that is already set up within the cluster. Each secret name is added under the imagePullSecrets field for the workloads that are found in the input manifest files. |
strategy Strategy |
(Optional) The deployment strategy used in the deploy action before a promote action or reject action. Currently, canary is the only acceptable deployment strategy. |
Create secret action
Parameter | Description |
---|---|
action Action |
(Required) createSecret |
secretType Secret type |
(Required) Acceptable values are dockerRegistry and generic. The default value is dockerRegistry. If you set secretType to dockerRegistry, the imagePullSecrets field is created or updated in a cluster to help image pull from a private container registry. |
secretName Secret name |
(Required) The name of the secret to be created or updated. |
dockerRegistryEndpoint Docker registry service connection |
(Required only if secretType is set to dockerRegistry) The credentials of the specified service connection are used to create a Docker registry secret within the cluster. Manifest files under the imagePullSecrets field can then refer to this secret's name. |
secretArguments Secret arguments |
(Required only if secretType is set to generic) Accepts keys and literal values to be used for creation and updating of secrets. Here's an example: --from-literal=key1=value1 --from-literal=key2="top secret" |
kubernetesServiceConnection Kubernetes service connection |
(Required) The name of the Kubernetes service connection. |
namespace Namespace |
(Required) The cluster namespace within which to create a secret. |
The following YAML code shows a sample creation of Docker registry secrets by using Docker Registry service connection:
steps:
- task: KubernetesManifest@0
displayName: Create secret
inputs:
action: createSecret
secretType: dockerRegistry
secretName: foobar
dockerRegistryEndpoint: demoACR
kubernetesServiceConnection: someK8sSC
namespace: default
This YAML code shows a sample creation of generic secrets:
steps:
- task: KubernetesManifest@0
displayName: Create secret
inputs:
action: createSecret
secretType: generic
secretName: some-secret
secretArguments: --from-literal=key1=value1
kubernetesServiceConnection: someK8sSC
namespace: default
Bake action
Parameter | Description |
---|---|
action Action |
(Required) bake |
renderType Render engine |
(Required) The render type used to produce the manifest files. Acceptable values are helm2, kompose, and kustomize. The default value is helm2. |
helmChart Helm chart |
(Required only if renderType is set to helm2) The path to the Helm chart used for baking. |
overrideFiles Override files |
(Optional, and relevant only if renderType is set to helm2) Multiline input that accepts the path to the override files. The files are used when manifest files from Helm charts are baked. |
overrides Override values |
(Optional, and relevant only if renderType is set to helm2) Additional override values that are used via the command-line switch --set when manifest files using Helm are baked. Specify override values as key-value pairs in the format key:value. If you use multiple overriding key-value pairs, specify each key-value pair in a separate line. Use a newline character as the delimiter between different key-value pairs. |
releaseName Release name |
(Optional, and relevant only if renderType is set to helm2) The name of the release used when baking Helm charts. |
kustomizationPath Kustomization path |
(Optional, and relevant only if renderType is set to kustomize) The path to the directory containing the file kustomization.yaml. |
dockerComposeFile Path to Docker compose file |
(Optional, and relevant only if renderType is set to kompose) The path to the Docker compose file. |
The following YAML code is an example of baking manifest files from Helm charts. Note the usage of name input in the first task. This name is later referenced from the deploy step for specifying the path to the manifests that were produced by the bake step.
steps:
- task: KubernetesManifest@0
name: bake
displayName: Bake K8s manifests from Helm chart
inputs:
action: bake
helmChart: charts/sample
overrides: 'image.repository:nginx'
- task: KubernetesManifest@0
displayName: Deploy K8s manifests
inputs:
kubernetesServiceConnection: someK8sSC
namespace: default
manifests: $(bake.manifestsBundle)
containers: |
nginx: 1.7.9
Scale action
Parameter | Description |
---|---|
action Action |
(Required) scale |
kind Kind |
(Required) The kind of Kubernetes object to be scaled up or down. Examples include ReplicaSet and StatefulSet. |
name Name |
(Required) The name of the Kubernetes object to be scaled up or down. |
replicas Replica count |
(Required) The number of replicas to scale to. |
kubernetesServiceConnection Kubernetes service connection |
(Required) The name of the Kubernetes service connection. |
namespace Namespace |
(Required) The namespace within the cluster to deploy to. |
rolloutStatusTimeout Timeout for rollout status |
(Optional) The length of time (in seconds) to wait before ending watch on rollout status. Default is 0 (don't wait). |
The following YAML code shows an example of scaling objects:
steps:
- task: KubernetesManifest@0
displayName: Scale
inputs:
action: scale
kind: deployment
name: bootcamp-demo
replicas: 5
kubernetesServiceConnection: someK8sSC
namespace: default
Patch action
Parameter | Description |
---|---|
action Action |
(Required) patch |
resourceToPatch Resource to patch |
(Required) Indicates one of the following patch methods:
|
resourceFiletoPatch File path |
(Required only if action is set to patch and resourceToPatch is set to file) The path to the file used for the patch. |
kind Kind |
(Required only if resourceToPatch is set to name) The kind of the Kubernetes object. Examples include ReplicaSet and StatefulSet. |
name Name |
(Required only if resourceToPatch is set to name) The name of the Kubernetes object to be patched. |
mergeStrategy Merge strategy |
(Required) The strategy to be used for applying the patch. Acceptable values are json, merge, and strategic. The default value is strategic. |
patch Patch |
(Required) The contents of the patch. |
kubernetesServiceConnection Kubernetes service connection |
(Required) The name of the Kubernetes service connection. |
namespace Namespace |
(Required) The namespace within the cluster to deploy to. |
rolloutStatusTimeout Timeout for rollout status |
(Optional) The length of time (in seconds) to wait before ending watch on rollout status. Default is 0 (don't wait). |
The following YAML code shows an example of object patching:
steps:
- task: KubernetesManifest@0
displayName: Patch
inputs:
action: patch
kind: pod
name: demo-5fbc4d6cd9-pgxn4
mergeStrategy: strategic
patch: '{"spec":{"containers":[{"name":"demo","image":"foobar/demo:2239"}]}}'
kubernetesServiceConnection: someK8sSC
namespace: default
Delete action
Parameter | Description |
---|---|
action Action |
(Required) delete |
arguments Arguments |
(Required) Arguments to be passed on to kubectl for deleting the necessary objects. An example is: arguments: deployment hello-world foo-bar |
kubernetesServiceConnection Kubernetes service connection |
(Required) The name of the Kubernetes service connection. |
namespace Namespace |
(Required) The namespace within the cluster to deploy to. |
This YAML code shows a sample object deletion:
steps:
- task: KubernetesManifest@0
displayName: Delete
inputs:
action: delete
arguments: deployment expressapp
kubernetesServiceConnection: someK8sSC
namespace: default
Troubleshooting
My Kubernetes cluster is behind a firewall and I am using hosted agents. How can I deploy to this cluster?
You can grant hosted agents access through your firewall by allowing the IP addresses for the hosted agents. For more details, see Agent IP ranges
Open source
This task is open source on GitHub. Feedback and contributions are welcome.
Feedback
Submit and view feedback for