From a0daa0ea7778cef7c65f3fc8c241112deba27a69 Mon Sep 17 00:00:00 2001 From: cfernhout Date: Tue, 5 Nov 2024 14:14:38 +0100 Subject: [PATCH] feat: Add capability to connect to k8s API over public internet through whitelisting and jumpbox --- main.tf | 23 ++++++++------- modules/aks/main.tf | 13 ++++++++- modules/aks/variables.tf | 12 +++++++- modules/networking/bastion.tf | 4 +++ modules/networking/outputs.tf | 4 +++ modules/networking/public_ip.tf | 16 +++++++++++ modules/networking/sg.tf | 50 ++++++++++++++++++++++++++++++++- modules/networking/variables.tf | 11 ++++++++ outputs.tf | 5 ++++ variables.tf | 11 ++++++++ 10 files changed, 136 insertions(+), 13 deletions(-) diff --git a/main.tf b/main.tf index 2ef4e87..fd95dd0 100644 --- a/main.tf +++ b/main.tf @@ -118,6 +118,7 @@ module "networking" { private_endpoint_adls_subnet_cidrs = local.private_endpoint_adls_subnet_cidrs jumpbox_custom_data = var.jumpbox_custom_data lb_is_public = var.lb_is_public + k8s_public_access_cidrs = var.k8s_public_access_cidrs } module "identity" { @@ -220,14 +221,16 @@ module "aks" { identity = module.identity.identity etcd_key_vault_key_id = module.key_vault.etcd_key_id - max_pods = var.max_pods - node_pool_node_count = var.node_pool_node_count - min_node_count = var.min_node_count - max_node_count = var.max_node_count - node_pool_vm_size = var.node_pool_vm_size - node_pool_name = var.node_pool_name - sku_tier = var.aks_sku_tier - service_cidr = var.aks_service_cidr - dns_service_ip = var.aks_dns_service_ip - custom_node_pools = var.custom_node_pools + max_pods = var.max_pods + node_pool_node_count = var.node_pool_node_count + min_node_count = var.min_node_count + max_node_count = var.max_node_count + node_pool_vm_size = var.node_pool_vm_size + node_pool_name = var.node_pool_name + sku_tier = var.aks_sku_tier + service_cidr = var.aks_service_cidr + dns_service_ip = var.aks_dns_service_ip + custom_node_pools = var.custom_node_pools + private_cluster_enabled = var.private_cluster_enabled + k8s_public_access_cidrs = var.k8s_public_access_cidrs } diff --git a/modules/aks/main.tf b/modules/aks/main.tf index 25b462d..b973d3a 100644 --- a/modules/aks/main.tf +++ b/modules/aks/main.tf @@ -5,7 +5,14 @@ resource "azurerm_kubernetes_cluster" "default" { dns_prefix = "${var.deployment_name}-k8s" sku_tier = var.sku_tier - private_cluster_enabled = true + dynamic api_server_access_profile { + for_each = var.private_cluster_enabled ? [] : [1] + content { + authorized_ip_ranges = var.k8s_public_access_cidrs + } + } + + private_cluster_enabled = var.private_cluster_enabled private_cluster_public_fqdn_enabled = true ingress_application_gateway { @@ -88,6 +95,10 @@ resource "azurerm_kubernetes_cluster_node_pool" "custom_node_pools" { node_labels = each.value.labels tags = var.tags + + lifecycle { + ignore_changes = [ node_count ] + } } locals { diff --git a/modules/aks/variables.tf b/modules/aks/variables.tf index e010e2d..9927a14 100644 --- a/modules/aks/variables.tf +++ b/modules/aks/variables.tf @@ -119,4 +119,14 @@ variable "custom_node_pools" { })) description = "Dynamic extra node pools" default = [] -} \ No newline at end of file +} + +variable "private_cluster_enabled" { + type = bool + description = "Flag to enable private cluster" +} + +variable "k8s_public_access_cidrs" { + type = list(string) + description = "List of CIDRs that are allowed to connect to the EKS control plane" +} diff --git a/modules/networking/bastion.tf b/modules/networking/bastion.tf index 5491129..bc001c5 100644 --- a/modules/networking/bastion.tf +++ b/modules/networking/bastion.tf @@ -42,9 +42,13 @@ resource "azurerm_network_interface" "vm_nic" { ip_configuration { name = "internal" subnet_id = azurerm_subnet.vm_bastion_subnet.id + public_ip_address_id = azurerm_public_ip.jumpbox[0].id private_ip_address_allocation = "Dynamic" + primary = true } + ip_forwarding_enabled = "true" + tags = var.tags } diff --git a/modules/networking/outputs.tf b/modules/networking/outputs.tf index 1a4b09c..e1a903c 100644 --- a/modules/networking/outputs.tf +++ b/modules/networking/outputs.tf @@ -38,6 +38,10 @@ output "public_ip" { value = var.lb_is_public ? azurerm_public_ip.default[0].id : null } +output "public_ip_jumpbox" { + value = azurerm_public_ip.jumpbox[0].ip_address +} + output "vnet_name" { value = azurerm_virtual_network.vnet.name } diff --git a/modules/networking/public_ip.tf b/modules/networking/public_ip.tf index f8c0a4b..43df6ed 100644 --- a/modules/networking/public_ip.tf +++ b/modules/networking/public_ip.tf @@ -8,5 +8,21 @@ resource "azurerm_public_ip" "default" { allocation_method = "Static" domain_name_label = var.deployment_name + tags = var.tags +} + +resource "azurerm_public_ip" "jumpbox" { + count = var.private_cluster_enabled ? 1 : 0 + + allocation_method = "Static" + ddos_protection_mode = "VirtualNetworkInherited" + idle_timeout_in_minutes = "4" + ip_version = "IPv4" + name = "${var.deployment_name}-ip-jumpbox" + resource_group_name = var.resource_group_name + location = var.location + sku = "Standard" + sku_tier = "Regional" + tags = var.tags } \ No newline at end of file diff --git a/modules/networking/sg.tf b/modules/networking/sg.tf index 7496070..f455b8b 100644 --- a/modules/networking/sg.tf +++ b/modules/networking/sg.tf @@ -4,4 +4,52 @@ resource "azurerm_network_security_group" "nsg_vnet" { resource_group_name = var.resource_group_name tags = var.tags -} \ No newline at end of file +} + +resource "azurerm_network_security_group" "jumpbox" { + name = "${var.deployment_name}-jumpbox-sg" + location = var.location + resource_group_name = var.resource_group_name +} + +resource "azurerm_network_security_rule" "jumpbox_8443" { + access = "Allow" + destination_address_prefix = "*" + destination_port_range = "8443" + direction = "Inbound" + name = "AllowCidrBlockCustomInbound" + network_security_group_name = "${azurerm_network_security_group.jumpbox.name}" + priority = "120" + protocol = "Tcp" + resource_group_name = var.resource_group_name + source_address_prefixes = var.k8s_public_access_cidrs + source_port_range = "8443" +} + +resource "azurerm_network_security_rule" "jumpbox_443" { + access = "Allow" + destination_address_prefix = "*" + destination_port_range = "443" + direction = "Inbound" + name = "AllowCidrBlockHTTPSInbound" + network_security_group_name = "${azurerm_network_security_group.jumpbox.name}" + priority = "100" + protocol = "Tcp" + resource_group_name = var.resource_group_name + source_address_prefixes = var.k8s_public_access_cidrs + source_port_range = "443" +} + +resource "azurerm_network_security_rule" "jumpbox_22" { + access = "Allow" + destination_address_prefix = "*" + destination_port_range = "22" + direction = "Inbound" + name = "AllowCidrBlockSSHInbound" + network_security_group_name = "${azurerm_network_security_group.jumpbox.name}" + priority = "110" + protocol = "Tcp" + resource_group_name = var.resource_group_name + source_address_prefixes = var.k8s_public_access_cidrs + source_port_range = "22" +} diff --git a/modules/networking/variables.tf b/modules/networking/variables.tf index 4ebe77b..3c9b1ca 100644 --- a/modules/networking/variables.tf +++ b/modules/networking/variables.tf @@ -97,3 +97,14 @@ variable "lb_is_public" { description = "Flag that determines if LB is public" type = bool } + +variable "k8s_public_access_cidrs" { + type = list(string) + description = "List of CIDRs that are allowed to connect to the EKS control plane" +} + +variable "private_cluster_enabled" { + type = bool + description = "Flag to enable private cluster" + default = true +} diff --git a/outputs.tf b/outputs.tf index 73cf828..634ad4f 100644 --- a/outputs.tf +++ b/outputs.tf @@ -48,6 +48,11 @@ output "vnet_name" { description = "The name of the virtual network" } +output "public_ip_jumpbox" { + description = "The private IP address of the jumpbox" + value = module.networking.public_ip_jumpbox +} + # Domain Information output "domain_name" { description = "The domain name configured for the deployment" diff --git a/variables.tf b/variables.tf index 35d0d04..3b71f8e 100644 --- a/variables.tf +++ b/variables.tf @@ -348,6 +348,17 @@ variable "custom_node_pools" { default = [] } +variable "private_cluster_enabled" { + type = bool + description = "Flag to enable private cluster" + default = true +} + +variable "k8s_public_access_cidrs" { + type = list(string) + description = "List of CIDRs that are allowed to connect to the EKS control plane" +} + # ┏━╸┏━╸┏━┓╺┳╸ # ┃ ┣╸ ┣┳┛ ┃ # ┗━╸┗━╸╹┗╸ ╹