Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion infrastructure/modules/app-service-plan/autoscale.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

resource "azurerm_monitor_autoscale_setting" "asp_autoscale" {
name = "${var.name}-autoscale"
resource_group_name = var.resource_group_name
Expand Down
11 changes: 11 additions & 0 deletions infrastructure/modules/app-service-plan/certificate.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "azurerm_app_service_certificate" "wildcard" {
count = var.wildcard_ssl_cert_key_vault_secret_id != null ? 1 : 0

name = var.wildcard_ssl_cert_name
resource_group_name = var.resource_group_name
location = var.location

app_service_plan_id = azurerm_service_plan.appserviceplan.id
key_vault_secret_id = var.wildcard_ssl_cert_key_vault_secret_id
key_vault_id = var.wildcard_ssl_cert_key_vault_id
}
7 changes: 0 additions & 7 deletions infrastructure/modules/app-service-plan/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
resource "azurerm_service_plan" "appserviceplan" {

name = var.name
resource_group_name = var.resource_group_name
location = var.location
Expand All @@ -21,10 +20,6 @@ resource "azurerm_app_service_virtual_network_swift_connection" "appservice_vnet
subnet_id = var.vnet_integration_subnet_id
}

/* --------------------------------------------------------------------------------------------------
Diagnostic Settings
-------------------------------------------------------------------------------------------------- */

module "diagnostic-settings" {
source = "../diagnostic-settings"

Expand All @@ -33,6 +28,4 @@ module "diagnostic-settings" {
log_analytics_workspace_id = var.log_analytics_workspace_id
#enabled_log = var.enabled_log
metric = var.monitor_diagnostic_setting_appserviceplan_metrics

}

4 changes: 3 additions & 1 deletion infrastructure/modules/app-service-plan/output.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

output "app_service_plan_name" {
value = azurerm_service_plan.appserviceplan.name
}
Expand All @@ -7,3 +6,6 @@ output "app_service_plan_id" {
value = azurerm_service_plan.appserviceplan.id
}

output "wildcard_ssl_cert_id" {
value = var.wildcard_ssl_cert_key_vault_secret_id != null ? azurerm_app_service_certificate.wildcard[0].id : null
}
28 changes: 24 additions & 4 deletions infrastructure/modules/app-service-plan/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ variable "sku_name" {
default = "B1"
}

variable "tags" {
type = map(string)
description = "Resource tags to be applied throughout the deployment."
default = {}
}

variable "vnet_integration_enabled" {
type = bool
description = "Indicates whether the App Service Plan is integrated with a VNET."
Expand All @@ -47,18 +53,32 @@ variable "vnet_integration_subnet_id" {
default = ""
}

variable "tags" {
type = map(string)
description = "Resource tags to be applied throughout the deployment."
default = {}
variable "wildcard_ssl_cert_key_vault_secret_id" {
type = string
description = "Wildcard SSL certificate Key Vault secret id, for App Service Custom Domain binding."
default = null
}

variable "wildcard_ssl_cert_key_vault_id" {
type = string
description = "Wildcard SSL certificate Key Vault id, needed if the Key Vault is in a different subscription."
default = null
}

variable "wildcard_ssl_cert_name" {
type = string
description = "Wildcard SSL certificate name, for Custom Domain binding."
default = null
}


## autoscale rule ##

variable "metric" {
type = string
default = "MemoryPercentage"
}

variable "capacity_min" {
type = string
default = "1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
data "azurerm_dns_zone" "lookup" {
name = var.dns_zone_name
for_each = var.dns_zone_names

name = each.value
resource_group_name = var.dns_zone_resource_group_name
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ resource "local_file" "certbot_ini_file" {
content = <<EOT
dns_azure_use_cli_credentials = true
dns_azure_environment = "AzurePublicCloud"
dns_azure_zone1 = ${var.dns_zone_name}:${data.azurerm_dns_zone.lookup.id}
%{for name, zone in var.dns_zone_names~}
dns_azure_zone${index(keys(var.dns_zone_names), name) + 1} = ${zone}:${data.azurerm_dns_zone.lookup[name].id}
%{endfor~}
EOT
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ if [[ ${#kv_names[@]} -eq 0 || -z "${email}" || -z "${subscription_id_target}" |
fi

# Temporary until version 4 is actually working with library josepy 2.0.0
pip3 install 'certbot==2.11.1' certbot-dns-azure
pip3 install 'certbot==3.3.0' certbot-dns-azure
#pip3 install certbot certbot-dns-azure

mkdir -p .terraform/certbot
Expand All @@ -84,7 +84,7 @@ echo "Attempting retrieval of stored certificate creation state..."
az account set --subscription "${subscription_id_hub}"
az storage blob download --account-name "${storage_account_name}" --container-name "${container_name}" --name "${environment}.zip" --file "./certbot_state.zip" --auth-mode login || true # continue on failure
if [[ -e ./certbot_state.zip ]]; then
unzip -o ./certbot_state.zip
unzip -oq ./certbot_state.zip
rm ./certbot_state.zip
# reset canonical paths in renewal conf files to match the local environment
sed -i "s#agent_workdir#${agent_workdir}#g" certbot/config/renewal/*.conf
Expand Down Expand Up @@ -136,7 +136,7 @@ done
echo "Persisting certificate creation state to Azure Storage Account..."
# reset canonical paths in renewal conf files to something predictable
sed -i "s#${agent_workdir}#agent_workdir#g" certbot/config/renewal/*.conf
zip -ry certbot_state.zip certbot/config certbot/logs
zip -ryq certbot_state.zip certbot/config certbot/logs
az account set --subscription "${subscription_id_hub}"
az storage blob upload --account-name "${storage_account_name}" --container-name "${container_name}" --file "./certbot_state.zip" --name "${environment}.zip" --overwrite --auth-mode login

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ variable "certificates" {
type = map(string)
}

variable "dns_zone_name" {
type = string
variable "dns_zone_names" {
type = map(string)
description = "Map of zone identifiers to their full private DNS zone names"
}

variable "dns_zone_resource_group_name" {
Expand Down
53 changes: 48 additions & 5 deletions infrastructure/modules/linux-web-app/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
resource "azurerm_linux_web_app" "linux_web_app" {

resource "azurerm_linux_web_app" "this" {
name = var.linux_web_app_name
resource_group_name = var.resource_group_name
location = var.location
Expand Down Expand Up @@ -68,6 +67,50 @@ resource "azurerm_linux_web_app" "linux_web_app" {
tags = var.tags
}


/* --------------------------------------------------------------------------------------------------
Custom Domain and Certificate Bindings
-------------------------------------------------------------------------------------------------- */

resource "azurerm_dns_txt_record" "validation" {
for_each = toset(var.custom_domains)

provider = azurerm.hub # Terraform Managed Identity will need DNS Contributor RBAC role on the DNS Zone

name = "asuid.${split(".", each.key)[0]}"
zone_name = replace(each.key, "${split(".", each.key)[0]}.", "")
resource_group_name = var.public_dns_zone_rg_name
ttl = 300

record {
value = azurerm_linux_web_app.this.custom_domain_verification_id
}
}

resource "azurerm_app_service_custom_hostname_binding" "this" {
for_each = toset(var.custom_domains)

hostname = each.key
app_service_name = azurerm_linux_web_app.this.name
resource_group_name = azurerm_linux_web_app.this.resource_group_name

depends_on = [azurerm_dns_txt_record.validation]

# Ignore ssl_state and thumbprint as they are managed using azurerm_app_service_certificate_binding
lifecycle {
ignore_changes = [ssl_state, thumbprint]
}
}

resource "azurerm_app_service_certificate_binding" "this" {
for_each = toset(var.custom_domains)

hostname_binding_id = azurerm_app_service_custom_hostname_binding.this[each.key].id
certificate_id = var.wildcard_ssl_cert_id
ssl_state = "SniEnabled"
}


/* --------------------------------------------------------------------------------------------------
Private Endpoint Configuration
-------------------------------------------------------------------------------------------------- */
Expand All @@ -89,7 +132,7 @@ module "private_endpoint" {

private_service_connection = {
name = "${var.linux_web_app_name}-private-endpoint-connection"
private_connection_resource_id = azurerm_linux_web_app.linux_web_app.id
private_connection_resource_id = azurerm_linux_web_app.this.id
subresource_names = ["sites"]
is_manual_connection = var.private_endpoint_properties.private_service_connection_is_manual
}
Expand All @@ -107,7 +150,7 @@ module "linux_web_app_slots" {
source = "../linux-web-app-slots"

name = each.value.linux_web_app_slots_name
linux_web_app_id = azurerm_linux_web_app.linux_web_app.id
linux_web_app_id = azurerm_linux_web_app.this.id
linux_web_app_slots_enabled = each.value.linux_web_app_slots_enabled

storage_account_access_key = var.storage_account_access_key
Expand All @@ -128,7 +171,7 @@ module "diagnostic-settings" {
source = "../diagnostic-settings"

name = "${var.linux_web_app_name}-diagnostic-setting"
target_resource_id = azurerm_linux_web_app.linux_web_app.id
target_resource_id = azurerm_linux_web_app.this.id
log_analytics_workspace_id = var.log_analytics_workspace_id
enabled_log = var.monitor_diagnostic_setting_linux_web_app_enabled_logs
metric = var.monitor_diagnostic_setting_linux_web_app_metrics
Expand Down
6 changes: 3 additions & 3 deletions infrastructure/modules/linux-web-app/output.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
output "name" {
description = "The name of the Linux Web App."
value = azurerm_linux_web_app.linux_web_app.name
value = azurerm_linux_web_app.this.name
}

output "linux_web_app_endpoint_name" {
Expand All @@ -10,10 +10,10 @@ output "linux_web_app_endpoint_name" {

output "id" {
description = "The id of the Linux Web App."
value = azurerm_linux_web_app.linux_web_app.id
value = azurerm_linux_web_app.this.id
}

output "linux_web_app_sami_id" {
description = "The Principal ID of the System Assigned Managed Service Identity that is configured on this Linux Web App."
value = azurerm_linux_web_app.linux_web_app.identity.0.principal_id
value = azurerm_linux_web_app.this.identity.0.principal_id
}
7 changes: 7 additions & 0 deletions infrastructure/modules/linux-web-app/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
}
}
2 changes: 1 addition & 1 deletion infrastructure/modules/linux-web-app/rbac.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module "rbac_assignments" {

source = "../rbac-assignment"

principal_id = azurerm_linux_web_app.linux_web_app.identity.0.principal_id
principal_id = azurerm_linux_web_app.this.identity.0.principal_id
role_definition_name = each.value.role_definition_name
scope = each.value.scope
}
39 changes: 28 additions & 11 deletions infrastructure/modules/linux-web-app/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ variable "acr_mi_client_id" {

variable "always_on" {
type = bool
description = "Should the Function App be always on. Override standard default."
description = "Should the Web App be always on. Override standard default."
default = true
}

Expand All @@ -25,7 +25,7 @@ variable "asp_id" {

variable "assigned_identity_ids" {
type = list(string)
description = "The list of User Assigned Identity IDs to assign to the Function App."
description = "The list of User Assigned Identity IDs to assign to the Web App."
}

variable "cont_registry_use_mi" {
Expand All @@ -34,7 +34,12 @@ variable "cont_registry_use_mi" {

variable "cors_allowed_origins" {
type = list(string)
default = [""]
default = []
}

variable "custom_domains" {
type = list(string)
default = []
}

variable "docker_image_name" {
Expand Down Expand Up @@ -108,12 +113,12 @@ variable "http_version" {

variable "https_only" {
type = bool
description = "Can the Function App only be accessed via HTTPS? Override standard default."
description = "Can the Web App only be accessed via HTTPS? Override standard default."
default = true
}

variable "linux_web_app_name" {
description = "Name of the Function App"
description = "Name of the Web App"
}

variable "linux_web_app_slots" {
Expand All @@ -127,7 +132,7 @@ variable "linux_web_app_slots" {

variable "location" {
type = string
description = "The location/region where the Function App is created."
description = "The location/region where the Web App is created."
}

variable "log_analytics_workspace_id" {
Expand Down Expand Up @@ -156,7 +161,7 @@ variable "monitor_diagnostic_setting_linux_web_app_metrics" {
}

variable "private_endpoint_properties" {
description = "Consolidated properties for the Function App Private Endpoint."
description = "Consolidated properties for the Web App Private Endpoint."
type = object({
private_dns_zone_ids = optional(list(string), [])
private_endpoint_enabled = optional(bool, false)
Expand All @@ -171,9 +176,15 @@ variable "private_endpoint_properties" {
}
}

variable "public_dns_zone_rg_name" {
type = string
description = "Name of the Resource Group containing the public DNS zones in the Hub subscription."
default = null
}

variable "public_network_access_enabled" {
type = bool
description = "Should the Function App be accessible from the public network. Override standard default."
description = "Should the Web App be accessible from the public network. Override standard default."
default = false
}

Expand All @@ -187,7 +198,7 @@ variable "rbac_role_assignments" {

variable "resource_group_name" {
type = string
description = "The name of the resource group in which to create the Function App. Changing this forces a new resource to be created."
description = "The name of the resource group in which to create the Web App. Changing this forces a new resource to be created."
}

variable "storage_account_access_key" {
Expand Down Expand Up @@ -228,7 +239,7 @@ variable "tags" {

variable "vnet_integration_subnet_id" {
type = string
description = "The ID of the subnet to integrate the Function App with."
description = "The ID of the subnet to integrate the Web App with."
default = null
}

Expand All @@ -238,7 +249,13 @@ variable "webdeploy_publish_basic_authentication_enabled" {
default = false
}

variable "wildcard_ssl_cert_id" {
type = string
description = "The ID of the wildcard SSL certificate associated to the App Service Plan, used for Custom Domain binding."
default = null
}

variable "worker_32bit" {
type = bool
description = "Should the Windows Function App use a 32-bit worker process. Defaults to true"
description = "Should the Windows Web App use a 32-bit worker process. Defaults to true"
}
Loading
Loading