diff --git a/modules/azapi/FrontDoor/frontdoor.tf b/modules/azapi/FrontDoor/frontdoor.tf new file mode 100644 index 00000000..8cd6fc8e --- /dev/null +++ b/modules/azapi/FrontDoor/frontdoor.tf @@ -0,0 +1,123 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +resource "azapi_resource" "frontdoor" { + type = "Microsoft.Network/frontDoors@2021-06-01" + name = local.frontdoor_name + parent_id = var.resource_group_id + location = "Global" + body = jsonencode({ + properties = { + enabledState = var.enabled + + # Configure Frontend Endpoints + frontendEndpoints = [ + for endpoint in var.frontend_endpoints : + { + name = join("-", [var.frontend_endpoints_abbreviation, endpoint.name]) + properties = { + hostName = endpoint.hostname + sessionAffinityEnabledState = endpoint.sessionAffinityEnabledState + sessionAffinityTtlSeconds = endpoint.sessionAffinityTtlSeconds + webApplicationFirewallPolicyLink = endpoint.webApplicationFirewallPolicyLink + } + } + ] + + # Configure Routing Rules + routingRules = [ + for rule in var.routing_rules : + { + name = rule.name + properties = { + acceptedProtocols = rule.acceptedProtocols + enabledState = rule.enabledState + patternsToMatch = rule.patternsToMatch + frontendEndpoints = rule.frontendEndpoints != null ? [ + for frontend_endpoint in rule.frontendEndpoints : + { + id = "${var.resource_group_id}/providers/Microsoft.Network/frontDoors/${local.frontdoor_name}/frontendEndpoints/${join("-", [var.frontend_endpoints_abbreviation, frontend_endpoint])}" + } + ] : null + routeConfiguration = rule.routeConfiguration + } + } + ] + + # Configure Load Balancing Settings + loadBalancingSettings = [ + for load_balance in var.load_balancing_settings : + { + name = join("-", [var.load_balancing_abbreviation, load_balance.name]) + properties = { + sampleSize = load_balance.sampleSize + successfulSamplesRequired = load_balance.successfulSamplesRequired + additionalLatencyMilliseconds = load_balance.additionalLatencyMilliseconds + } + } + ] + + # Configure Health Probes + healthProbeSettings = [ + for health_probe in var.health_probe_settings : + { + name = join("-", [var.health_probe_abbreviation, health_probe.name]) + properties = { + enabledState = health_probe.enabledState + path = health_probe.path + protocol = health_probe.protocol + healthProbeMethod = health_probe.healthProbeMethod + intervalInSeconds = health_probe.intervalInSeconds + } + } + ] + + # Configure Backend Pool + backendPools = [ + for pool in var.backend_pools : + { + name = pool.name + properties = { + backends = [ + for backend in pool.backends : + { + address = backend.address + backendHostHeader = backend.backendHostHeader + enabledState = backend.enabledState + httpPort = backend.httpPort + httpsPort = backend.httpsPort + priority = backend.priority + weight = backend.weight + } + ] + loadBalancingSettings = pool.loadBalancingSettings != null ? { + id = "${var.resource_group_id}/providers/Microsoft.Network/frontDoors/${local.frontdoor_name}/loadBalancingSettings/${join("-", [var.load_balancing_abbreviation, pool.loadBalancingSettings])}" + } : null + healthProbeSettings = pool.healthProbeSettings != null ? { + id = "${var.resource_group_id}/providers/Microsoft.Network/frontDoors/${local.frontdoor_name}/healthProbeSettings/${join("-", [var.health_probe_abbreviation, pool.healthProbeSettings])}" + } : null + } + } + ] + } + }) + + response_export_values = ["*"] +} diff --git a/modules/azapi/FrontDoor/locals.tf b/modules/azapi/FrontDoor/locals.tf new file mode 100644 index 00000000..00b09900 --- /dev/null +++ b/modules/azapi/FrontDoor/locals.tf @@ -0,0 +1,23 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +locals { + frontdoor_name = join("-", [var.frontdoor_abbreviation, var.frontdoor_name]) +} diff --git a/modules/azapi/FrontDoor/outputs.tf b/modules/azapi/FrontDoor/outputs.tf new file mode 100644 index 00000000..a625e205 --- /dev/null +++ b/modules/azapi/FrontDoor/outputs.tf @@ -0,0 +1,34 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +output "frontdoor_id" { + description = "The ID of the Front Door." + value = jsondecode(azapi_resource.frontdoor.output).properties.frontdoorId +} + +output "frontdoor_frontend_endpoint_ids" { + description = "The Resource IDs of the Frontend Endpoints of the Front Door. This is used to configure custom HTTPS settings." + value = [for endpoint in jsondecode(azapi_resource.frontdoor.output).properties.frontendEndpoints : endpoint.id if endpoint.name != "${var.frontend_endpoints_abbreviation}-default"] +} + +output "frontdoor_frontend_endpoint_names" { + description = "The Resource names of the Frontend Endpoints of the Front Door." + value = [for endpoint in jsondecode(azapi_resource.frontdoor.output).properties.frontendEndpoints : endpoint.name if endpoint.name != "${var.frontend_endpoints_abbreviation}-default"] +} diff --git a/modules/azapi/FrontDoor/rules_engine.tf b/modules/azapi/FrontDoor/rules_engine.tf new file mode 100644 index 00000000..86009302 --- /dev/null +++ b/modules/azapi/FrontDoor/rules_engine.tf @@ -0,0 +1,70 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +# Define the rules engine resource +resource "azapi_resource" "frontdoor_rules_engine" { + count = length(var.rules_engines) + type = "Microsoft.Network/frontDoors/rulesEngines@2021-06-01" + name = var.rules_engines[count.index].name + parent_id = azapi_resource.frontdoor.id + + body = jsonencode({ + properties = { + rules = var.rules_engines[count.index].rules + } + }) + + depends_on = [ + azapi_resource.frontdoor + ] +} + +# Update the frontdoor resource with the rules engine +resource "azapi_update_resource" "frontdoor" { + type = "Microsoft.Network/frontDoors@2021-06-01" + resource_id = azapi_resource.frontdoor.id + body = jsonencode({ + properties = { + routingRules = [ + for rule in jsondecode(azapi_resource.frontdoor.output).properties.routingRules : + { + id = rule.id + name = rule.name + properties = { + acceptedProtocols = rule.properties.acceptedProtocols + enabledState = rule.properties.enabledState + patternsToMatch = rule.properties.patternsToMatch + frontendEndpoints = rule.properties.frontendEndpoints + routeConfiguration = rule.properties.routeConfiguration + + rulesEngine = rule.properties.rulesEngine != null ? rule.properties.rulesEngine : contains(keys(var.rules_engine_map), rule.name) ? { + id = "${var.resource_group_id}/providers/Microsoft.Network/frontDoors/${local.frontdoor_name}/RulesEngines/${var.rules_engine_map[rule.name]}" + } : null + } + } + ] + } + }) + + depends_on = [ + azapi_resource.frontdoor, + azapi_resource.frontdoor_rules_engine + ] +} diff --git a/modules/azapi/FrontDoor/variables.tf b/modules/azapi/FrontDoor/variables.tf new file mode 100644 index 00000000..bafefecc --- /dev/null +++ b/modules/azapi/FrontDoor/variables.tf @@ -0,0 +1,128 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +variable "frontdoor_name" { + description = "The name of the Front Door." + type = string +} + +variable "frontdoor_abbreviation" { + description = "The abbreviation to be used in the name of the Front Door." + type = string + default = "fd" +} + +variable "resource_group_id" { + description = "The ID of the resource group in which the Front Door will be created." + type = string +} + +variable "enabled" { + description = "The state of the Front Door. Values are Enabled or Disabled." + type = string + default = "Enabled" +} + +variable "frontend_endpoints" { + description = "A list of frontend endpoints to be associated with the Front Door." + type = list(object({ + name = string + hostname = string + sessionAffinityEnabledState = string + sessionAffinityTtlSeconds = number + webApplicationFirewallPolicyLink = string + })) +} + +variable "frontend_endpoints_abbreviation" { + description = "The abbreviation to be used in the name of the frontend endpoints." + type = string + default = "fe" +} + +variable "routing_rules" { + description = "A list of routing rules to be associated with the Front Door. Check https://learn.microsoft.com/en-us/azure/templates/microsoft.network/frontdoors?pivots=deployment-language-terraform for more information." + type = any +} + +variable "load_balancing_settings" { + description = "A list of load balancing settings to be associated with the Front Door." + type = list(object({ + name = string + sampleSize = number + successfulSamplesRequired = number + additionalLatencyMilliseconds = number + })) +} + +variable "load_balancing_abbreviation" { + description = "The abbreviation to be used in the name of the load balancing settings." + type = string + default = "lb" +} + +variable "health_probe_settings" { + description = "A list of health probe settings to be associated with the Front Door." + type = list(object({ + name = string + enabledState = string + path = string + protocol = string + healthProbeMethod = string + intervalInSeconds = number + })) +} + +variable "health_probe_abbreviation" { + description = "The abbreviation to be used in the name of the health probe settings." + type = string + default = "hp" +} + +variable "backend_pools" { + description = "A list of backend pools to be associated with the Front Door." + type = list(object({ + name = string + backends = list(object({ + address = string + backendHostHeader = string + enabledState = string + httpPort = number + httpsPort = number + priority = number + weight = number + })) + loadBalancingSettings = string + healthProbeSettings = string + })) +} + +variable "rules_engines" { + description = "A list of rules engines to be associated with the Front Door. Check https://learn.microsoft.com/en-us/azure/templates/microsoft.network/frontdoors/rulesengines?pivots=deployment-language-terraform for more information." + type = list(object({ + name = string + rules = any + })) +} + +variable "rules_engine_map" { + description = "A map of rules engines to be associated with the Front Door." + type = map(string) +} diff --git a/modules/azapi/FrontDoor/versions.tf b/modules/azapi/FrontDoor/versions.tf new file mode 100644 index 00000000..1113450a --- /dev/null +++ b/modules/azapi/FrontDoor/versions.tf @@ -0,0 +1,30 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +terraform { + required_version = ">= 0.14.10" + + required_providers { + azapi = { + source = "Azure/azapi" + version = "1.12.1" + } + } +}