Terraform: укажите правила группы безопасности сети при создании кластера AKS с помощью azurerm_kubernetes_cluster

Я использую провайдер Terraform Azurerm версии 1.19 для создания кластера AKS. Я хотел бы указать правила группы безопасности сети при создании кластера, но не могу понять, как ссылаться на группу безопасности, которая создается, поскольку сгенерированная группа безопасности получает имя со случайными числами.

Что-то вроде:

АКС-agentpool-33577837-NSG

Есть ли способ сослаться на созданный NSG или, по крайней мере, вывод случайное число, используемое в имени?

Конфигурация для создания кластера:

resource "azurerm_resource_group" "k8s" {
  name     = "${var.resource_group_name}"
  location = "${var.location}"
}

resource "azurerm_kubernetes_cluster" "k8s" {
  name                = "${var.cluster_name}"
  location            = "${azurerm_resource_group.k8s.location}"
  resource_group_name = "${azurerm_resource_group.k8s.name}"
  dns_prefix          = "${var.dns_prefix}"
  kubernetes_version  = "${var.kubernetes_version}"

  linux_profile {
    admin_username = "azureuser"

    ssh_key {
      key_data = "${file("${var.ssh_public_key}")}"
    }
  }

  agent_pool_profile {
    name    = "default"
    count   = "${var.agent_count}"
    vm_size = "${var.vm_size}"
    os_type = "Linux"
  }

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

  tags {
    source      = "terraform"
    environment = "${var.environment}" 
  }
}

Это создает группу безопасности, в которую я хотел бы добавить дополнительные правила. Вот правило, которое я хотел бы добавить, чтобы проверить работоспособность контроллера nginx.

resource "azurerm_network_security_rule" "nginx_liveness_probe" {
  name                        = "nginx_liveness"
  priority                    = 100 
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = "${var.nginx_liveness_probe_port}"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
  resource_group_name         = "${azurerm_kubernetes_cluster.k8s.node_resource_group}"
  network_security_group_name = How do I reference the auto-generated nsg ?
  description = "Allow access to nginx liveness probe"
}

3 ответа

Решение, которое отвечает на ваш вопрос:

      data "azurerm_resources" "example" {
  resource_group_name = azurerm_kubernetes_cluster.example.node_resource_group

  type = "Microsoft.Network/networkSecurityGroups"
}

output name_nsg {
    value = data.azurerm_resources.example.resources.0.name
}

resource "azurerm_network_security_rule" "example" {
  name                        = "example"
  priority                    = 100
  direction                   = "Outbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = "*"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
  resource_group_name         = azurerm_kubernetes_cluster.example.node_resource_group
  network_security_group_name = data.azurerm_resources.example.resources.0.name
}

.. а потом таким же образом добавить все свои правила.

В общем, лучше и рекомендуется использовать автоматизированный способ реакции службы Azure Kubernetes на создание служб Kubernetes, а не использовать больше Terraform (хотя ниже Kubernetes yaml также можно использовать с провайдером Kubernetes Terraform ):

Группа безопасности сети фильтрует трафик для виртуальных машин, таких как узлы AKS. При создании служб, таких как LoadBalancer, платформа Azure автоматически настраивает все необходимые правила группы безопасности сети. Не настраивайте вручную правила группы безопасности сети для фильтрации трафика для модулей в кластере AKS. Определите все необходимые порты и перенаправление как часть манифестов службы Kubernetes, а платформа Azure создаст или обновит соответствующие правила. Вы также можете использовать сетевые политики, как описано в следующем разделе, для автоматического применения правил фильтрации трафика к модулям.

Это должно быть возможно в рамках текущей настройки путем простого создания службы Kubernetes для тех портов, которые вы хотите раскрыть.

Например, когда я развертываю контроллер входящего трафика, создание службы Kubernetes запускает создание IP-адреса/балансировщика нагрузки с его NSG:

      apiVersion: v1
kind: Service
metadata:
  name: ingress-ingress-nginx-controller
  namespace: ingress
spec:
  loadBalancerSourceRanges:
  - 8.8.8.8/32
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: http
  - name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress
    app.kubernetes.io/name: ingress-nginx
  type: LoadBalancer

Создав службу Kubernetes (типа LoadBalancer), которая сопоставляется с нужным портом модуля и с указанием loadBalancerSourceRanges, можно указать аналогичную настройку для вашего пользовательского места назначения.

      apiVersion: v1
kind: Service
metadata:
  name: mycustomservice
  namespace: myownnamespace
spec:
  loadBalancerSourceRanges:
  - 8.8.8.8/32 # your source IPs
  - 9.9.9.9/32
  ports:
  - name: myaccessport
    port: 777
    protocol: TCP
    targetPort: mydestinationport
  selector:
    app.kubernetes.io/name: myapp
  type: LoadBalancer

См. также проблему в GitHub поставщика azurerm.

Немного поздно здесь, но только что наткнулся на эту проблему. Итак, для тех, кто все еще ищет решение, вот что я в итоге сделал, чтобы получить имя AKS NSG:

Добавьте это в файл *.tf, обеспечивающий ваш AKS:

resource "azurerm_network_security_rule" "http" {
  name                        = "YOUR_NAME"
  priority                    = 102
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "80"
  destination_port_range      = "*"
  source_address_prefixes     = "${var.ips}"
  destination_address_prefix  = "${azurerm_public_ip.ingress.ip_address}"
  resource_group_name         = "${azurerm_kubernetes_cluster.test.node_resource_group}"
  network_security_group_name = "${data.external.aks_nsg_name.result.output}"

  depends_on = ["azurerm_resource_group.test"]
}

# get the NSG name
data "external" "aks_nsg_name" {
  program = [
    "bash",
    "${path.root}/scripts/aks_nsg_name.sh"
  ]

  depends_on = [azurerm_resource_group.test]
}

Создайте aks_nsg_name.sh в своем проекте и добавьте следующее:

#!/bin/bash 
OUTPUT=$(az network nsg list --query [].name -o tsv | grep aks-agentpool | head -n 1)
jq -n --arg output "$OUTPUT" '{"output":$output}'

Ваш AKC добавлен в azurerm_resource_groupЯ полагаю, что вы предоставили Terraform. Если это так, вы можете добавить кастом azurerm_network_security_group с любым количеством azurerm_network_security_rule для этой группы ресурсов, как подробно описано здесь.

Пример:

resource "azurerm_resource_group" "test" {
  name     = "acceptanceTestResourceGroup1"
  location = "West US"
}

resource "azurerm_network_security_group" "test" {
  name                = "acceptanceTestSecurityGroup1"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
}

resource "azurerm_network_security_rule" "test" {
  name                        = "test123"
  priority                    = 100
  direction                   = "Outbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = "*"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
  resource_group_name         = "${azurerm_resource_group.test.name}"
  network_security_group_name = "${azurerm_network_security_group.test.name}"
}

К сожалению, name Параметр является обязательным для источников данных группы безопасности сети, и подстановочные знаки, похоже, не поддерживаются, иначе это также было бы возможным вариантом.

Другие вопросы по тегам