terraform azurerm - не может уничтожить общедоступный IP

Новичок в terraform, так что я надеюсь, что это несложная проблема. Я создаю некоторые ресурсы в лазурном и развертываю простое приложение-флягу в AKS. Создание отлично работает с использованием плана terraform. Я вижу, что лазурь настроен правильно, и могу запустить приложение Flask.

Когда я пытаюсь запустить terraform destroy, я получаю сообщение об ошибке - «StatusCode = 400 ... Чтобы удалить общедоступный IP-адрес, отсоедините / отсоедините общедоступный IP-адрес от ресурса.

Main.tf

variable "subscription_id" {}
variable "client_id" {}
variable "client_secret" {}
variable "tenant_id" {}

provider "azurerm" {
    version         = "=1.28.0"
    tenant_id       = "${var.tenant_id}"
    subscription_id = "${var.subscription_id}"
}

resource "azurerm_resource_group" "aks" {
    name        = "${var.name_prefix}"
    location    = "${var.location}"
}

resource "azurerm_kubernetes_cluster" "k8s" {
    name                    = "${var.name_prefix}-aks"
    kubernetes_version      = "${var.kubernetes_version}"
    location                = "${azurerm_resource_group.aks.location}"
    resource_group_name     = "${azurerm_resource_group.aks.name}"
    dns_prefix              = "AKS-${var.dns_prefix}"

    agent_pool_profile {
        name                = "${var.node_pool_name}"
        count               = "${var.node_pool_size}"
        vm_size             = "${var.node_pool_vmsize}"
        os_type             = "${var.node_pool_os}"
        os_disk_size_gb     = 30
    }

    service_principal {
        client_id           = "${var.client_id}"
        client_secret       = "${var.client_secret}"
    }

    tags = {
        environment = "${var.env_tag}"
    }
}

provider "helm" {
  install_tiller = true

  kubernetes {
    host                   = "${azurerm_kubernetes_cluster.k8s.kube_config.0.host}"
    client_certificate     = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate)}"
    client_key             = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_key)}"
    cluster_ca_certificate = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate)}"
  }
}

# Create Static Public IP Address to be used by Nginx Ingress
resource "azurerm_public_ip" "nginx_ingress" {
  name                         = "nginx-ingress-public-ip"
  location                     = "${azurerm_kubernetes_cluster.k8s.location}"
  resource_group_name          = "${azurerm_kubernetes_cluster.k8s.node_resource_group}"
  allocation_method            = "Static"
  domain_name_label            = "${var.name_prefix}"
}

# Add Kubernetes Stable Helm charts repo
data "helm_repository" "stable" {
  name = "stable"
  url  = "https://kubernetes-charts.storage.googleapis.com"
}

# Install Nginx Ingress using Helm Chart
resource "helm_release" "nginx_ingress" {
  name       = "nginx-ingress"
  repository = "${data.helm_repository.stable.metadata.0.name}"
  chart      = "nginx-ingress"

  set {
    name  = "rbac.create"
    value = "false"
  }

  set {
    name  = "controller.service.externalTrafficPolicy"
    value = "Local"
  }

  set {
    name  = "controller.service.loadBalancerIP"
    value = "${azurerm_public_ip.nginx_ingress.ip_address}"
  }
}

Также в этом файле k8s.tf разворачиваю мои материалы о кубернетах.

provider "kubernetes" {
    host                    = "${azurerm_kubernetes_cluster.k8s.kube_config.0.host}"
    username                = "${azurerm_kubernetes_cluster.k8s.kube_config.0.username}"
    password                = "${azurerm_kubernetes_cluster.k8s.kube_config.0.password}"
    client_certificate      = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate)}"
    client_key              = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_key)}"
    cluster_ca_certificate  = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate)}"
}

resource "kubernetes_deployment" "flask-api-deployment" {
    metadata {
        name = "flask-api-deployment"
    }

    spec {
        replicas = 2

        selector {
            match_labels {
                component = "api"
            }
        }

        template {
            metadata {
                labels = {
                    component = "api"
                }
            }

            spec {
                container {
                    image = "xxx.azurecr.io/sampleflask:0.1.0"
                    name = "flask-api"
                    port {
                        container_port = 5000
                    }
                }
            }
        }
    }
}

resource "kubernetes_service" "api-cluster-ip-service" {
    metadata {
        name = "flask-api-cluster-ip-service"
    }

    spec {
        selector {
            component = "api"
        }

        port {
            port = 5000
            target_port = 5000
        }
    }
}

resource "kubernetes_ingress" "flask-ingress-service" {
    metadata {
        name = "flask-ingress-service"
    }

    spec {
        backend {
            service_name = "flask-api-cluster-ip-service"
            service_port = 5000
        }
    }
}

person Matthew The Terrible    schedule 11.07.2019    source источник
comment
в чем вообще смысл предоставления IP-адреса? он создаст это сам   -  person 4c74356b41    schedule 11.07.2019
comment
он не создает его сам по себе.   -  person Matthew The Terrible    schedule 11.07.2019
comment
это так, в этом весь смысл сервисов в кубернетах, они абстрагируют базовую инфраструктуру облачного провайдера   -  person 4c74356b41    schedule 11.07.2019
comment
nginx ingress имеет некоторые обязательные и специфичные для Azure файлы yaml, которые вы должны применить, которые затем предоставят общедоступный IP-адрес и некоторые другие вещи, необходимые для входного контроллера. Чтобы сделать это в terraform, я думаю, вам нужно использовать helm для установки nginx ingress, а также самостоятельно предоставить общедоступный IP-адрес.   -  person Matthew The Terrible    schedule 11.07.2019
comment
нет, чтобы у службы был внешний IP-адрес, все, что вам нужно сделать, это установить для него значение "type": LoadBalancer   -  person 4c74356b41    schedule 11.07.2019
comment
В Azure, если вы хотите использовать определяемый пользователем общедоступный тип loadBalancerIP, вам сначала необходимо создать ресурс общедоступного IP-адреса статического типа. Этот ресурс общедоступного IP-адреса должен находиться в той же группе ресурсов, что и другие автоматически созданные ресурсы кластера. - kubernetes.io/docs/concepts/services-networking   -  person Matthew The Terrible    schedule 11.07.2019
comment
нет, вам не нужно делать это ни у одного поставщика облачных услуг, прочтите статью, на которую вы указали: On cloud providers which support external load balancers, setting the type field to LoadBalancer provisions a load balancer for your Service. The actual creation of the load balancer happens asynchronously, and information about the provisioned balancer is published in the Service’s .status.loadBalancer field.   -  person 4c74356b41    schedule 11.07.2019


Ответы (1)


По вашему мнению, это проблема последовательности ресурсов. Когда вы создаете вход nginx с общедоступным IP-адресом, сначала должен быть создан общедоступный IP-адрес. Но когда вы удаляете общедоступный IP-адрес, он все еще используется входом nginx. Итак, это вызывает ошибку.

Решение состоит в том, что вы можете отсоединить общедоступный IP-адрес от ресурса, который его использует. Затем используйте уничтожить ресурс из Terraform. Вы можете ознакомиться с объяснением в проблеме < / а>.

person Charles Xu    schedule 11.07.2019
comment
я думаю, это имеет смысл. Но как мне отсоединиться перед запуском terraform destroy? Это что-то, что я должен делать за пределами терраформирования? - person Matthew The Terrible; 11.07.2019
comment
@MatthewTheTerrible Да, вы можете отключить общедоступный IP-адрес на портале Azure. Кроме того, если вы разделите ресурсы Azure и кубернеты в двух файлах терраформирования. Затем вы можете сначала создать ресурсы Azure и сначала уничтожить ресурсы Kubernetes. - person Charles Xu; 11.07.2019
comment
Я не могу сделать это через портал. Мне нужно сделать это с помощью одной команды terraform. Похоже, что с помощью этой ссылки вы можете явно установить свойство зависимости от, которое может помочь terraform знать, что что-то должно быть сначала уничтожено. - person Matthew The Terrible; 11.07.2019