Deploy to Kubernetes
Deploy a Kubernetes resource, as well as optionally a Kubernetes secret containing your Docker registry credentials. This
secret containing the Docker registry credentials is always called “acr-auth”. Also can create a Kubernetes secret
of any secrets available in your cloud vault that match the application name. This Kubernetes secret will be given the name:
{application_name}-secret. All cloud vault secrets will be stored in a key-value form in this single Kubernetes Secret.
If any of the Kubernetes resources already exists, this step will update them where appropriate (similar to what the
kubectl apply -f
command will do. In some cases, you may wish to restart a Kubernetes resource, even if the Kubernetes
yaml configuration has not changed. An example of this is if you build a new Docker image, with the same tag. The default Kubernetes
behaviour is to not restart the resource. Takeoff allows you to override this behaviour if so desired.
This task is usually used in combination with Build Docker Image (assuming your Kubernetes config references the image that is built)
Deployment
Add the following task to deployment.yaml
:
- task: deploy_to_kubernetes
kubernetes_config_path: my_kubernetes_config.yml.j2
This should be after the build_docker_image task if used together.
field | description | value |
---|---|---|
kubernetes_config_path |
The path to a yml jinja_templated Kubernetes deployment config |
Mandatory value, must be a valid path in the repository |
image_pull_secret |
Whether or not to create Kubernetes image pull secret to allow pulling images from your container registry. | Defaults to True, with secret_name=registry-auth and namespace=default |
image_pull_secret.create |
Whether or not to create Kubernetes image pull secret to allow pulling images from your container registry. | Defaults to True |
image_pull_secret.secret_name |
The name of secret | Defaults to secret_name |
image_pull_secret.namespace |
The namespace where the secret should be created in | Default to default |
restart_unchanged_resources |
Whether or not to restart unchanged Kubernetes resources. Takeoff will attempt to restart all unchanged resources, which may result in error messages in the logs, as not all resources are ‘restartable’ | Boolean, defaults to False. |
wait_for_rollout |
Whether or not to wait for the successful rollout of a specified resource. Note that only a limited subset of Kubernetes resources are supported (see docs below) | Defaults to not waiting for rollout |
wait_for_rollout.resource_name |
The name of the resource to wait on. Note that it should be specified in the format <resource_type>/<resource_name> |
No default value |
wait_for_rollout.resource_namespace |
The namespace of the resource to wait on | No default value |
custom_values |
Any custom values you’d like to pass in to be rendered into your Jinja-templates Kubernetes configuration. Should be specified per environment | No custom values are passed by default. Should be a set of key-value pairs per environment |
An example of kubernetes_config_path.yml.j2
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-app
spec:
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-docker-image:
imagePullPolicy:
ports:
- containerPort: 8443
env:
- name: SOME_SECRET
valueFrom:
secretKeyRef:
name: my-app-secret
key: some-secret
imagePullSecrets:
- name: acr-auth
---
apiVersion: v1
kind: Service
metadata:
name: my_service
spec:
ports:
- port: 443
protocol: TCP
targetPort: 8443
selector:
app: my_app
type: LoadBalancer
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host:
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
An explanation for the Jinja templated values. These values get resolved automatically during deployment.
field | description |
---|---|
docker_tag |
The docker tag to apply. In a D/T/A/P setup, this will allow you to point to the image that was built in a previous step in your Takeoff config without explicitly specifying this |
Other templated variables can be filled in two ways:
- Via your cloud keyvault, such as `` is a reference to a cloud vault key. The task will pull all secrets from the cloud vault prefixed with you application name and resolve them in the template.
For the example above, if your application name is
myapp
, then a secret in your cloud vault must bemyapp-secret-pull-policy
ormyapp-secret_pull_policy
. The prefix gets removed by Takeoff and keysecret_pull_policy
with it’s value will be passed into the template. Hyphens-
get normalized to underscores_
. - Via the
custom_values
configuration option specified indeployment.yml
. Here, you are expected to set any custom key-value pairs, per environment. An example is shown below. In the above Kubernetes configuration, the `` key is filled by a custom value passed in viadeployment.yml
.
Takeoff config
Make sure .takeoff/config.yml
contains the following keys:
azure:
kubernetes_naming: "my_kubernetes{env}"
keyvault_keys:
container_registry:
username: "registry-username"
password: "registry-password"
registry: "registry-server"
Default fields available for rendering
The following fields are available while rendering your Kubernetes yaml template:
| field | description
| —– | ———–
| docker_tag
| the tag assigned to the docker image (based on environment configuration)|
| application_name
| the application name (used throughout takeoff) |
| env
| the deployment environment (used throughout takeoff) |
| build_env
| the contents of the build-runner’s environment variables |
Examples
Minimum Takeoff deployment configuration example to deploy Kubernetes resources. This will not create image pull secrets:
steps:
- task: deploy_to_kubernetes
kubernetes_config_path: my_kubernetes_config.yml.j2
image_pull_secret:
create: False
Extended configuration example, where we have explicitly disabled the creation of kubernetes secrets by Takeoff. In this case,
we also want to restart the resources, even if their Kubernetes yaml config is unchanged. It will also create image pull secrets in namespace default
with name registry-auth
.
We also pass in a custom url value per environment in this example. In this case, we’re using the default environment naming that Takeoff itself uses too. Please take a look at
the environment docs for more information on how to define your own environment names.
steps:
- task: deploy_to_kubernetes
kubernetes_config_path: my_kubernetes_config.yml.j2
image_pull_secret:
create: True
restart_unchanged_resources: true
wait_for_rollout:
resource_name: "deployment/my_app"
resource_namespace: "my_namespace"
custom_values:
dev:
url: 'dev-url-here-being-buggy'
acp:
url: 'acp-url-here-being-awesome'
prd:
url: 'prd-url-here-being-glorious'
Waiting for successful rollout
In the extended example above, you can see the wait_for_rollout
parameter. This tells Takeoff that it should wait until the specified resource is rolled out successfully. If it is not
rolled out successfully, or is not rolled out successfully quickly enough (e.g. within the default Kubernetes timeout), the task will fail. The failure of this task will trigger
Kubernetes to rollback the change and revert to a previous revision that did work.
There are few things to note regarding this option:
- It may result in unexpected behaviour if there are several CI jobs running simultaneously that apply changes to the specified Kubernetes resource. It is possible that the wrong version is awaited. This is unlikely, but not impossible.
- Note that the resource_name must be prefixed with the resource_type. If this is not the case, a schema validation error will be thrown. Also note that not all resources are “awaitable”. For a full list of resources that can be awaited, we refer you to the Kubernetes documentation.
Takeoff Context
Eventhub producer policy secrets and consumer group secrets from configure_eventhub
are available during this task. This makes it possible for the configuration below to inject the secrets into my_kubernetes_config.yml.j2
:
steps:
- task: configure_eventhub
create_producer_policies:
- eventhub_entity_naming: entity1
- eventhub_entity_naming: entity2
create_consumer_groups:
- eventhub_entity_naming: entity3
- task: deploy_to_kubernetes
kubernetes_config_path: my_kubernetes_config.yml.j2
with my_kubernetes_config.yml.j2
apiVersion: v1
kind: Secret
metadata:
name: armada-connections
data:
entity1-producer-secret:
entity2-producer-secret:
entity3-consumer-secret:
The jinja variables entity1_connection_string
and entity2_connection_string
are named by your eventhub_entity_naming
in create_producer_policies
, posfixed with connection_string
.
Base64 encoding of secrets
Kubernetes requires the values of secrets to be base64 encoded. Takeoff enables this, and by default takes the following approach:
- Any values that are inserted into your Kubernetes template that originate from the Keyvault are assumed to be confidential. As such, Takeoff will ensure that these values are base64 encoded, as they should only be used in Kubernetes secrets.
- Any values that are inserted into your Kubernetes template via the custom values support (i.e. that are supplied in Takeoff’s deployment.yml) are assumed to not be confidential. These values will therefore be inserted into the template in plain text.
We believe these two assumptions are reasonable, and recommend you do not deviate from this. If, for some reason, you want/need to deviate from this, you can by using the following two filters in your Jinja template:
b64_encode
: apply base64 encoding. Example usage: ``b64_decode
: apply base64 decoding. Example usage: ``
TL;DR: secrets are base64 encoded by default, custom_values are not. You can deviate from this using the jinja2 filters if you like.