Terraform module to manage Custom Resource Definitions in Kubernetes. Wraps kubectl_manifest resource that uses client-side rendering to avoid failures at planning stage. This will also consolidate CRD manifest within a single module to simplify upgrades.

Warning: you must establish a direct dependency between the resource that deploys CRD and the module that creates a CR. Otherwise, the planning phase will fail with the following error if the module doesn't find the CRD:

 bash Error: Provider produced null object
│  Provider "provider[\"registry.terraform.io/hashicorp/kubernetes\"]" produced a null value for module.mymodule.data.kubernetes_resource.crd.
│  This is a bug in the provider, which should be reported in the provider's own issue tracker.

This is intended behavior to ensure the correct order of resources creation.

Kubernetes CRD

Kubernetes CRD management
$50
BUY
1,525
Log in to Corewide IaC registry

Once you have a Corewide Solutions Portal account, this one-time action will use your browser session to retrieve credentials:

 shellterraform login solutions.corewide.com
Provision instructions

Initialize mandatory providers:

Copy and paste into your Terraform configuration and insert the variables:

 hclmodule "tf_k8s_crd" {
  source  = "solutions.corewide.com/kubernetes/tf-k8s-crd/kubectl"
  version = "~> 2.0.0"

  # specify module inputs here or try one of the examples below
  ...
}

Initialize the setup:

 shellterraform init
Define update strategy

Corewide DevOps team strictly follows Semantic Versioning Specification to provide our clients with products that have predictable upgrades between versions. We recommend pinning patch versions of our modules using pessimistic constraint operator (~>) to prevent breaking changes during upgrades.

To get new features during the upgrades (without breaking compatibility), use ~> 2.0 and run terraform init -upgrade

For the safest setup, use strict pinning with version = "2.0.0"

v2.0.0 released 1 year, 2 months ago
New version approx. every 9 weeks

Minimal example for CronTab

Adapted snippet from official docs:

 hclmodule "crontab" {
  source  = "solutions.corewide.com/kubernetes/tf-k8s-crd/kubectl"
  version = "~> 2.0"

  api_version = "stable.example.com/v1"
  kind        = "CronTab"

  metadata = {
    name = "cleanup-job"
  }

  spec = {
    cronSpec = "* * * * */5"
    image    = "custom.gcr.io/account/cleaner:latest"
  }
}

Switching from kubectl_manifest

  1. Rewrite your code first: change kubectl_manifest.something definition into module.something.
    Before:
 hclresource "kubectl_manifest" "sheep_counter" {
  yaml_body = yamlencode({
    apiVersion = "counting.sheep/v1beta1"
    kind       = "SheepCounter"
    ...
  })
}

After:

 hclmodule "sheep_counter" {
  source  = "solutions.corewide.com/kubernetes/tf-k8s-crd/kubectl"
  version = "~> 2.0"

  api_version = "counting.sheep/v1beta1"
  kind        = "SheepCounter"
  ...
}
  1. Move your old resource into new one in the TF state:
 bashterraform init
terraform state mv kubectl_manifest.sheep_counter module.sheep_counter.kubectl_manifest.crd
terraform apply
Variable Description Type Default Required Sensitive
api_version apiVersion of the resource string yes no
kind kind of the resource string yes no
metadata Custom resource metadata object yes no
spec spec content of the resource any yes no
metadata.annotations Annotations to attach to the resource map(any) {} no no
metadata.labels Labels to attach to the resource map(string) {} no no
metadata.name Name of the custom resource string yes no
metadata.namespace Namespace to deploy custom resource into string no no
recreate Whether the resource should be recreated and not updated during apply phase bool false no no
sensitive_fields List of fields to be marked as sensitive, for example, ['metadata.annotations.hello'] list(string) [] no no
Output Description Type Sensitive
attributes Decoded YAML body of the created custom resource attribute no
Dependency Version Kind
terraform >= 1.3 CLI
alekc/kubectl ~> 2.0 provider
hashicorp/kubernetes ~> 2.22 provider

Not sure where to start?
Let's find your perfect match.