Skip to content

Commit

Permalink
new web infra
Browse files Browse the repository at this point in the history
  • Loading branch information
kahlstrm committed Jan 18, 2024
1 parent 723e02b commit 51df61b
Show file tree
Hide file tree
Showing 14 changed files with 616 additions and 10 deletions.
29 changes: 28 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,33 @@ 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
}
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"
Expand All @@ -126,7 +153,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
Expand Down
104 changes: 103 additions & 1 deletion modules/common/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,110 @@ resource "acme_registration" "acme_reg" {
}

resource "azurerm_virtual_network" "tiknet" {
name = "tiknet-${var.env_name}"
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"]
}
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"]
}
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
}
15 changes: 15 additions & 0 deletions modules/common/output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,18 @@ 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
}
5 changes: 5 additions & 0 deletions modules/dns/root/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
3 changes: 3 additions & 0 deletions modules/dns/root/output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 10 additions & 0 deletions modules/keyvault/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
35 changes: 27 additions & 8 deletions modules/keyvault/output.tf
Original file line number Diff line number Diff line change
@@ -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
}
107 changes: 107 additions & 0 deletions modules/web/app/dns.tf
Original file line number Diff line number Diff line change
@@ -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:[email protected]!10m;ruf=mailto:[email protected]!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
}
Loading

0 comments on commit 51df61b

Please sign in to comment.