diff --git a/terraform/main.tf b/terraform/main.tf index 240c545f..f42b0903 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -1,24 +1,11 @@ -terraform { - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "3.43.0" - } - azurecaf = { - source = "aztfmod/azurecaf" - version = "1.2.16" - } - azuread = { - source = "hashicorp/azuread" - version = "2.33.0" +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false } } } -provider "azurerm" { - features {} -} - locals { // If an environment is set up (dev, test, prod...), it is used in the application name environment = var.environment == "" ? "dev" : var.environment @@ -84,7 +71,17 @@ module "key-vault" { application_name = var.application_name environment = local.environment location = var.location - + + virtual_network_id = module.network.vnet_id + private_endpoint_subnet_id = module.network.private_endpoint_subnet_id + + network_acls = { + bypass = "None" + default_action = "Deny" + ip_rules = [local.myip] + virtual_network_subnet_ids = [module.network.app_subnet_id] + } + azure_ad_tenant_id = data.azurerm_client_config.current.tenant_id } diff --git a/terraform/modules/key-vault/main.tf b/terraform/modules/key-vault/main.tf index d8c35dff..22a93229 100644 --- a/terraform/modules/key-vault/main.tf +++ b/terraform/modules/key-vault/main.tf @@ -23,8 +23,52 @@ resource "azurerm_key_vault" "application" { sku_name = "standard" + dynamic "network_acls" { + for_each = var.network_acls != null ? [true] : [] + content { + bypass = var.network_acls.bypass + default_action = var.network_acls.default_action + ip_rules = var.network_acls.ip_rules + virtual_network_subnet_ids = var.network_acls.virtual_network_subnet_ids + } + } + tags = { "environment" = var.environment "application-name" = var.application_name } +} + +# Azure Private DNS provides a reliable, secure DNS service to manage and +# resolve domain names in a virtual network without the need to add a custom DNS solution +# https://docs.microsoft.com/en-us/azure/dns/private-dns-privatednszone +resource "azurerm_private_dns_zone" "key_vault_dns_zone" { + name = "privatelink.vaultcore.azure.net" + resource_group_name = var.resource_group +} + +resource "azurerm_private_dns_zone_virtual_network_link" "virtual_network_link_redis" { + name = "${var.application_name}KeyVaultVnetZone.com" + private_dns_zone_name = azurerm_private_dns_zone.key_vault_dns_zone.name + virtual_network_id = var.virtual_network_id + resource_group_name = var.resource_group +} + +resource "azurerm_private_endpoint" "keyvault_private_endpoint" { + name = format("%s-private-endpoint", azurecaf_name.key_vault.result) + location = var.location + resource_group_name = var.resource_group + subnet_id = var.private_endpoint_subnet_id + + private_dns_zone_group { + name = "privatednsrediszonegroup" + private_dns_zone_ids = [azurerm_private_dns_zone.key_vault_dns_zone.id] + } + + private_service_connection { + name = "keyvault-privatelink" + is_manual_connection = false + private_connection_resource_id = azurerm_key_vault.application.id + subresource_names = ["vault"] + } } \ No newline at end of file diff --git a/terraform/modules/key-vault/variables.tf b/terraform/modules/key-vault/variables.tf index d59910b8..c5f3db31 100644 --- a/terraform/modules/key-vault/variables.tf +++ b/terraform/modules/key-vault/variables.tf @@ -22,4 +22,25 @@ variable "environment" { variable "location" { type = string description = "The Azure region where all resources in this example should be created" -} \ No newline at end of file +} + +variable "network_acls" { + description = "Network rules to apply to key vault." + type = object({ + bypass = string + default_action = string + ip_rules = list(string) + virtual_network_subnet_ids = list(string) + }) + default = null +} + +variable "virtual_network_id" { + type = string + description = "The id of the vnet with the address space of 10.0.0.0/16" +} + +variable "private_endpoint_subnet_id" { + type = string + description = "The id of the subnet to use for private endpoint" +} diff --git a/terraform/modules/network/main.tf b/terraform/modules/network/main.tf index 14faf0ee..e8997d99 100644 --- a/terraform/modules/network/main.tf +++ b/terraform/modules/network/main.tf @@ -33,7 +33,9 @@ resource "azurerm_subnet" "app_subnet" { virtual_network_name = azurerm_virtual_network.network.name address_prefixes = ["10.0.1.0/24"] - service_endpoints = [ "Microsoft.Storage" ] + private_endpoint_network_policies_enabled = true + + service_endpoints = [ "Microsoft.Storage", "Microsoft.KeyVault"] delegation { name = "app-service" @@ -44,7 +46,7 @@ resource "azurerm_subnet" "app_subnet" { } } -# Create the private endpoint subnet +# Create the private endpoint subnet. Private endpoint cannot be created in a subnet that's delegated resource "azurecaf_name" "private_endpoint_subnet_name" { name = var.application_name resource_type = "azurerm_subnet" @@ -82,4 +84,4 @@ resource "azurerm_subnet" "postgresql_subnet" { ] } } -} \ No newline at end of file +} diff --git a/terraform/modules/network/outputs.tf b/terraform/modules/network/outputs.tf index 3dd9c101..17b038f6 100644 --- a/terraform/modules/network/outputs.tf +++ b/terraform/modules/network/outputs.tf @@ -8,16 +8,16 @@ output "postgresql_subnet_id" { description = "The id of the postgresql subnet" } -output "private_endpoint_subnet_id" { - value = azurerm_subnet.private_endpoint_subnet.id - description = "The id of the postgresql subnet" -} - output "app_subnet_id" { value = azurerm_subnet.app_subnet.id description = "The id of the application subnet" } +output "private_endpoint_subnet_id" { + value = azurerm_subnet.private_endpoint_subnet.id + description = "The id of the subnet used for private endpoints" +} + #output "storage_subnet_id" { # value = azurerm_subnet.storage_subnet.id # description = "The id of the storage subnet" diff --git a/terraform/versions.tf b/terraform/versions.tf new file mode 100644 index 00000000..16d2c6b3 --- /dev/null +++ b/terraform/versions.tf @@ -0,0 +1,16 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "3.43.0" + } + azuread = { + source = "hashicorp/azuread" + version = "2.33.0" + } + azurecaf = { + source = "aztfmod/azurecaf" + version = "1.2.16" + } + } +} \ No newline at end of file