terraform-provider-kubernetes icon indicating copy to clipboard operation
terraform-provider-kubernetes copied to clipboard

cannot apply changes after importing istio VirtualService resource with kubernetes_manifest

Open crivetechie opened this issue 5 months ago • 0 comments

Terraform Version, Provider Version and Kubernetes Version

Terraform version: 1.12.2
Kubernetes provider version: v2.37.1
Kubernetes version: v1.32.4-gke.1353003

Affected Resource(s)

  • kubernetes_manifest

Terraform Configuration Files

Init state

This configuration is used to deploy the resource that will cause the import to fail, used for demo purposes

locals {
  virtual_service_spec = {
    hosts = ["demo.example.com"]
    http = [
      {
        match = [
          {
            uri = {
              prefix = "/private"
            }
          }
        ]
        route = [
          {
            destination = {
              host = "demo-api",
              port = {
                number = 8080
              }
            }
          }
        ]
        timeout = "30s"
      },
      {
        match = [
          {
            uri = {
              exact = "/public"
            }
          }
        ]
        route = [
          {
            destination = {
              host = "demo-api",
              port = {
                number = 8081
              }
            }
          }
        ]

        timeout = "30s"
      }
    ]
    gateways = ["demo"]
  }
}

resource "kubernetes_manifest" "virtual_service" {

  field_manager {
    force_conflicts = true
    name            = "demo2"
  }

  manifest = {
    apiVersion = "networking.istio.io/v1beta1"
    kind       = "VirtualService"
    metadata = {
      name      = "demo-vs"
      namespace = "demo"
      labels = {
        "app"   = "demo-vs"
      }
    }
    spec = local.virtual_service_spec
  }
}

Resource import

This configuration triggers the failure scenario

locals {
  virtual_service_spec = {
    hosts = ["demo.example.com"]
    http = [
      {
        match = [
          {
            uri = {
              prefix = "/private"
            }
          }
        ]
        route = [
          {
            destination = {
              host = "demo-api",
              port = {
                number = 8080
              }
            }
          }
        ]
        timeout = "30s"
      },
      {
        match = [
          {
            uri = {
              prefix = "/public"
            }
          }
        ]
        route = [
          {
            destination = {
              host = "demo-api",
              port = {
                number = 8081
              }
            }
          }
        ]

        timeout = "30s"
      }
    ]
    gateways = ["demo"]
  }
}

resource "kubernetes_manifest" "virtual_service" {

  field_manager {
    force_conflicts = true
    name            = "demo2"
  }

  manifest = {
    apiVersion = "networking.istio.io/v1beta1"
    kind       = "VirtualService"
    metadata = {
      name      = "demo-vs"
      namespace = "demo"
      labels = {
        "app"   = "demo-vs"
      }
    }
    spec = local.virtual_service_spec
  }
}

import {
  to = kubernetes_manifest.virtual_service
  id = "apiVersion=networking.istio.io/v1beta1,kind=VirtualService,namespace=demo,name=demo-vs"
}

Steps to Reproduce

  1. Run terraform apply for the configuration named Init state this will create a VirtualService with 2 http rules, one using url prefix and the other exact match
  2. Run terraform apply for the configuration named Resource import on top of the import of the resource kubernetes_manifest.virtual_service this configuration has a difference in the http rules: they both use prefix match

Expected Behavior

On apply the resource is imported and the http rules are updated

Actual Behavior

Following error occurs when modifying the k8s resource:

kubernetes_manifest.virtual_service: Modifying...
╷
│ Error: API response status: Failure
│ 
│   with kubernetes_manifest.virtual_service,
│   on main.tf line 51, in resource "kubernetes_manifest" "virtual_service":
│   51: resource "kubernetes_manifest" "virtual_service" {
│ 
│ VirtualService.networking.istio.io "demo-vs" is invalid: <nil>: Invalid value: "": "spec.http[1].match[0].uri" must
│ validate one and only one schema (oneOf). Found 2 valid alternatives
╵
╷
│ Error: Kubernetes API Error: Invalid VirtualService.networking.istio.io [demo-vs]
│ 
│   with kubernetes_manifest.virtual_service,
│   on main.tf line 51, in resource "kubernetes_manifest" "virtual_service":
│   51: resource "kubernetes_manifest" "virtual_service" {
│ 
╵
╷
│ Error: <nil>
│ 
│   with kubernetes_manifest.virtual_service,
│   on main.tf line 51, in resource "kubernetes_manifest" "virtual_service":
│   51: resource "kubernetes_manifest" "virtual_service" {
│ 
│ Invalid value: "": "spec.http[1].match[0].uri" must validate one and only one schema (oneOf). Found 2 valid
│ alternatives

Important Factoids

The http rules defined in the second configuration are valid, they are applied to both new resources and to resources that have been managed from Terraform from the start.

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

crivetechie avatar Jun 19 '25 19:06 crivetechie