From 998085165c8ca7730eb872ddc5238fc7a499106a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahlstr=C3=B6m=20Kalle?= Date: Thu, 18 Jan 2024 02:29:46 +0200 Subject: [PATCH] new web infra --- main.tf | 30 ++++++- modules/common/main.tf | 7 -- modules/common/network.tf | 134 ++++++++++++++++++++++++++++++ modules/common/output.tf | 21 +++++ modules/dns/root/main.tf | 5 ++ modules/dns/root/output.tf | 3 + modules/keyvault/main.tf | 10 +++ modules/keyvault/output.tf | 35 ++++++-- modules/web/app/dns.tf | 107 ++++++++++++++++++++++++ modules/web/app/main.tf | 135 +++++++++++++++++++++++++++++++ modules/web/app/outputs.tf | 3 + modules/web/app/variables.tf | 61 ++++++++++++++ modules/web/storage/main.tf | 87 ++++++++++++++++++++ modules/web/storage/output.tf | 21 +++++ modules/web/storage/variables.tf | 23 ++++++ 15 files changed, 666 insertions(+), 16 deletions(-) create mode 100644 modules/common/network.tf create mode 100644 modules/web/app/dns.tf create mode 100644 modules/web/app/main.tf create mode 100644 modules/web/app/outputs.tf create mode 100644 modules/web/app/variables.tf create mode 100644 modules/web/storage/main.tf create mode 100644 modules/web/storage/output.tf create mode 100644 modules/web/storage/variables.tf diff --git a/main.tf b/main.tf index 249e8e0..2abdccb 100644 --- a/main.tf +++ b/main.tf @@ -113,6 +113,34 @@ module "common" { env_name = "prod" resource_group_location = local.resource_group_location } +module "web_storage" { + source = "./modules/web/storage" + resource_group_location = local.resource_group_location + resource_group_name = module.common.resource_group_name + private_subnet_id = module.common.tiknet_private_subnet_id + private_subnet_name = module.common.tiknet_private_subnet_name + private_root_zone_name = module.dns_prod.private_root_zone_name + virtual_network_id = module.common.tiknet_virtual_network_id + private_storage_subnet_id = module.common.tiknet_private_storage_subnet_id +} +module "web" { + source = "./modules/web/app" + resource_group_location = local.resource_group_location + resource_group_name = module.common.resource_group_name + public_subnet_id = module.common.tiknet_public_subnet_id + private_subnet_id = module.common.tiknet_private_subnet_id + app_service_plan_id = module.common.tikweb_app_plan_id + acme_account_key = module.common.acme_account_key + root_zone_name = module.dns_prod.root_zone_name + dns_resource_group_name = module.dns_prod.resource_group_name + subdomain = "alpha" + mongo_connection_string = module.web_storage.mongo_connection_string + google_oauth_client_id = module.keyvault.google_oauth_client_id + google_oauth_client_secret = module.keyvault.google_oauth_client_secret + storage_connection_string = module.web_storage.storage_connection_string + storage_container_name = module.web_storage.storage_container_name + storage_account_base_url = module.web_storage.storage_account_base_url +} module "ilmo" { source = "./modules/ilmo" @@ -126,7 +154,7 @@ module "ilmo" { auth_jwt_secret = module.keyvault.ilmo_auth_jwt_secret mailgun_api_key = module.keyvault.ilmo_mailgun_api_key mailgun_domain = module.keyvault.ilmo_mailgun_domain - website_events_url = "https://tikwebprodsa.z16.web.core.windows.net/tapahtumat" #placeholder until new one is made + website_events_url = "${module.web.fqdn}/fi/tapahtumat" # TODO: needs two paths perhaps? for both languages tikweb_app_plan_id = module.common.tikweb_app_plan_id tikweb_rg_location = module.common.resource_group_location tikweb_rg_name = module.common.resource_group_name diff --git a/modules/common/main.tf b/modules/common/main.tf index 0b39f7b..e11ea98 100644 --- a/modules/common/main.tf +++ b/modules/common/main.tf @@ -60,10 +60,3 @@ resource "acme_registration" "acme_reg" { account_key_pem = tls_private_key.acme_account_key.private_key_pem email_address = "admin@tietokilta.fi" } - -resource "azurerm_virtual_network" "tiknet" { - name = "tiknet-${var.env_name}" - address_space = ["10.1.0.0/16"] - location = azurerm_resource_group.tikweb_rg.location - resource_group_name = azurerm_resource_group.tikweb_rg.name -} diff --git a/modules/common/network.tf b/modules/common/network.tf new file mode 100644 index 0000000..11a74dd --- /dev/null +++ b/modules/common/network.tf @@ -0,0 +1,134 @@ + +resource "azurerm_virtual_network" "tiknet" { + name = "tiknet-${terraform.workspace}" + address_space = ["10.1.0.0/16"] + location = azurerm_resource_group.tikweb_rg.location + resource_group_name = azurerm_resource_group.tikweb_rg.name +} +resource "azurerm_subnet" "web-public-subnet" { + name = "web-public-subnet-${terraform.workspace}" + resource_group_name = azurerm_resource_group.tikweb_rg.name + virtual_network_name = azurerm_virtual_network.tiknet.name + address_prefixes = ["10.1.1.0/24"] + delegation { + name = "webappdelegation" + + service_delegation { + name = "Microsoft.Web/serverFarms" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } + +} +resource "azurerm_subnet" "web-private-subnet" { + name = "web-private-subnet-${terraform.workspace}" + resource_group_name = azurerm_resource_group.tikweb_rg.name + virtual_network_name = azurerm_virtual_network.tiknet.name + address_prefixes = ["10.1.2.0/24"] + service_endpoints = ["Microsoft.AzureCosmosDB"] + delegation { + name = "webappdelegation" + + service_delegation { + name = "Microsoft.Web/serverFarms" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } + +} +resource "azurerm_subnet" "web-private-storage-subnet" { + name = "web-private-storage-subnet-${terraform.workspace}" + resource_group_name = azurerm_resource_group.tikweb_rg.name + virtual_network_name = azurerm_virtual_network.tiknet.name + address_prefixes = ["10.1.3.0/24"] +} + +resource "azurerm_network_security_group" "public_nsg" { + name = "public-nsg-${terraform.workspace}" + location = azurerm_resource_group.tikweb_rg.location + resource_group_name = azurerm_resource_group.tikweb_rg.name + security_rule { + name = "AllowHTTPHTTPSInbound" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_ranges = ["80", "443"] + source_address_prefix = "Internet" + destination_address_prefix = "*" + } + + security_rule { + name = "AllowToPrivateSubnet" + priority = 110 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = azurerm_subnet.web-private-subnet.address_prefixes[0] + } + security_rule { + name = "AllowInternetOutbound" + priority = 120 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = "Internet" + } +} +resource "azurerm_network_security_group" "private_nsg" { + name = "private-nsg-${terraform.workspace}" + location = azurerm_resource_group.tikweb_rg.location + resource_group_name = azurerm_resource_group.tikweb_rg.name + + security_rule { + name = "DenyAllInboundFromInternet" + priority = 100 + direction = "Inbound" + access = "Deny" + protocol = "*" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "Internet" + destination_address_prefix = "*" + } + security_rule { + name = "AllowAllInboundFromVnet" + priority = 110 + direction = "Inbound" + access = "Allow" + protocol = "*" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "*" + } + + security_rule { + name = "AllowOutboundToSpecificServices" + priority = 110 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = "AzureCloud" + } +} + +resource "azurerm_subnet_network_security_group_association" "public_subnet_nsg_association" { + subnet_id = azurerm_subnet.web-public-subnet.id + network_security_group_id = azurerm_network_security_group.public_nsg.id +} + +resource "azurerm_subnet_network_security_group_association" "private_subnet_nsg_association" { + subnet_id = azurerm_subnet.web-private-subnet.id + network_security_group_id = azurerm_network_security_group.private_nsg.id +} diff --git a/modules/common/output.tf b/modules/common/output.tf index 86e288c..ef58ed1 100644 --- a/modules/common/output.tf +++ b/modules/common/output.tf @@ -36,3 +36,24 @@ output "acme_account_key" { output "tiknet_virtual_network_name" { value = azurerm_virtual_network.tiknet.name } +output "tiknet_virtual_network_id" { + value = azurerm_virtual_network.tiknet.id +} +output "tiknet_public_subnet_name" { + value = azurerm_subnet.web-public-subnet.name +} +output "tiknet_public_subnet_id" { + value = azurerm_subnet.web-public-subnet.id +} +output "tiknet_private_subnet_name" { + value = azurerm_subnet.web-private-subnet.name +} +output "tiknet_private_subnet_id" { + value = azurerm_subnet.web-private-subnet.id +} +output "tiknet_private_storage_subnet_name" { + value = azurerm_subnet.web-private-storage-subnet.name +} +output "tiknet_private_storage_subnet_id" { + value = azurerm_subnet.web-private-storage-subnet.id +} \ No newline at end of file diff --git a/modules/dns/root/main.tf b/modules/dns/root/main.tf index 6142678..0fe1708 100644 --- a/modules/dns/root/main.tf +++ b/modules/dns/root/main.tf @@ -25,3 +25,8 @@ resource "azurerm_dns_cname_record" "www_cname" { ttl = 300 record = azurerm_dns_zone.root_zone.name } + +resource "azurerm_private_dns_zone" "private_root_zone" { + name = var.zone_name + resource_group_name = azurerm_resource_group.dns_rg.name +} \ No newline at end of file diff --git a/modules/dns/root/output.tf b/modules/dns/root/output.tf index abe07c3..11d4331 100644 --- a/modules/dns/root/output.tf +++ b/modules/dns/root/output.tf @@ -5,3 +5,6 @@ output "resource_group_name" { output "root_zone_name" { value = azurerm_dns_zone.root_zone.name } +output "private_root_zone_name" { + value = azurerm_private_dns_zone.private_root_zone.name +} \ No newline at end of file diff --git a/modules/keyvault/main.tf b/modules/keyvault/main.tf index 8a72311..339d937 100644 --- a/modules/keyvault/main.tf +++ b/modules/keyvault/main.tf @@ -110,3 +110,13 @@ data "azurerm_key_vault_secret" "github_app_key" { key_vault_id = azurerm_key_vault.keyvault.id depends_on = [azurerm_key_vault_access_policy.admin, azurerm_key_vault_access_policy.CI] } +data "azurerm_key_vault_secret" "google_oauth_client_id" { + name = "google-oauth-client-id" + key_vault_id = azurerm_key_vault.keyvault.id + depends_on = [azurerm_key_vault_access_policy.admin, azurerm_key_vault_access_policy.CI] +} +data "azurerm_key_vault_secret" "google_oauth_client_secret" { + name = "google-oauth-client-secret" + key_vault_id = azurerm_key_vault.keyvault.id + depends_on = [azurerm_key_vault_access_policy.admin, azurerm_key_vault_access_policy.CI] +} diff --git a/modules/keyvault/output.tf b/modules/keyvault/output.tf index ec9c7a2..6fb5afa 100644 --- a/modules/keyvault/output.tf +++ b/modules/keyvault/output.tf @@ -1,30 +1,49 @@ output "ilmo_auth_jwt_secret" { - value = data.azurerm_key_vault_secret.ilmo_auth_jwt_secret.value + value = data.azurerm_key_vault_secret.ilmo_auth_jwt_secret.value + sensitive = true } output "ilmo_edit_token_secret" { - value = data.azurerm_key_vault_secret.ilmo_edit_token_secret.value + value = data.azurerm_key_vault_secret.ilmo_edit_token_secret.value + sensitive = true } output "ilmo_mailgun_api_key" { - value = data.azurerm_key_vault_secret.ilmo_mailgun_api_key.value + value = data.azurerm_key_vault_secret.ilmo_mailgun_api_key.value + sensitive = true } output "ilmo_mailgun_domain" { - value = data.azurerm_key_vault_secret.ilmo_mailgun_domain.value + value = data.azurerm_key_vault_secret.ilmo_mailgun_domain.value + sensitive = true } output "tikjob_ghost_mail_username" { - value = data.azurerm_key_vault_secret.tikjob_ghost_mail_username.value + value = data.azurerm_key_vault_secret.tikjob_ghost_mail_username.value + sensitive = true } output "tikjob_ghost_mail_password" { - value = data.azurerm_key_vault_secret.tikjob_ghost_mail_password.value + value = data.azurerm_key_vault_secret.tikjob_ghost_mail_password.value + sensitive = true } + output "tenttiarkisto_django_secret_key" { - value = data.azurerm_key_vault_secret.tenttiarkisto_django_secret_key.value + value = data.azurerm_key_vault_secret.tenttiarkisto_django_secret_key.value + sensitive = true } output "github_app_key" { - value = data.azurerm_key_vault_secret.github_app_key.value + value = data.azurerm_key_vault_secret.github_app_key.value + sensitive = true +} + +output "google_oauth_client_id" { + value = data.azurerm_key_vault_secret.google_oauth_client_id.value + sensitive = true +} + +output "google_oauth_client_secret" { + value = data.azurerm_key_vault_secret.google_oauth_client_secret.value + sensitive = true } diff --git a/modules/web/app/dns.tf b/modules/web/app/dns.tf new file mode 100644 index 0000000..a30a942 --- /dev/null +++ b/modules/web/app/dns.tf @@ -0,0 +1,107 @@ + + +terraform { + required_providers { + acme = { + source = "vancluever/acme" + version = "2.19.0" + } + } +} + +locals { + fqdn = "${var.subdomain}.${var.root_zone_name}" +} +# A record for the web app +resource "azurerm_dns_a_record" "tikweb_a" { + name = var.subdomain + resource_group_name = var.dns_resource_group_name + zone_name = var.root_zone_name + ttl = 300 + records = data.dns_a_record_set.tikweb_dns_fetch.addrs +} + +# Azure verification key +resource "azurerm_dns_txt_record" "tikweb_asuid" { + name = "asuid.${var.subdomain}" + resource_group_name = var.dns_resource_group_name + zone_name = var.root_zone_name + ttl = 300 + + record { + value = azurerm_linux_web_app.frontend.custom_domain_verification_id + } +} + + +# Reporting-only DMARC policy +resource "azurerm_dns_txt_record" "tikweb_dmarc" { + name = "_dmarc.${var.subdomain}" + resource_group_name = var.dns_resource_group_name + zone_name = var.root_zone_name + ttl = 300 + + record { + value = "v=DMARC1;p=none;sp=none;rua=mailto:dmarc@tietokilta.fi!10m;ruf=mailto:dmarc@tietokilta.fi!10m" + } +} +resource "azurerm_app_service_custom_hostname_binding" "tikweb_hostname_binding" { + hostname = local.fqdn + app_service_name = azurerm_linux_web_app.frontend.name + resource_group_name = var.resource_group_name + + # Deletion may need manual work. + # https://github.com/hashicorp/terraform-provider-azurerm/issues/11231 + # TODO: Add dependencies for creation + depends_on = [ + azurerm_dns_a_record.tikweb_a, + azurerm_dns_txt_record.tikweb_asuid + ] +} +resource "random_password" "tikweb_cert_password" { + length = 48 + special = false +} + +resource "acme_certificate" "tikweb_acme_cert" { + account_key_pem = var.acme_account_key + common_name = local.fqdn + key_type = "2048" # RSA + certificate_p12_password = random_password.tikweb_cert_password.result + + dns_challenge { + provider = "azure" + config = { + AZURE_RESOURCE_GROUP = var.dns_resource_group_name + AZURE_ZONE_NAME = var.root_zone_name + } + } +} + +resource "azurerm_app_service_certificate" "tikweb_cert" { + name = "tikweb-cert-${terraform.workspace}" + resource_group_name = var.resource_group_name + location = var.resource_group_location + pfx_blob = acme_certificate.tikweb_acme_cert.certificate_p12 + password = acme_certificate.tikweb_acme_cert.certificate_p12_password +} + +resource "azurerm_app_service_certificate_binding" "tikweb_cert_binding" { + certificate_id = azurerm_app_service_certificate.tikweb_cert.id + hostname_binding_id = azurerm_app_service_custom_hostname_binding.tikweb_hostname_binding.id + ssl_state = "SniEnabled" +} + +# https://github.com/hashicorp/terraform-provider-azurerm/issues/14642#issuecomment-1084728235 +# Currently, the azurerm provider doesn't give us the IP address, so we need to fetch it ourselves. +data "dns_a_record_set" "tikweb_dns_fetch" { + host = azurerm_linux_web_app.frontend.default_hostname +} + +resource "azurerm_dns_cname_record" "tikweb_cdn_cname_record" { + name = "cdn.${var.subdomain}" + resource_group_name = var.dns_resource_group_name + zone_name = var.root_zone_name + ttl = 300 + record = azurerm_cdn_endpoint.next-cdn-endpoint.fqdn +} diff --git a/modules/web/app/main.tf b/modules/web/app/main.tf new file mode 100644 index 0000000..46fd6c7 --- /dev/null +++ b/modules/web/app/main.tf @@ -0,0 +1,135 @@ +locals { + payload_port = 3001 +} +resource "random_password" "revalidation_key" { + length = 32 + special = true +} +resource "azurerm_linux_web_app" "frontend" { + name = "tikweb-frontend-${terraform.workspace}" + location = var.resource_group_location + resource_group_name = var.resource_group_name + service_plan_id = var.app_service_plan_id + virtual_network_subnet_id = var.public_subnet_id + public_network_access_enabled = true + site_config { + application_stack { + docker_registry_url = "https://ghcr.io" + docker_image_name = "tietokilta/web:latest" + } + } + logs { + http_logs { + file_system { + retention_in_days = 7 + retention_in_mb = 100 + } + } + } + app_settings = { + WEBSITES_PORT = 3000 + PORT = 3000 + NEXT_REVALIDATION_KEY = random_password.revalidation_key.result + SERVER_URL = "http://${azurerm_linux_web_app.cms.default_hostname}:${local.payload_port}" + } +} +resource "random_password" "payload_secret" { + length = 32 + special = true +} +resource "azurerm_linux_web_app" "cms" { + name = "tikweb-cms-${terraform.workspace}" + location = var.resource_group_location + resource_group_name = var.resource_group_name + service_plan_id = var.app_service_plan_id + virtual_network_subnet_id = var.private_subnet_id + public_network_access_enabled = false + site_config { + + application_stack { + docker_registry_url = "https://ghcr.io" + docker_image_name = "tietokilta/cms:latest" + } + } + logs { + http_logs { + file_system { + retention_in_days = 7 + retention_in_mb = 100 + } + } + } + app_settings = { + PUBLIC_FRONTEND_URL = "https://${local.fqdn}" + PAYLOAD_MONGO_CONNECTION_STRING = var.mongo_connection_string + PAYLOAD_SECRET = random_password.payload_secret.result + PAYLOAD_PORT = local.payload_port + AZURE_STORAGE_CONNECTION_STRING = var.storage_connection_string + AZURE_STORAGE_CONTAINER_NAME = var.storage_container_name + AZURE_STORAGE_ACCOUNT_BASEURL = var.storage_account_base_url + GOOGLE_OAUTH_CLIENT_ID = var.google_oauth_client_id + GOOGLE_OAUTH_CLIENT_SECRET = var.google_oauth_client_secret + } +} + +resource "azurerm_cdn_profile" "cdn" { + name = "cdn-${terraform.workspace}" + location = var.resource_group_location + resource_group_name = var.resource_group_name + sku = "Standard_Microsoft" +} + +resource "azurerm_cdn_endpoint" "next-cdn-endpoint" { + name = "next-cdn-endpoint-${terraform.workspace}" + profile_name = azurerm_cdn_profile.cdn.name + location = var.resource_group_location + resource_group_name = var.resource_group_name + is_http_allowed = false + is_https_allowed = true + # TODO: Add custom domain support + origin { + name = "tikweb-frontend-${terraform.workspace}" + host_name = azurerm_linux_web_app.frontend.default_hostname + } + + global_delivery_rule { + cache_expiration_action { + behavior = "Override" + duration = "10.00:00:00" + } + } + + delivery_rule { + name = "NextStaticAssets" + order = 1 + + request_uri_condition { + operator = "BeginsWith" + match_values = [ + "/_next/static/" + ] + } + cache_expiration_action { + behavior = "Override" + duration = "10.00:00:00" + } + } +} + +resource "azurerm_cdn_endpoint_custom_domain" "tikweb_cdn_domain" { + name = "web-cdn-${terraform.workspace}-domain" + cdn_endpoint_id = azurerm_cdn_endpoint.next-cdn-endpoint.id + host_name = "cdn.${var.subdomain}.${var.root_zone_name}" + + cdn_managed_https { + certificate_type = "Dedicated" + protocol_type = "ServerNameIndication" + tls_version = "TLS12" + } + + # Deletion needs manual work. Hashicorp seems uninterested in fixing. + # https://github.com/hashicorp/terraform-provider-azurerm/issues/11231 + depends_on = [ + azurerm_dns_cname_record.tikweb_cdn_cname_record + ] +} diff --git a/modules/web/app/outputs.tf b/modules/web/app/outputs.tf new file mode 100644 index 0000000..e86c5a3 --- /dev/null +++ b/modules/web/app/outputs.tf @@ -0,0 +1,3 @@ +output "fqdn" { + value = local.fqdn +} diff --git a/modules/web/app/variables.tf b/modules/web/app/variables.tf new file mode 100644 index 0000000..144879e --- /dev/null +++ b/modules/web/app/variables.tf @@ -0,0 +1,61 @@ +variable "resource_group_name" { + type = string +} + +variable "resource_group_location" { + type = string +} + +// Certs + +variable "acme_account_key" { + type = string + sensitive = true +} + +variable "dns_resource_group_name" { + type = string +} +variable "subdomain" { + type = string +} + +variable "root_zone_name" { + type = string +} + + +variable "app_service_plan_id" { + type = string +} +variable "public_subnet_id" { + type = string +} + +variable "private_subnet_id" { + type = string +} +variable "mongo_connection_string" { + type = string + sensitive = true +} +variable "google_oauth_client_id" { + type = string + sensitive = true +} +variable "google_oauth_client_secret" { + type = string + sensitive = true +} +variable "storage_connection_string" { + type = string + sensitive = true +} + +variable "storage_container_name" { + type = string +} + +variable "storage_account_base_url" { + type = string +} diff --git a/modules/web/storage/main.tf b/modules/web/storage/main.tf new file mode 100644 index 0000000..403d111 --- /dev/null +++ b/modules/web/storage/main.tf @@ -0,0 +1,87 @@ +resource "azurerm_cosmosdb_account" "db_account" { + name = "tikweb-cosmosdb-${terraform.workspace}" + location = var.resource_group_location + resource_group_name = var.resource_group_name + offer_type = "Standard" + kind = "MongoDB" + mongo_server_version = "4.2" + enable_free_tier = true + capabilities { + name = "EnableMongo" + } + public_network_access_enabled = false + consistency_policy { + consistency_level = "Session" + } + + geo_location { + location = var.resource_group_location + failover_priority = 0 + } + is_virtual_network_filter_enabled = true + virtual_network_rule { + id = var.private_subnet_id + } + capacity { + # CosmosDB free tier allows for a throughput of 1000 at max + total_throughput_limit = 1000 + } + backup { + retention_in_hours = 168 + interval_in_minutes = 1440 + type = "Periodic" + } +} +resource "azurerm_private_endpoint" "tikweb_db_private_endpoint" { + name = "tikweb-db-private-endpoint-${terraform.workspace}" + location = var.resource_group_location + resource_group_name = var.resource_group_name + subnet_id = var.private_storage_subnet_id + + private_service_connection { + name = "tikweb-db-private-endpoint-connection-${terraform.workspace}" + private_connection_resource_id = azurerm_cosmosdb_account.db_account.id + is_manual_connection = false + subresource_names = ["MongoDB"] + } +} + +resource "azurerm_cosmosdb_mongo_database" "db" { + name = "cms-${terraform.workspace}" + resource_group_name = var.resource_group_name + account_name = azurerm_cosmosdb_account.db_account.name + autoscale_settings { + # CosmosDB free tier allows for a throughput of 1000 at max + max_throughput = 1000 + } +} + +resource "azurerm_storage_account" "tikweb_storage_account" { + name = "tikwebstorage${terraform.workspace}" + resource_group_name = var.resource_group_name + location = var.resource_group_location + account_tier = "Standard" + account_replication_type = "LRS" + allow_nested_items_to_be_public = false + min_tls_version = "TLS1_2" +} +resource "azurerm_private_endpoint" "tikweb_storage_private_endpoint" { + name = "tikweb-storage-private-endpoint-${terraform.workspace}" + location = var.resource_group_location + resource_group_name = var.resource_group_name + subnet_id = var.private_storage_subnet_id + + private_service_connection { + name = "tikweb-storage-private-endpoint-connection-${terraform.workspace}" + private_connection_resource_id = azurerm_storage_account.tikweb_storage_account.id + is_manual_connection = false + subresource_names = ["blob"] + } +} + +resource "azurerm_storage_container" "tikweb_media" { + name = "media-${terraform.workspace}" + storage_account_name = azurerm_storage_account.tikweb_storage_account.name + container_access_type = "private" + depends_on = [azurerm_storage_account.tikweb_storage_account] +} diff --git a/modules/web/storage/output.tf b/modules/web/storage/output.tf new file mode 100644 index 0000000..eb5ecae --- /dev/null +++ b/modules/web/storage/output.tf @@ -0,0 +1,21 @@ +// Mongo +output "mongo_connection_string" { + value = "${azurerm_cosmosdb_account.db_account.primary_mongodb_connection_string}/${azurerm_cosmosdb_mongo_database.db.name}" + sensitive = true +} + +// Storage + +output "storage_account_name" { + value = azurerm_storage_account.tikweb_storage_account.name +} +output "storage_connection_string" { + value = azurerm_storage_account.tikweb_storage_account.primary_connection_string + sensitive = true +} +output "storage_container_name" { + value = azurerm_storage_container.tikweb_media.name +} +output "storage_account_base_url" { + value = azurerm_storage_account.tikweb_storage_account.primary_blob_endpoint +} diff --git a/modules/web/storage/variables.tf b/modules/web/storage/variables.tf new file mode 100644 index 0000000..2463244 --- /dev/null +++ b/modules/web/storage/variables.tf @@ -0,0 +1,23 @@ +variable "resource_group_name" { + type = string +} + +variable "resource_group_location" { + type = string +} + +variable "private_subnet_name" { + type = string +} +variable "private_subnet_id" { + type = string +} +variable "private_root_zone_name" { + type = string +} +variable "virtual_network_id" { + type = string +} +variable "private_storage_subnet_id" { + type = string +} \ No newline at end of file