-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DEVEX-131] New TF module to create an Azure App Service (#26)
- Loading branch information
Showing
11 changed files
with
461 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# DX - Azure App Service Module | ||
|
||
<!-- markdownlint-disable --> | ||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | ||
## Requirements | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 3.100.0 | | ||
|
||
## Providers | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.105.0 | | ||
|
||
## Modules | ||
|
||
| Name | Source | Version | | ||
|------|--------|---------| | ||
| <a name="module_naming_convention"></a> [naming\_convention](#module\_naming\_convention) | ../azure_naming_convention | n/a | | ||
|
||
## Resources | ||
|
||
| Name | Type | | ||
|------|------| | ||
| [azurerm_linux_web_app.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app) | resource | | ||
| [azurerm_linux_web_app_slot.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app_slot) | resource | | ||
| [azurerm_private_endpoint.app_service_sites](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource | | ||
| [azurerm_private_endpoint.staging_app_service_sites](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource | | ||
| [azurerm_service_plan.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/service_plan) | resource | | ||
| [azurerm_subnet.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) | resource | | ||
| [azurerm_private_dns_zone.app_service](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/private_dns_zone) | data source | | ||
| [azurerm_virtual_network.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source | | ||
|
||
## Inputs | ||
|
||
| Name | Description | Type | Default | Required | | ||
|------|-------------|------|---------|:--------:| | ||
| <a name="input_app_service_plan_id"></a> [app\_service\_plan\_id](#input\_app\_service\_plan\_id) | (Optional) Set the AppService Id where you want to host the Function App | `string` | `null` | no | | ||
| <a name="input_app_settings"></a> [app\_settings](#input\_app\_settings) | Application settings | `map(string)` | n/a | yes | | ||
| <a name="input_application_insights_connection_string"></a> [application\_insights\_connection\_string](#input\_application\_insights\_connection\_string) | (Optional) Application Insights connection string | `string` | `null` | no | | ||
| <a name="input_application_insights_sampling_percentage"></a> [application\_insights\_sampling\_percentage](#input\_application\_insights\_sampling\_percentage) | (Optional) The sampling percentage of Application Insights. Default is 5 | `number` | `5` | no | | ||
| <a name="input_environment"></a> [environment](#input\_environment) | Values which are used to generate resource names and location short names. They are all mandatory except for domain, which should not be used only in the case of a resource used by multiple domains. | <pre>object({<br> prefix = string<br> env_short = string<br> location = string<br> domain = optional(string)<br> app_name = string<br> instance_number = string<br> })</pre> | n/a | yes | | ||
| <a name="input_health_check_path"></a> [health\_check\_path](#input\_health\_check\_path) | Endpoint where health probe is exposed | `string` | n/a | yes | | ||
| <a name="input_java_version"></a> [java\_version](#input\_java\_version) | Java version to use | `string` | `17` | no | | ||
| <a name="input_node_version"></a> [node\_version](#input\_node\_version) | Node version to use | `number` | `20` | no | | ||
| <a name="input_private_dns_zone_resource_group_name"></a> [private\_dns\_zone\_resource\_group\_name](#input\_private\_dns\_zone\_resource\_group\_name) | (Optional) The name of the resource group holding private DNS zone to use for private endpoints. Default is Virtual Network resource group | `string` | `null` | no | | ||
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Resource group to deploy resources to | `string` | n/a | yes | | ||
| <a name="input_slot_app_settings"></a> [slot\_app\_settings](#input\_slot\_app\_settings) | Staging slot application settings | `map(string)` | `{}` | no | | ||
| <a name="input_stack"></a> [stack](#input\_stack) | n/a | `string` | `"node"` | no | | ||
| <a name="input_sticky_app_setting_names"></a> [sticky\_app\_setting\_names](#input\_sticky\_app\_setting\_names) | (Optional) A list of application setting names that are not swapped between slots | `list(string)` | `[]` | no | | ||
| <a name="input_subnet_cidr"></a> [subnet\_cidr](#input\_subnet\_cidr) | CIDR block to use for the subnet the Function App uses for outbound connectivity | `string` | n/a | yes | | ||
| <a name="input_subnet_pep_id"></a> [subnet\_pep\_id](#input\_subnet\_pep\_id) | Id of the subnet which holds private endpoints | `string` | n/a | yes | | ||
| <a name="input_tags"></a> [tags](#input\_tags) | Resources tags | `map(any)` | n/a | yes | | ||
| <a name="input_tier"></a> [tier](#input\_tier) | Resource tiers depending on demanding workload. Allowed values are 'premium', 'standard', 'test'. Note, "test" does not support deployment slots. | `string` | `"premium"` | no | | ||
| <a name="input_virtual_network"></a> [virtual\_network](#input\_virtual\_network) | Virtual network in which to create the subnet | <pre>object({<br> name = string<br> resource_group_name = string<br> })</pre> | n/a | yes | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|------|-------------| | ||
| <a name="output_app_service"></a> [app\_service](#output\_app\_service) | n/a | | ||
| <a name="output_subnet"></a> [subnet](#output\_subnet) | n/a | | ||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
resource "azurerm_linux_web_app" "this" { | ||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-app-${var.environment.instance_number}" | ||
location = var.environment.location | ||
resource_group_name = var.resource_group_name | ||
|
||
service_plan_id = local.app_service_plan.enable ? azurerm_service_plan.this[0].id : var.app_service_plan_id | ||
|
||
https_only = true | ||
public_network_access_enabled = false | ||
virtual_network_subnet_id = azurerm_subnet.this.id | ||
|
||
identity { | ||
type = "SystemAssigned" | ||
} | ||
|
||
site_config { | ||
http2_enabled = true | ||
always_on = true | ||
vnet_route_all_enabled = true | ||
health_check_path = var.health_check_path | ||
health_check_eviction_time_in_min = 2 | ||
ip_restriction_default_action = "Deny" | ||
|
||
application_stack { | ||
node_version = var.stack == "node" ? "${var.node_version}-lts" : null | ||
java_version = var.stack == "java" ? var.java_version : null | ||
} | ||
} | ||
|
||
app_settings = merge( | ||
{ | ||
# https://github.com/projectkudu/kudu/wiki/Configurable-settings#attempt-to-rename-dlls-if-they-cant-be-copied-during-a-webdeploy-deployment-1 | ||
WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG = 1 | ||
# https://learn.microsoft.com/en-us/azure/azure-functions/run-functions-from-deployment-package#using-website_run_from_package--1 | ||
WEBSITE_RUN_FROM_PACKAGE = 1 | ||
# https://docs.microsoft.com/en-us/azure/virtual-network/what-is-ip-address-168-63-129-16 | ||
WEBSITE_DNS_SERVER = "168.63.129.16" | ||
}, | ||
var.app_settings, | ||
local.application_insights.enable ? { | ||
# https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#applicationinsights_connection_string | ||
APPLICATIONINSIGHTS_CONNECTION_STRING = var.application_insights_connection_string | ||
# https://docs.microsoft.com/en-us/azure/azure-monitor/app/sampling | ||
APPINSIGHTS_SAMPLING_PERCENTAGE = var.application_insights_sampling_percentage | ||
} : {} | ||
) | ||
|
||
dynamic "sticky_settings" { | ||
for_each = length(var.sticky_app_setting_names) == 0 ? [] : [1] | ||
content { | ||
app_setting_names = var.sticky_app_setting_names | ||
} | ||
} | ||
|
||
lifecycle { | ||
ignore_changes = [ | ||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"], | ||
app_settings["WEBSITE_HEALTHCHECK_MAXPINGFAILURES"], | ||
tags["hidden-link: /app-insights-conn-string"], | ||
tags["hidden-link: /app-insights-instrumentation-key"], | ||
tags["hidden-link: /app-insights-resource-id"] | ||
] | ||
} | ||
|
||
tags = var.tags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
resource "azurerm_service_plan" "this" { | ||
count = local.app_service_plan.enable ? 1 : 0 | ||
|
||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-asp-${var.environment.instance_number}" | ||
location = var.environment.location | ||
resource_group_name = var.resource_group_name | ||
os_type = "Linux" | ||
sku_name = local.app_service.sku_name | ||
zone_balancing_enabled = local.app_service.zone_balancing_enabled | ||
|
||
tags = var.tags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
resource "azurerm_linux_web_app_slot" "this" { | ||
count = local.app_service.is_slot_enabled | ||
|
||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-staging-app-${var.environment.instance_number}" | ||
|
||
app_service_id = azurerm_linux_web_app.this.id | ||
|
||
https_only = true | ||
public_network_access_enabled = false | ||
virtual_network_subnet_id = azurerm_subnet.this.id | ||
|
||
identity { | ||
type = "SystemAssigned" | ||
} | ||
|
||
site_config { | ||
http2_enabled = true | ||
always_on = true | ||
vnet_route_all_enabled = true | ||
health_check_path = var.health_check_path | ||
health_check_eviction_time_in_min = 2 | ||
ip_restriction_default_action = "Deny" | ||
|
||
application_stack { | ||
node_version = var.stack == "node" ? var.node_version : null | ||
java_version = var.stack == "java" ? var.java_version : null | ||
} | ||
} | ||
|
||
app_settings = merge( | ||
{ | ||
# https://github.com/projectkudu/kudu/wiki/Configurable-settings#attempt-to-rename-dlls-if-they-cant-be-copied-during-a-webdeploy-deployment-1 | ||
WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG = 1 | ||
# https://learn.microsoft.com/en-us/azure/azure-functions/run-functions-from-deployment-package#using-website_run_from_package--1 | ||
WEBSITE_RUN_FROM_PACKAGE = 1 | ||
# https://docs.microsoft.com/en-us/azure/virtual-network/what-is-ip-address-168-63-129-16 | ||
WEBSITE_DNS_SERVER = "168.63.129.16" | ||
}, | ||
var.slot_app_settings, | ||
local.application_insights.enable ? { | ||
# https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#applicationinsights_connection_string | ||
APPLICATIONINSIGHTS_CONNECTION_STRING = var.application_insights_connection_string | ||
# https://docs.microsoft.com/en-us/azure/azure-monitor/app/sampling | ||
APPINSIGHTS_SAMPLING_PERCENTAGE = var.application_insights_sampling_percentage | ||
} : {} | ||
) | ||
|
||
lifecycle { | ||
ignore_changes = [ | ||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"], | ||
app_settings["WEBSITE_HEALTHCHECK_MAXPINGFAILURES"], | ||
tags["hidden-link: /app-insights-conn-string"], | ||
tags["hidden-link: /app-insights-instrumentation-key"], | ||
tags["hidden-link: /app-insights-resource-id"] | ||
] | ||
} | ||
|
||
tags = var.tags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
data "azurerm_virtual_network" "this" { | ||
name = var.virtual_network.name | ||
resource_group_name = var.virtual_network.resource_group_name | ||
} | ||
|
||
data "azurerm_private_dns_zone" "app_service" { | ||
name = "privatelink.azurewebsites.net" | ||
resource_group_name = local.private_dns_zone.resource_group_name | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
locals { | ||
location_short = var.environment.location == "italynorth" ? "itn" : var.environment.location == "westeurope" ? "weu" : var.environment.location == "germanywestcentral" ? "gwc" : "neu" | ||
project = "${var.environment.prefix}-${var.environment.env_short}-${local.location_short}" | ||
|
||
app_service_plan = { | ||
enable = var.app_service_plan_id == null | ||
} | ||
|
||
app_service = { | ||
sku_name = var.tier == "test" ? "B1" : var.tier == "standard" ? "P0v3" : "P1v3" | ||
zone_balancing_enabled = var.tier != "test" | ||
is_slot_enabled = var.tier == "test" ? 0 : 1 | ||
} | ||
|
||
application_insights = { | ||
enable = var.application_insights_connection_string != null | ||
} | ||
|
||
private_dns_zone = { | ||
resource_group_name = var.private_dns_zone_resource_group_name == null ? var.virtual_network.resource_group_name : var.private_dns_zone_resource_group_name | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
terraform { | ||
required_providers { | ||
azurerm = { | ||
source = "hashicorp/azurerm" | ||
version = ">= 3.100.0" | ||
} | ||
} | ||
} | ||
|
||
provider "azurerm" { | ||
features {} | ||
} | ||
|
||
module "naming_convention" { | ||
source = "../azure_naming_convention" | ||
|
||
environment = { | ||
prefix = var.environment.prefix | ||
env_short = var.environment.env_short | ||
location = var.environment.location | ||
domain = var.environment.domain | ||
app_name = var.environment.app_name | ||
instance_number = var.environment.instance_number | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
resource "azurerm_private_endpoint" "app_service_sites" { | ||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-app-pep-${var.environment.instance_number}" | ||
location = var.environment.location | ||
resource_group_name = var.resource_group_name | ||
subnet_id = var.subnet_pep_id | ||
|
||
private_service_connection { | ||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-app-pep-${var.environment.instance_number}" | ||
private_connection_resource_id = azurerm_linux_web_app.this.id | ||
is_manual_connection = false | ||
subresource_names = ["sites"] | ||
} | ||
|
||
private_dns_zone_group { | ||
name = "private-dns-zone-group" | ||
private_dns_zone_ids = [data.azurerm_private_dns_zone.app_service.id] | ||
} | ||
|
||
tags = var.tags | ||
} | ||
|
||
resource "azurerm_private_endpoint" "staging_app_service_sites" { | ||
count = local.app_service.is_slot_enabled | ||
|
||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-staging-app-pep-${var.environment.instance_number}" | ||
location = var.environment.location | ||
resource_group_name = var.resource_group_name | ||
subnet_id = var.subnet_pep_id | ||
|
||
private_service_connection { | ||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-staging-app-pep-${var.environment.instance_number}" | ||
private_connection_resource_id = azurerm_linux_web_app.this.id | ||
is_manual_connection = false | ||
subresource_names = ["sites-${azurerm_linux_web_app_slot.this[0].name}"] | ||
} | ||
|
||
private_dns_zone_group { | ||
name = "private-dns-zone-group" | ||
private_dns_zone_ids = [data.azurerm_private_dns_zone.app_service.id] | ||
} | ||
|
||
tags = var.tags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
output "subnet" { | ||
value = { | ||
id = azurerm_subnet.this.id | ||
name = azurerm_subnet.this.name | ||
} | ||
} | ||
|
||
output "app_service" { | ||
value = { | ||
resource_group_name = azurerm_linux_web_app.this.resource_group_name | ||
plan = { | ||
id = try(azurerm_service_plan.this[0].id, null) | ||
name = try(azurerm_service_plan.this[0].name, null) | ||
} | ||
app_service = { | ||
id = azurerm_linux_web_app.this.id | ||
name = azurerm_linux_web_app.this.name | ||
principal_id = azurerm_linux_web_app.this.identity[0].principal_id | ||
slot = { | ||
id = try(azurerm_linux_web_app_slot.this[0].id, null) | ||
name = try(azurerm_linux_web_app_slot.this[0].name, null) | ||
principal_id = try(azurerm_linux_web_app_slot.this[0].identity[0].principal_id, null) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
resource "azurerm_subnet" "this" { | ||
name = "${local.project}-${var.environment.domain}-${var.environment.app_name}-app-snet-${var.environment.instance_number}" | ||
virtual_network_name = data.azurerm_virtual_network.this.name | ||
resource_group_name = data.azurerm_virtual_network.this.resource_group_name | ||
address_prefixes = [var.subnet_cidr] | ||
|
||
delegation { | ||
name = "default" | ||
service_delegation { | ||
name = "Microsoft.Web/serverFarms" | ||
actions = ["Microsoft.Network/virtualNetworks/subnets/action"] | ||
} | ||
} | ||
} |
Oops, something went wrong.