LogoLogo
Bonsai (0.13) DocsGitHubDiscord CommunityGarden Enterprise
Bonsai (0.13)
Bonsai (0.13)
  • Welcome to Garden!
  • 🌸Overview
    • How Garden Works
    • Core Concepts
    • Adopting Garden
    • Garden vs Other Tools
  • 🌳Use Cases
    • Isolated On-Demand Preview Environments
    • Fast, Portable CI Pipelines that Run Anywhere
    • Shift Testing Left
    • Local Development With Remote Clusters
    • Jumpstart your Internal Developer Platform
  • 🌻Getting Started
    • Quickstart Guide
    • Installing Garden
    • Next Steps
  • 💐Tutorials
    • Your First Project
      • 1. Create a Garden Project
      • 2. Pick a Kubernetes Plugin
      • 3. Add Actions
      • 4. Add Tests
      • 5. Code Syncing (Hot Reload)
      • 6. Next Steps
  • 🌿Using Garden
    • About
    • Configuration Overview
    • Projects
    • Dashboard
    • Actions
    • Tests
    • Runs
    • Workflows
    • Variables and templating
    • Config Templates
    • Using the CLI
    • Modules
  • Kubernetes Plugins
    • About
    • Remote K8s Plugin Configuration
      • 1. Create a Cluster
        • AWS
        • GCP
        • Azure
      • 2. Configure Container Registry
        • AWS
        • GCP
        • Azure
        • Docker Hub
      • 3. Set Up Ingress, TLS and DNS
      • 4. Configure the Provider
    • Local K8s Plugin Configuration
      • 1. Install Local Kubernetes
      • 2. Configure the Provider
    • Ephemeral K8s Plugin Configuration
      • 1. Configure the Provider
      • 2. Login to the Garden dashboard
      • 3. Configure Ingress (optional)
      • 4. Retrieve Kubeconfig (optional)
    • Actions
      • Build
        • Container
      • Deploy
        • Kubernetes
        • Helm
        • Container
        • PersistentVolumeClaim
        • ConfigMap
      • Run and Test
        • Kubernetes Pod
        • Helm Pod
        • Kubernetes Exec
        • Container
    • Guides
      • In-Cluster Building
      • Minimal RBAC Configuration for Development Clusters
      • Deploying to Production
      • Using a Registry Mirror
  • ☘️Terraform Plugin
    • About
    • Plugin Configuration
    • Actions
  • 🌹Pulumi Plugin
    • About
    • Plugin Configuration
    • Actions
  • 🌼Other Plugins
    • Container
    • Exec (local scripts)
  • 🌷Guides
    • Migrating to Bonsai
    • Migrating from Docker Compose to Garden
    • Deprecations and updating to Cedar
    • Code Synchronization
    • Connecting a local application to a Kubernetes cluster (Local Mode)
    • Environments and namespaces
    • Using Garden in CircleCI
  • 🪷Advanced
    • Using Remote Sources
    • Custom Commands
  • 🎋Reference
    • Providers
      • conftest-container
      • conftest-kubernetes
      • conftest
      • container
      • ephemeral-kubernetes
      • exec
      • hadolint
      • jib
      • kubernetes
      • local-kubernetes
      • octant
      • otel-collector
      • pulumi
      • terraform
    • Action Types
      • Build
        • container Build
        • exec Build
        • jib-container Build
      • Deploy
        • configmap Deploy
        • container Deploy
        • exec Deploy
        • helm Deploy
        • kubernetes Deploy
        • persistentvolumeclaim Deploy
        • pulumi Deploy
        • terraform Deploy
      • Run
        • container Run
        • exec Run
        • helm-pod Run
        • kubernetes-exec Run
        • kubernetes-pod Run
      • Test
        • conftest-helm Test
        • conftest Test
        • container Test
        • exec Test
        • hadolint Test
        • helm-pod Test
        • kubernetes-exec Test
        • kubernetes-pod Test
    • Template Strings
      • Project template context
      • Environment template context
      • Provider template context
      • Action (all fields) template context
      • Action spec template context
      • Module template context
      • Remote Source template context
      • Project Output template context
      • Custom Command template context
      • Workflow template context
      • Template Helper Functions
    • Commands
    • Project Configuration
    • ConfigTemplate Reference
    • RenderTemplate Reference
    • Workflow Configuration
    • Garden Containers on Docker Hub
    • Module Template Configuration
    • Module Types
      • configmap
      • conftest
      • container
      • exec
      • hadolint
      • helm
      • jib-container
      • kubernetes
      • persistentvolumeclaim
      • pulumi
      • templated
      • terraform
  • 🌸Misc
    • FAQ
    • Troubleshooting
    • Telemetry
    • New Garden Cloud Version
  • Contributing to Garden
    • Contributor Covenant Code of Conduct
    • Contributing to the Docs
    • Setting up your developer environment
    • Developing Garden
    • Config resolution
    • Graph execution
Powered by GitBook
On this page
  • Referencing manifests
  • Option 1: Manifest files (recommended)
  • Option 2: Inline
  • Deploying a container image built by Garden
  • Option 1: Patching resources (recommended)
  • Option 2: Using Garden template strings
  • Overwriting values
  • Setting a default target resource
  • Code Synchronization
  • Production environments
  • Next steps

Was this helpful?

  1. Kubernetes Plugins
  2. Actions
  3. Deploy

Kubernetes

PreviousDeployNextHelm

Last updated 1 month ago

Was this helpful?

You can use the kubernetes Deploy action type to deploy the parts of your stack that already have Kubernetes manifests.

In the sections below we'll explain how to:

  • Point Garden to your manifests

  • Deploy a container image that's been built by Garden

  • Overwrite values in your manifests to suit your environment

  • Set the deployment target so Garden can stream logs and sync code changes

  • Configure code syncing for rapid development

The kubernetes Deploy action type works very similarly to the Deploy action, and you'll find a lot common between the two guides.

See the full spec for the kubernetes deploy action in our .

Referencing manifests

When configuring a kubernetes Deploy action, you point Garden to the manifest files via the spec.files directive.

You can also specify them inline in your Garden config via the spec.manifests field but we recommend the former approach since that allows you to re-use them with other tools.

Option 1: Manifest files (recommended)

If your project structure looks something like this:

.
├── api
│   ├── garden.yml
│   ├── manifests
│   │   ├── prod
│   │   ├── Deployment.yaml
│   │   ├── Ingress.yaml
│   │   └── Service.yaml
│   │   ├── dev
│   │   ├── Deployment.yaml
│   │   ├── Ingress.yaml
│   │   └── Service.yaml
│   └── src
└── project.garden.yml

You can reference the manifests like so:

kind: Deploy
type: kubernetes
name: api
spec:
  files:
    - ./manifests/Deployment.yaml
    - ./manifests/Ingress.yaml
    - ./manifests/Service.yaml

You can also use glob patterns like so:

kind: Deploy
type: kubernetes
name: api
spec:
  files:
    - ./manifests/*

You can also use templating to reference different manifests based on environment.

For example, if your project structure looks like this:

.
├── api
│   ├── garden.yml
│   ├── manifests
│   │   ├── dev
│   │   │   ├── Deployment.yaml
│   │   │   ├── Ingress.yaml
│   │   │   └── Service.yaml
│   │   └── prod
│   │       ├── Deployment.yaml
│   │       ├── Ingress.yaml
│   │       └── Service.yaml
│   └── src
└── project.garden.yml

You can reference the manifests like so:

kind: Deploy
type: kubernetes
name: api
spec:
  files:
    - ./manifests/${environment.name}/Deployment.yaml
    - ./manifests/${environment.name}/Ingress.yaml
    - ./manifests/${environment.name}/Service.yaml

If your manifests are in a parent directory relative to the action config file, you need to set the source.path field for your action since Garden cannot include files from parent directories.

For example, if your project has the following structure:

.
├── api
│   ├── src
│   ├── garden.yml
├── manifests
│   ├── Deploment.yaml
│   ├── Ingress.yaml
│   └── Service.yaml
└── project.garden.yml

You can reference manifests like so:

kind: Deploy
type: kubernetes
name: api
source:
  path: ../ # <--- Garden will now treat the parent directory as the action source path
spec:
  files:
    - ./manifests/Deployment.yaml # <--- Reference the manifests relative to the source path
    - ./manifests/Ingress.yaml
    - ./manifests/Service.yaml

Option 2: Inline

You can also include the manifests inline with your Garden configuration although we generally recommend having dedicated manifest files since those are easier to re-use and will work with other tools.

You define manifests inline like so:

kind: Deploy
type: kubernetes
name: api
spec:
  manifests:
    - apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: api
        labels:
          app: api
      spec:
        # ...

    - apiVersion: v1
      kind: Service
      metadata:
      labels:
        app: api
        name: api
      spec:
        # ...
    - apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: api
        labels:
          app: api
      spec:
        # ...

Deploying a container image built by Garden

Most commonly you'll use the kubernetes Deploy action together with a container Build action. That is, you build your source code with one action and deploy it with another.

Simplified, it looks like this:

kind: Build
type: container
name: api
---
kind: Deploy
type: kubernetes
name: api
dependencies: [build.api] # <--- This ensures the image is built before its deployed
spec:
  files: [my-manifests.yml]

The problem here is that your manifests will likely contain a "hard coded" container image whereas the image built by Garden will have a different version.

There's a few ways to handle that but the recommend approach is to use the patchResources field.

Option 1: Patching resources (recommended)

The config will look like this:

kind: Build
type: container
name: api
---
kind: Deploy
type: kubernetes
name: api
dependencies: [build.api]
spec:
  files: [my-manifests.yml]
  patchResources:
    - name: api # <--- The name of the resource to patch, should match the name in the K8s manifest
      kind: Deployment # <--- The kind of the resource to patch
      patch:
        spec:
          template:
            spec:
              containers:
                - name: api # <--- Should match the container name from the K8s manifest
                  image: ${actions.build.api.outputs.deployment-image-id} # <--- The output from the Build action above

With this approach, you can add the Garden action to your project without making any changes to existing config.

Option 2: Using Garden template strings

You can use Garden template strings in your Kubernetes manifests, both in manifests from files and in inline manifests.

For example, if you're using manifest files you can set the image like so:

# In the corresponding manifest file
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  labels:
    app: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: ${actions.build.api.outputs.deployment-image-id} # <--- Garden will resolve this to the correct image before applying the manifest

Similarly, if you define your manifest inline you can set the image like so:

kind: Build
type: container
name: api
---
kind: Deploy
type: kubernetes
name: api
dependencies: [build.api]
spec:
  files: [my-manifests.yml]
  manifests:
    - apiVersion: apps/v1
      kind: Deployment
      spec:
        template:
          spec:
            containers:
              - name: api
                image: ${actions.build.api.outputs.deployment-image-id} # <--- The output from the Build action above

Overwriting values

You can use the exact same pattern as above where we set the container image to overwrite other values from your manifests.

If you for example need to change the number or replicas depending on environment and/or set some env variables, you can do so via the patchResources field like we did above. For example:

kind: Build
type: container
name: api
---
kind: Deploy
type: kubernetes
name: api
spec:
  files: [my-manifests.yml]
  patchResources:
    - name: api # <--- The name of the resource to patch, should match the name in the K8s manifest
      kind: Deployment # <--- The kind of the resource to patch
      patch:
        spec:
          replicas: "${environment.name == 'dev' ? 1 : 3}" # <-- Set replicas depending on environment
          template:
            spec:
              containers:
                - name: api # <--- Should match the container name from the K8s manifest
                  env:
                    LOG_LEVEL: "${environment.name == 'dev' ? 'verbose' : 'info' }"

The benefit of this approach is that you don't need to make any changes to your existing manifests.

Setting a default target resource

This is only relevant for Deploy actions that deploy resources that contain a Pod spec. If you're using the action to e.g. deploy a ConfigMap or a Secret you can skip this.

Some Garden commands like the logs and exec commands depend on Garden knowing what the target Kubernetes resource is. Same applies to code synchronization, Garden needs to know into what container in which Pod to sync code changes.

To enable this, users can configure a default target for Garden to use for these commands like so:

kind: Deploy
type: kubernetes
name: api
spec:
  files: [my-manifests.yml]
  defaultTarget: # <--- The values below should match one of the K8s resources from the manifests
    kind: Deployment
    name: api
    containerName: api # <--- If not set, Garden picks the first container from the Pod spec

Instead of specifying the target kind and name, you can also set a pod selector directly like so:

kind: Deploy
type: kubernetes
name: api
spec:
  files: [my-manifests.yml]
  defaultTarget:
    podSelector: # <--- This should match the labels in the desired Pod spec. A random Pod with matching labels will be picked as the target.
      app: api
      environment: dev

Code Synchronization

Code synchronization (i.e. hot reloading) can be configured for the Kubernetes Deploy action. In the example below, code synchronization is set up from the api Build action's directory.

kind: Deploy
type: kubernetes
name: api
---
spec:
  defaultTarget:
    kind: Deployment
    name: api
  sync:
    paths:
      - containerPath: /app/src
        sourcePath: ${actions.build.api.sourcePath}/src
        mode: two-way

Production environments

Next steps

The patchResources directive allows you to overwrite any field in your manifests using without modifying the underlying manifest.

Here's a using this approach.

Here's a using this approach. The downside though is that this is no longer a valid Kubernetes manifest.

If you'd rather use template strings in the manifests, you can do that as well as described in the section above.

For more information on synchronization, check out the full .

You can define a remote environment as a production environment by setting the to true. This affects some default behavior when working with kubernetes actions. See the guide for details.

Add Test and Run actions via the and action types.

You'll also find the .

helm
reference docs
Kubernetes' built-in patch functionality
complete example project
complete example
Code Synchronization Guide
kubernetes-pod
kubernetes-exec
full Kubernetes Deploy action reference here
referencing container images
Deploying to production
production flag