Using an azure public IP, when removing the IP from a kubernetes LoadBalancer service and deleting it, Terraform tries to delete the IP first. This fails because in Azure the IP cannot be deleted if it is still attached to the LoadBalancer service.
I can't think of any workaround for this.
Terraform v0.12.15
+ provider.azuread v0.6.0
+ provider.azurerm v1.35.0
+ provider.kubernetes v1.10.0
+ provider.local v1.4.0
variable "aks_configure_static_ip" {
default = false
}
data "azurerm_kubernetes_cluster" "myfm-cluster" {
name = "chaaksmyfm01"
resource_group_name = data.azurerm_resource_group.project-rg.name
}
data "azurerm_resource_group" "aks-node-rg" {
name = data.azurerm_kubernetes_cluster.myfm-cluster.node_resource_group
}
resource "azurerm_public_ip" "aks-public-ip" {
count = var.aks_configure_static_ip ? 1 : 0
#count = 0
name = "chaakspubip"
resource_group_name = data.azurerm_resource_group.aks-node-rg.name
location = data.azurerm_resource_group.aks-node-rg.location
allocation_method = "Static"
}
provider "kubernetes" {
host = data.azurerm_kubernetes_cluster.myfm-cluster.kube_config.0.host
username = data.azurerm_kubernetes_cluster.myfm-cluster.kube_config.0.username
password = data.azurerm_kubernetes_cluster.myfm-cluster.kube_config.0.password
client_certificate = base64decode(data.azurerm_kubernetes_cluster.myfm-cluster.kube_config.0.client_certificate)
client_key = base64decode(data.azurerm_kubernetes_cluster.myfm-cluster.kube_config.0.client_key)
cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.myfm-cluster.kube_config.0.cluster_ca_certificate)
}
resource "kubernetes_service" "nginx_ingress_service" {
metadata {
name = "ingress-nginx"
namespace = kubernetes_namespace.ingress_nginx.metadata.0.name
labels = {
"app.kubernetes.io/name": "ingress-nginx"
"app.kubernetes.io/part-of": "ingress-nginx"
}
}
spec {
type = "LoadBalancer"
external_traffic_policy = "Local"
selector = {
"app.kubernetes.io/name": "ingress-nginx"
"app.kubernetes.io/part-of": "ingress-nginx"
}
port {
name = "http"
port = 80
target_port = "http"
}
port {
name = "https"
port = 443
target_port = "https"
}
load_balancer_ip = length(azurerm_public_ip.aks-public-ip.*) == 1 ? azurerm_public_ip.aks-public-ip[0].ip_address : null
}
}
https://gist.github.com/erlacherl-city/d577efcc6736eb2533e3b3d43455c561
Terraform should redeploy the service first without the public IP, and then delete the IP.
Terraform tries to destroy the public IP first and fails.
aks_configure_static_ip variable to trueterraform apply creates the public IP and attaches it to the Kubernetes LoadBalancer serviceaks_configure_static_ip variable to trueterraform apply tries to delete the public IP and fails because it is still attachedSo I've had a pretty bad time actually getting this public IP destroyed. I'll have to do some more testing but it seems AKS (at least with basic networking as I am running right now) doesn't really have all its dependencies properly set up and doesn't do the proper clean-up itself.
You have to first remove the services with type load balancer from the cluster using kubectl. This will remove the ip from the load balancer, and then terraform can do it's thing.
Yes we have this same issue. As above, you have to target destroy the NGINX Ingress first which will release control over the public IP.
Just ran into this today. FWIW, unlike @erlacherl-city we are using Azure CNI rather than basic networking.
We are struggling with this gem too. We are not using kubernetes terraform provider to manage our cluster, but are using terraform to manage the infrastructure. I would expect the kubernetes provider here to make the changes suggested, removing the ingress controller before deleting the IP. In our case, it becomes a process issue, as we must manually run kubectl scripts to remove the ingress controller before removing the public IP. Issues like this have caused us to steer away from using the kubernetes and helm providers with terraform.
You don't need to remove the ingress controller, only services of type LoadBalancer (or, to simplify, all services). It is a one liner.
That said, I agree that the AKS provider should be able to do this by itself. It is a really simple thing to do and they already have management pods running, anyway, so add this functionality to them.
@jluk I'd agree with @giggio here this probably makes sense for the AKS ARM RP to do, since the Kubernetes control plane isn't necessarily available (network rules/disabled) - is there an upstream task tracking this?
I just opened an issue at the AKS repo: https://github.com/Azure/AKS/issues/1405
Since this is a bug in AKS (rather than something we can fix directly in Terraform) I'm going to close this in favour of the upstream issue: https://github.com/Azure/AKS/issues/1405
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!