Terraform Provider kubectl

repository·master·Indexed 20 days ago

https://github.com/gavinbunney/terraform-provider-kubectl

A Terraform provider that allows users to manage Kubernetes resources using native YAML manifests. It treats YAML as the source of truth to handle the full resource lifecycle, including drift detection. The provider includes data sources for splitting multi-document YAML files (kubectl_file_documents), listing manifests via glob patterns (kubectl_filename_list), rendering Kustomize targets (kubectl_kustomize_documents), and retrieving Kubernetes server version information (kubectl_server_version).

Tokens
8.4K
Snippets
28
Records
36
Agent score
72%

What's inside terraform-provider-kubectl

  1. Use the kubectl_path_documents data source

    master

    The kubectl_path_documents data source allows you to find and split multi-document YAML files matching a specific glob pattern. It combines the functionality of finding files and parsing their individual YAML documents into a single resource. It also supports Terraform-style template rendering, allowing you to parameterize your manifests using variables.

    data "kubectl_path_documents" "docs" {
        pattern = "./manifests/*.yaml"
    }
  2. Ignore manifest fields in kubectl_manifest

    master

    Use the ignore_fields argument to prevent Terraform from attempting to update fields that are managed by Kubernetes controllers, operators, or other processes.

    Default Ignored Fields:

    • status
    • metadata.finalizers
    • metadata.initializers
    • metadata.ownerReferences
    • metadata.creationTimestamp
    • metadata.generation
    • metadata.resourceVersion
    • metadata.uid
    • metadata.annotations.kubectl.kubernetes.io/last-applied-configuration

    Syntax Rules:

    • Use dot-separated paths for maps (e.g., metadata.annotations).
    • Use zero-based indexing for arrays (e.g., webhooks.0.clientConfig.caBundle).
    # Example: Ignoring a specific annotation
    resource "kubectl_manifest" "test" {
        yaml_body = <<YAML
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: name-here
      namespace: default
      annotations:
        this.should.be.ignored: "true"
    YAML
    
        ignore_fields = ["metadata.annotations"]
    }
    
    # Example: Ignoring a field within an array
    resource "kubectl_manifest" "test" {
        yaml_body = <<YAML
    apiVersion: admissionregistration.k8s.io/v1beta1
    kind: MutatingWebhookConfiguration
    metadata:
      name: istio-sidecar-injector
    webhooks:
      - clientConfig:
          caBundle: ""
    YAML
    
        ignore_fields = ["webhooks.0.clientConfig.caBundle"]
    }
  3. Split multi-document YAML files with kubectl_file_documents

    master

    The kubectl_file_documents data source allows you to split a single YAML file containing multiple documents (separated by ---) into individual components that can be managed as separate Terraform resources.

    To use it, provide the file content to the content attribute. You can then access the split documents using either the manifests map (recommended) or the documents list.

    data "kubectl_file_documents" "docs" {
        content = file("multi-doc-manifest.yaml")
    }
  4. Obfuscate sensitive fields in kubectl_manifest

    master

    Use the sensitive_fields argument to hide specific field content from Terraform diff outputs. This is useful for preventing secrets from appearing in logs or console output.

    • Use dot-syntax to specify the path to the field.
    • Only Map values are supported for direct obfuscation. To obfuscate a value within a list, you must set the high-level key as sensitive to suppress the entire tree.
    • By default, v1/Secret manifests have ["data"] set as sensitive.
    resource "kubectl_manifest" "test" {
        sensitive_fields = [
            "metadata.annotations.my-secret-annotation"
        ]
    
        yaml_body = <<YAML
    apiVersion: admissionregistration.k8s.io/v1beta1
    kind: MutatingWebhookConfiguration
    metadata:
      name: istio-sidecar-injector
      annotations:
        my-secret-annotation: "this is very secret"
    webhooks:
      - clientConfig:
          caBundle: ""
    YAML
    }
  5. Run provider tests

    master

    The provider includes two types of tests:

    1. Integration Tests: Run make test. These use k3s to run a plan, apply, refresh, and plan loop over .tf files in the test/e2e folder. Note that the string name-here is automatically replaced with a unique name to prevent naming collisions.
    2. Acceptance Tests: Run make testacc. These create real resources and may incur costs.
    # Run integration tests
    $ make test
    
    # Run acceptance tests
    $ make testacc
  6. Install the kubectl provider for Terraform 0.12

    master

    For Terraform 0.12, you can install the latest version using a one-liner script that downloads the binary to your ~/.terraform.d/plugins directory, or you can manually download a binary from the release page and place it in your Terraform folder or system plugin folder.

    $ mkdir -p ~/.terraform.d/plugins && \
          curl -Ls https://api.github.com/repos/gavinbunney/terraform-provider-kubectl/releases/latest \
          | jq -r ".assets[] | select(.browser_download_url | contains("$(uname -s | tr A-Z a-z)")) | select(.browser_download_url | contains("amd64")) | .browser_download_url" \
          | xargs -n 1 curl -Lo ~/.terraform.d/plugins/terraform-provider-kubectl.zip && \
          pushd ~/.terraform.d/plugins/ && \
          unzip ~/.terraform.d/plugins/terraform-provider-kubectl.zip -d terraform-provider-kubectl-tmp && \
          mv terraform-provider-kubectl-tmp/terraform-provider-kubectl* . && \
          chmod +x terraform-provider-kubectl* && \
          rm -rf terraform-provider-kubectl-tmp && \
          rm -rf terraform-provider-kubectl.zip && \
          popd
  7. Use the kubectl_filename_list data source to list Kubernetes manifests

    master

    The kubectl_filename_list data source allows you to easily discover and iterate over directories containing Kubernetes manifest files. By using a glob pattern, you can retrieve a list of matching filenames, which can then be used with kubectl_manifest resources to apply multiple files dynamically using Terraform's count or for_each meta-arguments.

    data "kubectl_filename_list" "manifests" {
        pattern = "./manifests/*.yaml"
    }
    
    resource "kubectl_manifest" "test" {
        count     = length(data.kubectl_filename_list.manifests.matches)
        yaml_body = file(element(data.kubectl_filename_list.manifests.matches, count.index))
    }
  8. Use the kubectl_kustomize_documents data source to render manifests

    master

    The kubectl_kustomize_documents data source allows you to use Kustomize to render a target (such as a local directory or a remote URL) into a list of individual YAML documents. This is useful for generating Kubernetes manifests dynamically during a Terraform run.

    To use it, specify the target path or URL. The resulting documents are accessible via the documents attribute, which returns a list of strings, where each string is a single YAML document.

    data "kubectl_kustomize_documents" "manifests" {
        target = "https://github.com/kubernetes-sigs/kustomize/examples/multibases?ref=v1.0.6"
    }
    
    resource "kubectl_manifest" "test" {
        count     = length(data.kubectl_kustomize_documents.manifests.documents)
        yaml_body = element(data.kubectl_kustomize_documents.manifests.documents, count.index)
    }
  9. Install the kubectl provider for Terraform 0.13+

    master

    For Terraform versions 0.13 and above, the provider can be managed automatically via the required_providers block in your Terraform configuration. This is the recommended method for most users.

    terraform {
      required_version = ">= 0.13"
    
      required_providers {
        kubectl = {
          source  = "gavinbunney/kubectl"
          version = ">= 1.7.0"
        }
      }
    }
  10. Build the kubectl provider from source

    master

    To build the provider, you must have Go (version 1.12+) installed and a correctly configured GOPATH with $GOPATH/bin in your $PATH. Use make build to compile the provider into your $GOPATH/bin directory.

    $ go get github.com/gavinbunney/terraform-provider-kubectl
    $ cd $GOPATH/src/github.com/gavinbunney/terraform-provider-kubectl
    $ make build
  11. Use the kubectl_server_version resource to look up Kubernetes version information

    master

    The kubectl_server_version resource allows you to retrieve Kubernetes server version information. While it functions similarly to the kubectl_server_version data source, using it as a resource allows for more reliable dependency chaining (e.g., using depends_on), which can be difficult with data sources. This is useful when you need to ensure the Kubernetes API is available before attempting to match specific components like kube-proxy against the server version.

    resource "kubectl_server_version" "current" { }