Skip to content

Commit

Permalink
Merge pull request #11 from Justin-DynamicD/add-win-support
Browse files Browse the repository at this point in the history
AGW major update
  • Loading branch information
Justin-DynamicD authored Sep 26, 2023
2 parents ebfdf22 + d05a9e5 commit 0930aec
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 46 deletions.
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ In this example, the integrated WAF is disabled, but OMS logging is enabled and
app_gateway = {
enabled = false
name = ""
public_ip_id = ""
private_ip = false
public_ip = true
sku_capacity = "2"
sku_name = "WAF_v2"
sku_tier = "WAF_v2"
Expand All @@ -63,13 +64,19 @@ app_gateway = {

This block defines the app gateway integration. If `enabled` = true, the `subnet_id` becomes a required field, as AGW requires it's own dedicated subnet to provision into.

The module actually specifically defines the AGW and components as a seperate resource, so that if AKS is ever destroyed and rebuilt, provisioned public IPs remain until a value that forces similar action on the AGW occurs.
The module actually specifically defines the AGW and components as a seperate resource, so that if AKS is ever destroyed and rebuilt, provisioned public IPs remain until a value that forces similar action on the AGW occurs. Some parameter combinations are specific to certain versions of AGW (v1 vs v2). [Please see here for more information](# read more here: https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-components#static-versus-dynamic-public-ip-address)

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| enabled | bool | no | false | enables creation of AGW |
| name | string | no | - | if specified, overrides the auto-generated name with this string |
| private_ip | bool | no | false | enables creation of a private IP listener |
| private_ip_address | string | no | "" | if specified, sets the private IP address |
| private_priority | string | no | 20 | if specified, set the routing rule priority |
| private_ip_subnet_id | string | no | - | if specified, attempts to create the listener in the specified subnet_id |
| public_ip | bool | no | true | enables creation of a private IP listener |
| public_ip_id | string | no | - | if specified, instead of creating a public IP resource, will leverage the existing defined IP |
| public_priority | string | no | 10 | if specified, set the routing rule priority |
| sku_capacity | string | no | "2" | number of systems to deploy |
| sku_name | string | no | WAF_v2 | set subscription information |
| sku_tier | string | no | WAF_v2 | set subscription information |
Expand Down Expand Up @@ -133,6 +140,7 @@ node_default_pool = {
| only_critical_addons_enabled | bool | no | true | sets the node pool as type "system" restricting user workloads |
| os_disk_size_gb | number | no | 70 | size of node disks in GB |
| os_disk_type | string | no | "Ephemeral" | type of disk |
| os_sku | string | no | null | Specifies the OS SKU used by the agent pool. Possible values include: `AzureLinux`, `Ubuntu`, `Windows2019`, `Windows2022` |
| vm_size | string | no | "Standard_D2ds_v5" | set the node type |

### node_user_pool
Expand All @@ -153,6 +161,7 @@ node_user_pool = {
node_count = 2
os_disk_size_gb = 120
os_disk_type = "Ephemeral"
os_type = "Linux"
priority = "Regular"
spot_max_price = -1
vm_size = "Standard_D4ds_v5"
Expand All @@ -173,6 +182,8 @@ node_user_pool = {
| node_taints | list | no | [][^1] | add taints to the nodes |
| os_disk_size_gb | number | no | 120 | size of node disks in GB |
| os_disk_type | string | no | "Ephemeral" | type of disk |
| os_sku | string | no | null | Specifies the OS SKU used by the agent pool. Possible values include: `AzureLinux`, `Ubuntu`, `Windows2019`, `Windows2022` |
| os_type | string | no | "Linux" | the type of OS to run. As of this writing, supported types are `Windows` `Linux` |
| priority | string | no | "Regular" | the type of nodes |
| spot_max_price | number | no | -1 | used with spot instances, set a price limit on server cost, -1 means no limit |
| vm_size | string | no | "Standard_D4ds_v5" | set the node type |
Expand Down
75 changes: 58 additions & 17 deletions agw.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Public Ip
resource "azurerm_public_ip" "main" {
count = (local.app_gateway.enabled && local.app_gateway.public_ip_id == "") ? 1 : 0
count = (local.app_gateway.enabled && local.app_gateway.public_ip && local.app_gateway.public_ip_id == "") ? 1 : 0
name = local.names.agw
resource_group_name = local.resource_group_name
location = local.location
allocation_method = "Static"
sku = "Standard"
zones = local.zones != [] ? local.zones : null
tags = var.tags
lifecycle {
create_before_destroy = true
}
}

resource "azurerm_application_gateway" "main" {
Expand Down Expand Up @@ -47,9 +50,21 @@ resource "azurerm_application_gateway" "main" {
name = "defaulthttp"
port = 80
}
frontend_ip_configuration {
name = "appGatewayFrontendIP"
public_ip_address_id = local.app_gateway.public_ip_id == "" ? azurerm_public_ip.main[0].id : local.app_gateway.public_ip_id
dynamic "frontend_ip_configuration" {
for_each = local.app_gateway.public_ip ? ["public_ip_configuration"] : []
content {
name = "appGatewayFrontendPublicIP"
public_ip_address_id = local.app_gateway.public_ip_id == "" ? azurerm_public_ip.main[0].id : local.app_gateway.public_ip_id
}
}
dynamic "frontend_ip_configuration" {
for_each = local.app_gateway.private_ip ? ["private_ip_configuration"] : []
content {
name = "appGatewayFrontendPrivateIP"
private_ip_address_allocation = local.private_ip_address_allocation
private_ip_address = local.app_gateway.private_ip_address
subnet_id = coalesce(local.app_gateway.private_ip_subnet_id, local.app_gateway.subnet_id)
}
}
backend_address_pool {
name = "defaultaddresspool"
Expand All @@ -61,22 +76,48 @@ resource "azurerm_application_gateway" "main" {
protocol = "Http"
request_timeout = 30
}
http_listener {
name = "defaultlistener"
frontend_ip_configuration_name = "appGatewayFrontendIP"
frontend_port_name = "defaulthttp"
protocol = "Http"
dynamic "http_listener" {
for_each = local.app_gateway.public_ip ? ["public_listener"] : []
content {
name = "publiclistener"
frontend_ip_configuration_name = "appGatewayFrontendPublicIP"
frontend_port_name = "defaulthttp"
protocol = "Http"
}
}
request_routing_rule {
name = "default"
rule_type = "Basic"
http_listener_name = "defaultlistener"
backend_address_pool_name = "defaultaddresspool"
backend_http_settings_name = "defaulthttpsetting"
priority = local.priority != -1 ? local.priority : null
dynamic "http_listener" {
for_each = local.app_gateway.private_ip ? ["private_listener"] : []
content {
name = "privatelistener"
frontend_ip_configuration_name = "appGatewayFrontendPrivateIP"
frontend_port_name = "defaulthttp"
protocol = "Http"
}
}
dynamic "request_routing_rule" {
for_each = local.app_gateway.public_ip ? ["public_rr"] : []
content {
name = "public"
rule_type = "Basic"
http_listener_name = "publiclistener"
backend_address_pool_name = "defaultaddresspool"
backend_http_settings_name = "defaulthttpsetting"
priority = local.public_priority != -1 ? local.public_priority : null
}
}
dynamic "request_routing_rule" {
for_each = local.app_gateway.private_ip ? ["private_rr"] : []
content {
name = "private"
rule_type = "Basic"
http_listener_name = "privatelistener"
backend_address_pool_name = "defaultaddresspool"
backend_http_settings_name = "defaulthttpsetting"
priority = local.private_priority != -1 ? local.private_priority : null
}
}
dynamic "waf_configuration" {
for_each = length(regexall("^WAF", var.app_gateway.sku_tier)) > 0 ? ["waf_configuration"] : []
for_each = local.is_v2 ? ["waf_configuration"] : []
content {
enabled = local.waf_configuration.enabled
firewall_mode = local.waf_configuration.firewall_mode
Expand Down
3 changes: 3 additions & 0 deletions aks.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ resource "azurerm_kubernetes_cluster" "main" {
only_critical_addons_enabled = local.node_default_pool.only_critical_addons_enabled
os_disk_size_gb = local.node_default_pool.os_disk_size_gb
os_disk_type = local.node_default_pool.os_disk_type
os_sku = local.node_default_pool.os_sku
tags = local.tags
vm_size = local.node_default_pool.vm_size
vnet_subnet_id = local.subnet_id
Expand Down Expand Up @@ -74,6 +75,8 @@ resource "azurerm_kubernetes_cluster_node_pool" "user" {
node_taints = local.node_user_pool_merged.node_taints
os_disk_size_gb = local.node_user_pool.os_disk_size_gb
os_disk_type = local.node_user_pool.os_disk_type
os_sku = local.node_user_pool.os_sku
os_type = local.node_user_pool.os_type
priority = local.node_user_pool.priority
eviction_policy = local.node_user_pool.priority == "Spot" ? local.node_user_pool.eviction_policy : null
spot_max_price = local.node_user_pool.priority == "Spot" ? local.node_user_pool.spot_max_price : null
Expand Down
38 changes: 23 additions & 15 deletions diagnostics.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,12 @@ resource "azurerm_monitor_diagnostic_setting" "aks" {
for_each = local.oms.aks_logs
content {
category = enabled_log.key
retention_policy {
enabled = enabled_log.value
days = local.oms.retention_days
}
}
}

metric {
category = "AllMetrics"
enabled = local.oms.aks_metrics
retention_policy {
enabled = local.oms.aks_metrics
days = local.oms.retention_days
}
}
}

Expand All @@ -39,19 +31,35 @@ resource "azurerm_monitor_diagnostic_setting" "agw" {
for_each = local.oms.agw_logs
content {
category = enabled_log.key
retention_policy {
enabled = enabled_log.value
days = local.oms.retention_days
}
}
}

metric {
category = "AllMetrics"
enabled = local.oms.agw_metrics
retention_policy {
enabled = local.oms.agw_metrics
days = local.oms.retention_days
}
}

resource "random_string" "policySuffix" {
length = 8
special = false
upper = false
}

resource "azurerm_storage_management_policy" "main" {
count = local.oms.enabled == true ? 1 : 0
storage_account_id = local.oms.storage_account_id

rule {
name = "aks_basseline-${random_string.policySuffix.result}"
enabled = true
filters {
blob_types = ["appendBlob"]
}
actions {
base_blob {
delete_after_days_since_modification_greater_than = local.oms.retention_days
}
}
}
}
14 changes: 11 additions & 3 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
######

locals {
# detect if sku is of type "v2". This impacts supported ip address combinations
# read more here: https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-components#static-versus-dynamic-public-ip-address
is_v2 = length(regexall("v2$", var.app_gateway.sku_tier)) > 0 ? true : false

# ensure agw priority is set if sku is of type "v2"
# if nothing is provided, we will set to 1 for v2, or -1 to omit
detect_priority = length(regexall("v2$", var.app_gateway.sku_tier)) > 0 ? 10 : null
priority = coalesce(var.app_gateway.priority, local.detect_priority, -1)
# if nothing is provided, we will set to 10/20 for v2, or -1 to omit
default_priority = local.is_v2 ? 10 : null
public_priority = coalesce(var.app_gateway.public_priority, local.default_priority, -1)
private_priority = coalesce(var.app_gateway.private_priority, local.default_priority + 10, -1)

# only v1 WAF supports dynamic address allocation, set that here
private_ip_address_allocation = local.is_v2 || local.app_gateway.private_ip_address != "" ? "Static" : "Dynamic"

# generate the resource names for everything based on the values offered
names = {
Expand Down
2 changes: 2 additions & 0 deletions test/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ module "aks" {
app_gateway = {
enabled = true
subnet_id = module.myvnet.vnet_subnets["agw"].id
public_ip = true
private_ip = false
}
node_default_pool = {
min_count = 1
Expand Down
40 changes: 32 additions & 8 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,38 @@

variable "app_gateway" {
type = object({
enabled = optional(bool, false)
name = optional(string)
public_ip_id = optional(string, "")
priority = optional(number)
sku_capacity = optional(string, "2")
sku_name = optional(string, "WAF_v2")
sku_tier = optional(string, "WAF_v2")
subnet_id = optional(string, "")
enabled = optional(bool, false)
name = optional(string)
private_ip = optional(bool, false)
private_ip_address = optional(string, "")
private_priority = optional(number)
private_ip_subnet_id = optional(string)
public_ip = optional(bool, true)
public_ip_id = optional(string, "")
public_priority = optional(number)
sku_capacity = optional(string, "2")
sku_name = optional(string, "WAF_v2")
sku_tier = optional(string, "WAF_v2")
subnet_id = optional(string)
})
description = "map of all agw variables"
default = {}
validation {
condition = length(regexall("v2$", var.app_gateway.sku_tier)) == 0 || (length(regexall("v2$", var.app_gateway.sku_tier)) > 0 && var.app_gateway.public_ip == true)
error_message = "If sku_tier is v2, then public_ip must be set to true."
}
validation {
condition = var.app_gateway.private_ip == false || (length(regexall("v2$", var.app_gateway.sku_tier)) > 0 && var.app_gateway.private_ip_address != "")
error_message = "If sku_tier is v2, then private_ip_address must be set when private_ip is set to true"
}
validation {
condition = length(regexall("v2$", var.app_gateway.sku_tier)) > 0 || (length(regexall("v2$", var.app_gateway.sku_tier)) == 0 && var.app_gateway.public_ip_id != "")
error_message = "If sku_tier is v1, then public_ip_id must be empty"
}
validation {
condition = var.app_gateway.enabled == false || (var.app_gateway.enabled && var.app_gateway.subnet_id != null)
error_message = "subnet_id is required when enabled is true"
}
}

variable "waf_configuration" {
Expand Down Expand Up @@ -43,6 +64,7 @@ variable "node_default_pool" {
only_critical_addons_enabled = optional(bool, true)
os_disk_size_gb = optional(number, 70)
os_disk_type = optional(string, "Ephemeral")
os_sku = optional(string, null)
vm_size = optional(string, "Standard_D2ds_v5")
})
description = "node default system pool for aks"
Expand All @@ -63,6 +85,8 @@ variable "node_user_pool" {
node_taints = optional(list(string), []) # needs defaults as we concat it later
os_disk_size_gb = optional(number, 120)
os_disk_type = optional(string, "Ephemeral")
os_sku = optional(string, null)
os_type = optional(string, "Linux")
priority = optional(string, "Regular")
spot_max_price = optional(number, -1)
vm_size = optional(string, "Standard_D4ds_v5")
Expand Down
2 changes: 1 addition & 1 deletion versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
terraform {
required_version = ">= 1.4.0"
required_providers {
azurerm = ">= 3.32.0"
azurerm = ">= 3.74.0"
random = ">= 3.4.0"
}
}

0 comments on commit 0930aec

Please sign in to comment.