Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot apply changes to kubernetes_manifest directly after it has been imported #2639

Open
theKlisha opened this issue Dec 4, 2024 · 0 comments
Assignees
Labels

Comments

@theKlisha
Copy link

Hello,

Terraform fails to run apply after kubernetes_manifest that is defining kubernetes deployment has been imported if doing so would modify order of environment variables.

Terraform Version, Provider Version and Kubernetes Version

sh-3.2$ terraform -v
Terraform v1.10.1
on darwin_arm64
+ provider registry.terraform.io/hashicorp/kubernetes v2.34.0

sh-3.2$ kubectl version
Client Version: v1.31.1
Kustomize Version: v5.4.2
Server Version: v1.31.0

Affected Resource(s)

  • kubernetes_manifest

Terraform Configuration Files

terraform {
  backend "local" {
    path = "terraform.tfstate"
  }
}

terraform {
  required_providers {
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = ">=2.34.0"
    }
  }
  required_version = ">= 1.8.0"
}

provider "kubernetes" {
  config_path    = "~/.kube/config"
  config_context = "minikube"
}

resource "kubernetes_manifest" "manifest" {
  manifest = {
    apiVersion = "apps/v1"
    kind       = "Deployment"

    metadata = {
      name      = "test"
      namespace = "default"
    }

    spec = {
      replicas = 1

      selector = {
        matchLabels = { app = "test" }
      }

      template = {
        metadata = {
          labels = { app = "test" }
        }

        spec = {
          containers = [
            {
              name  = "nginx"
              image = "nginx"
              env = [
                { name = "A", valueFrom = { fieldRef = { apiVersion = "v1", fieldPath = "metadata.uid" } } },
                { name = "B", value = "B" },
              ]
            }
          ]
        }
      }
    }
  }
}

Debug Output

https://gist.github.com/theKlisha/4ef98730ba5836cc4fe7d1168b39e930

Steps to Reproduce

  1. terraform apply
  2. terraform state rm kubernetes_manifest.manifest
  3. terraform import kubernetes_manifest.manifest "apiVersion=apps/v1,kind=Deployment,namespace=default,name=test"
  4. modify terraform configuration: change order of env variables
          containers = [
            {
              name  = "nginx"
              image = "nginx"
              env = [
-               { name = "A", valueFrom = { fieldRef = { apiVersion = "v1", fieldPath = "metadata.uid" } } },
                { name = "B", value = "B" },
+               { name = "A", valueFrom = { fieldRef = { apiVersion = "v1", fieldPath = "metadata.uid" } } },
              ]
            }
          ]
  1. terraform apply

Expected Behavior

apply should succeed

Actual Behavior

apply fails with:

Error: API response status: Failure

  with kubernetes_manifest.manifest,
  on main.tf line 22, in resource "kubernetes_manifest" "manifest":
  22: resource "kubernetes_manifest" "manifest" {

Deployment.apps "test" is invalid:
[spec.template.spec.containers[0].env[0].valueFrom: Invalid value: "": may
not be specified when `value` is not empty,
spec.template.spec.containers[0].env[1].valueFrom: Invalid value: "": may not
be specified when `value` is not empty]

Error: Kubernetes API Error: Invalid Deployment.apps [test]

  with kubernetes_manifest.manifest,
  on main.tf line 22, in resource "kubernetes_manifest" "manifest":
  22: resource "kubernetes_manifest" "manifest" {


Error: spec.template.spec.containers[0].env[0].valueFrom

  with kubernetes_manifest.manifest,
  on main.tf line 22, in resource "kubernetes_manifest" "manifest":
  22: resource "kubernetes_manifest" "manifest" {

Invalid value: "": may not be specified when `value` is not empty

Error: spec.template.spec.containers[0].env[1].valueFrom

  with kubernetes_manifest.manifest,
  on main.tf line 22, in resource "kubernetes_manifest" "manifest":
  22: resource "kubernetes_manifest" "manifest" {

Invalid value: "": may not be specified when `value` is not empty

Important Factoids

  1. Wen you do one additional apply before changing the order everything goes fine.
  2. One workaround we found was to modify the sate manually by copying value of resources[0].instances[0].attributes.object to resources[0].instances[0].attributes.manifest after import (indices for the provided example). This causes significant amount of drift but only on terraform state side, whats more important, apply goes smoothly.

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants