-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Terraform Version, Provider Version and Kubernetes Version
Terraform version: any
Kubernetes provider version: 2.38.0
Kubernetes version: any
Affected Resource(s)
kubernetes_service_v1
Terraform Configuration Files
IPValidation breaks functionality of load_balancer_ip in spec, when using a for loop to parse yaml files and create dynamically loadbalancers.
My code breaks when some of the loadbalancer have a specific IP and some of them are empty string each.value.loadbalancer_ip==""
Cloud controllers generate automatically the loadbalancerIP if nothing or empty string ("") is given and in case "specific ip" is requested then it gets that IP if the controller supports that.
I get the following error which is invalid functionality of IP Validation...
**Error: expected spec.0.load_balancer_ip to contain a valid IP, got: "" **
00:03:15.953 │
00:03:15.953 │ with module.kubernetes_components.kubernetes_service_v1.nginx-ingress-controller-svc["ingress-nginx-controller"],
00:03:15.953 │ on module/kubernetes_components/main.tf line 470, in resource "kubernetes_service_v1" "nginx-ingress-controller-svc":
00:03:15.953 │ 470: load_balancer_ip = each.value.type == "LoadBalancer" && each.value.loadbalancer_ip != "" ? each.value.loadbalancer_ip : ""
00:03:15.953 │
A similar Issue was in the past with ClusterIP functionality and it was solved in following PR:
PR: #1273 (comment)
Example of my code:
kubernetes_service_v1 {
for_each = {
for lb in local.final_svcs : lb.name => lb
}
wait_for_load_balancer = false
spec {
metadata {
name = each.value.name
namespace = each.value.namespace
labels = {
"app.kubernetes.io/component" = "controller"
"app.kubernetes.io/instance" = "ingress-nginx"
"app.kubernetes.io/name" = "ingress-nginx"
}
}
external_traffic_policy = "Local"
health_check_node_port = 31952
load_balancer_ip = each.value.type == "LoadBalancer" && each.value.loadbalancer_ip != "" ? each.value.loadbalancer_ip : ""
dynamic "port" {
for_each = each.value.ports
content {
name = port.value["name"]
node_port = each.value.type == "LoadBalancer" ? port.value["node_port"] != null ? port.value["node_port"] : null : null
port = port.value["port"]
protocol = port.value["protocol"]
target_port = port.value["target_port"]
}
}
selector = try(each.value.selectors, [])
session_affinity = "None"
type = each.value.type
}
Example YAML Files that are parsed in loop:
name: ingress-nginx-controller
loadbalancer_ip: 1.2.3.4
cluster_ips: []
external_ips: []
type: LoadBalancer
is_enabled: true
namespace: kube-system
selectors:
app.kubernetes.io/name: ingress-nginx-2
ports:
- name: http
node_port: 32647
port: 80
protocol: TCP
target_port: http
- name: https
node_port: 31956
port: 443
protocol: TCP
target_port: https
name: ingress-nginx-controller
loadbalancer_ip: ""
cluster_ips: []
external_ips: []
type: LoadBalancer
is_enabled: true
namespace: kube-system
selectors:
app.kubernetes.io/name: ingress-nginx
ports:
- name: http
node_port: 32648
port: 80
protocol: TCP
target_port: http
- name: https
node_port: 31957
port: 443
protocol: TCP
target_port: https
Debug Output
Panic Output
Steps to Reproduce
Expected Behavior
What should have happened?
- Since load_balancer_ip is optional then empty string or None or null as value should omit checking if "isIPAddress" in validators.
Actual Behavior
What actually happened?
- Error: expected spec.0.load_balancer_ip to contain a valid IP, got:
Important Factoids
References
Similar to ClusterIP issue in the past:
#1273 (comment)
#1291
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