diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index ab581b2..4f8a08b 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,23 +2,22 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/azure/azapi" { - version = "1.0.0" - constraints = "1.0.0" + version = "1.13.1" + constraints = "1.13.1" hashes = [ - "h1:/yVPJkiudd2Ls3U3aJkalf+WgLLU+eID7hskCXbQb6A=", - "h1:rR1wGOj94gwaZ6D1PTQAKTIT5Kxg2F/9rEKB3cZR/Y0=", - "zh:01a33aaefe4d185e70d926103eeb0ac9fefeadf750f69c5977ead2ae02e0b038", - "zh:1ce767851be07e432b4cdde91b40beef84f030432bb7b431ffda85b89305414d", - "zh:1cf15bc8430377091c06373c74a68ce61a9f36dd1455929a64e8083332f2c291", - "zh:4372f59b2761b3ae4b59d59f978af547cd8fae44d2b2e5baa91735b0ea3b16e2", - "zh:6602e2aae7937456418f53372d7139d2f56aea5e46dfd46634f9b202988178c0", - "zh:6f0945ee6ae05cbd708c10ee7b0f8c987032e35122a01d661188538f7548e59f", - "zh:6fc5e5017b8f87aff48732cc619f1295175913e3c1c039a170e8f0100a8233a2", - "zh:740f6c339f28406988204af6fadc9e58c754a22f234902b34c1f6d54421476c2", - "zh:7f003da3b64cb5129627b96a5eb0a03113853a0b17fd4cb77bd505fd27a8ca0b", - "zh:a1ed7aa209cdee91b013691ddb61d77eb3d840f9cba2f4c8b923ba80823c5912", - "zh:d6dad27af147a127027a8aa08a259f6dc418b09f842620e56e5db85547b1b090", - "zh:e67ddb150ff40cf9453fd56f47c2ac657ede1c1861b4d2f9009e98bddfc345b2", + "h1:Q10vF78s0i71/CfRYbeoRLAWuJrat2kxIrHK9/yaEYk=", + "zh:1f2aceddd67ceeb82a75c2f15dc01e54781e9aed5968507dbc29590c165b2e2b", + "zh:397f0bfbac899d48e23cecf38d362c27562150aa20b19157b5bd370b8e6801ee", + "zh:652263b7d00623684e29ef7b8ff285a17c5bd7cc8ba7d22967c66d0b3a3c568a", + "zh:652c53320a41434942877515780296a1509be03f32d54e60178f39200f960a67", + "zh:666426faf686401e54ec09fe06e9d7c06a6455ec398764f70558440c73aeb7f9", + "zh:6aa91ae8ba78f2494f99b4c99e66d15ed0b14d735cd1f77adc12ff9dfa075807", + "zh:a529e5a13c37d1805c469227f08cdbe7527d04dd64d18709d26627c6a0b588b1", + "zh:a589c049205e8e5bf94a13d56b28f400d908ad27e13e16df64408ee82eb8a0ff", + "zh:a9a50defdee230f315f74be6c77ff104fe2610a1b3ad6b87326f555e80d13b18", + "zh:ba49ef70d96e13795e2dbffd6cb2ff976dfe84e0373a5971ebe3b4c9c9b7af60", + "zh:d3ed50efe5f8c80d3d7d464ab9a13ccf82440d871c9ce3032ce476845364c6b9", + "zh:e3eb48ee8c36ee4f81850d8a21fc59b81886c729d7c3b7adece4a25f355bed2f", ] } @@ -63,41 +62,41 @@ provider "registry.terraform.io/hashicorp/azurerm" { } provider "registry.terraform.io/hashicorp/http" { - version = "3.4.0" - constraints = ">= 3.0.1" + version = "3.4.5" + constraints = ">= 3.4.0" hashes = [ - "h1:ZWoE0ARqUMnujHu62cMkmjF2+FoWwUn9YbHjiKPq0e8=", - "zh:56712497a87bc4e91bbaf1a5a2be4b3f9cfa2384baeb20fc9fad0aff8f063914", - "zh:6661355e1090ebacab16a40ede35b029caffc279d67da73a000b6eecf0b58eba", - "zh:67b92d343e808b92d7e6c3bbcb9b9d5475fecfed0836963f7feb9d9908bd4c4f", + "h1:o4H2Oe0OM3M2YNokKJzvZoBnDAw6yuLJXBO7RSEhL/E=", + "zh:2072006c177efc101471f3d5eb8e1d8e6c68778cbfd6db3d3f22f59cfe6ce6ae", + "zh:3ac4cc0efe11ee054300769cfcc37491433937a8824621d1f8f7a18e7401da87", + "zh:63997e5457c9ddf9cfff17bd7bf9f083cbeff3105452045662109dd6be499ef9", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:86ebb9be9b685c96dbb5c024b55d87526d57a4b127796d6046344f8294d3f28e", - "zh:902be7cfca4308cba3e1e7ba6fc292629dfd150eb9a9f054a854fa1532b0ceba", - "zh:9ba26e0215cd53b21fe26a0a98c007de1348b7d13a75ae3cfaf7729e0f2c50bb", - "zh:a195c941e1f1526147134c257ff549bea4c89c953685acd3d48d9de7a38f39dc", - "zh:a7967b3d2a8c3e7e1dc9ae381ca753268f9fce756466fe2fc9e414ca2d85a92e", - "zh:bde56542e9a093434d96bea21c341285737c6d38fea2f05e12ba7b333f3e9c05", - "zh:c0306f76903024c497fd01f9fd9bace5854c263e87a97bc2e89dcc96d35ca3cc", - "zh:f9335a6c336171e85f8e3e99c3d31758811a19aeb21fa8c9013d427e155ae2a9", + "zh:826819bb8ab7d6e3095f597083d5b1ab93d1854312b9e1b6c18288fff9664f34", + "zh:8ad74e7d8ec2e226a73d49c7c317108f61a4cb803972fb3f945d1709d5115fcd", + "zh:a609ca9e0c91d250ac80295e39d5f524e8c0872d33ba8fde3c3e41893b4b015d", + "zh:ae07d19babc452f63f6a6511b944990e819dc20687b6c8f01d1676812f5ada53", + "zh:b7c827dc32a1a5d77185a78cd391b01217894b384f58169f98a96d683730d8ce", + "zh:d045e3db9f5e39ce78860d3fd94e04604fcbe246f6fe346ee50a971f936e9ccd", + "zh:ec28f9b52c74edd47eebbb5c254a6df5706360cde5ccd65097976efca23a2977", + "zh:f24982eaa7d34fd66554c3cf94873713a0dff14da9ea4c4be0cc76f1a6146d59", ] } provider "registry.terraform.io/hashicorp/random" { - version = "3.6.0" - constraints = ">= 3.1.0" + version = "3.6.3" + constraints = ">= 3.6.0" hashes = [ - "h1:t0mRdJzegohRKhfdoQEJnv3JRISSezJRblN0HIe67vo=", - "zh:03360ed3ecd31e8c5dac9c95fe0858be50f3e9a0d0c654b5e504109c2159287d", - "zh:1c67ac51254ba2a2bb53a25e8ae7e4d076103483f55f39b426ec55e47d1fe211", - "zh:24a17bba7f6d679538ff51b3a2f378cedadede97af8a1db7dad4fd8d6d50f829", - "zh:30ffb297ffd1633175d6545d37c2217e2cef9545a6e03946e514c59c0859b77d", - "zh:454ce4b3dbc73e6775f2f6605d45cee6e16c3872a2e66a2c97993d6e5cbd7055", + "h1:+UItZOLue/moJfnI3tqZBQbXUYR4ZnqPYfJDJPgLZy0=", + "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", + "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", + "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", + "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", + "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", + "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:91df0a9fab329aff2ff4cf26797592eb7a3a90b4a0c04d64ce186654e0cc6e17", - "zh:aa57384b85622a9f7bfb5d4512ca88e61f22a9cea9f30febaa4c98c68ff0dc21", - "zh:c4a3e329ba786ffb6f2b694e1fd41d413a7010f3a53c20b432325a94fa71e839", - "zh:e2699bc9116447f96c53d55f2a00570f982e6f9935038c3810603572693712d0", - "zh:e747c0fd5d7684e5bfad8aa0ca441903f15ae7a98a737ff6aca24ba223207e2c", - "zh:f1ca75f417ce490368f047b63ec09fd003711ae48487fba90b4aba2ccf71920e", + "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", + "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", + "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", + "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", + "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", ] } diff --git a/main.tf b/main.tf index 4d16aba..377db37 100644 --- a/main.tf +++ b/main.tf @@ -24,6 +24,7 @@ locals { sql_name = "${var.sql_name}-${local.name_sufix}" postgresql_name = "${var.postgresql_name}-${local.name_sufix}" postgresql_flexible_server_name = "${var.postgresql_name}-fs-${local.name_sufix}" + apim_name = "${var.apim_name}-${local.name_sufix}" } resource "azurerm_resource_group" "rg" { @@ -57,6 +58,7 @@ module "vnet" { contoso_address_prefixes = var.contoso_address_prefixes contoso_tests_address_prefixes = var.contoso_tests_address_prefixes flexible_server_address_prefixes = var.flexible_server_address_prefixes + apim_address_prefixes = var.apim_address_prefixes tags = var.tags } @@ -91,6 +93,7 @@ module "nsg" { module.vnet.subnet_jumpbox_id, module.vnet.subnet_hub_jumpbox_id, module.vnet.subnet_contoso_id, + module.vnet.subnet_apim_id, ] aci_subnet_ids = [ module.vnet.subnet_dns_id, @@ -150,7 +153,7 @@ module "firewall" { firewall_subnet_id = module.vnet.subnet_firewall_id gateway_address_prefixes = module.vnet.subnet_gateway_address_prefixes dns_address_prefixes = module.vnet.subnet_dns_address_prefixes - contoso_address_prefixes = module.vnet.vnet_contoso_address_space + contoso_address_prefixes = concat(module.vnet.vnet_contoso_address_space, module.vnet.subnet_apim_address_prefixes) tags = var.tags depends_on = [ module.nsg, @@ -172,6 +175,7 @@ module "udr" { contoso_address_prefixes = module.vnet.vnet_contoso_address_space gateway_subnet_id = module.vnet.subnet_gateway_id spoke_address_prefixes = module.vnet.vnet_spoke_address_space + apim_subnet_id = module.vnet.subnet_apim_id enable_gateway_route_to_firewall = var.enable_gateway_route_to_firewall tags = var.tags } @@ -486,3 +490,24 @@ module "onpremises_tests" { module.udr ] } + +module "apim" { + count = var.enable_apim ? 1 : 0 + source = "./modules/apim" + location = azurerm_resource_group.rg.location + resource_group_id = azurerm_resource_group.rg.id + resource_group_name = azurerm_resource_group.rg.name + apim_name = local.apim_name + apim_subnet_id = module.vnet.subnet_apim_id + publisher_name = var.publisher_name + publisher_email = var.publisher_email + appi_resource_id = var.enable_apim ? module.function[0].appi_id : "" + appi_instrumentation_key = var.enable_apim ? module.function[0].appi_key : "" + function_fqdn = var.deploy_function ? module.function[0].fqdn : "" + + depends_on = [ + module.app_gateway, + module.app_gateway_tcp, + module.udr + ] +} diff --git a/modules/apim/external_api.tf b/modules/apim/external_api.tf new file mode 100644 index 0000000..3b29471 --- /dev/null +++ b/modules/apim/external_api.tf @@ -0,0 +1,60 @@ + +resource "azurerm_api_management_backend" "backend" { + name = "me" + resource_group_name = var.resource_group_name + api_management_name = azapi_resource.apim.name + protocol = "http" + url = "https://carlos.mendible.com" +} + +resource "azurerm_api_management_api" "me" { + name = "me" + resource_group_name = var.resource_group_name + api_management_name = azapi_resource.apim.name + revision = "1" + display_name = "me" + path = "me" + protocols = ["https"] + + subscription_required = false +} + +resource "azurerm_api_management_api_operation" "me_operation" { + operation_id = "me" + api_name = azurerm_api_management_api.me.name + api_management_name = azapi_resource.apim.name + resource_group_name = var.resource_group_name + display_name = "GET" + method = "GET" + url_template = "/" + description = "me" + + response { + status_code = 200 + } +} + +resource "azurerm_api_management_api_operation_policy" "me_policy" { + api_name = azurerm_api_management_api_operation.me_operation.api_name + api_management_name = azurerm_api_management_api_operation.me_operation.api_management_name + resource_group_name = azurerm_api_management_api_operation.me_operation.resource_group_name + operation_id = azurerm_api_management_api_operation.me_operation.operation_id + + xml_content = < + + + + + + + + + + + + + + +XML +} diff --git a/modules/apim/internal_api.tf b/modules/apim/internal_api.tf new file mode 100644 index 0000000..d61b4a7 --- /dev/null +++ b/modules/apim/internal_api.tf @@ -0,0 +1,60 @@ + +resource "azurerm_api_management_backend" "fucntion_backend" { + name = "function" + resource_group_name = var.resource_group_name + api_management_name = azapi_resource.apim.name + protocol = "http" + url = "https://${var.function_fqdn}" +} + +resource "azurerm_api_management_api" "function" { + name = "function" + resource_group_name = var.resource_group_name + api_management_name = azapi_resource.apim.name + revision = "1" + display_name = "function" + path = "function" + protocols = ["https"] + + subscription_required = false +} + +resource "azurerm_api_management_api_operation" "function_operation" { + operation_id = "function" + api_name = azurerm_api_management_api.function.name + api_management_name = azapi_resource.apim.name + resource_group_name = var.resource_group_name + display_name = "GET" + method = "GET" + url_template = "/" + description = "function" + + response { + status_code = 200 + } +} + +resource "azurerm_api_management_api_operation_policy" "function_policy" { + api_name = azurerm_api_management_api_operation.function_operation.api_name + api_management_name = azurerm_api_management_api_operation.function_operation.api_management_name + resource_group_name = azurerm_api_management_api_operation.function_operation.resource_group_name + operation_id = azurerm_api_management_api_operation.function_operation.operation_id + + xml_content = < + + + + + + + + + + + + + + +XML +} diff --git a/modules/apim/main.tf b/modules/apim/main.tf new file mode 100644 index 0000000..435dd7f --- /dev/null +++ b/modules/apim/main.tf @@ -0,0 +1,46 @@ +locals { + logger_name = "openai-appi-logger" +} + +resource "azapi_resource" "apim" { + type = "Microsoft.ApiManagement/service@2023-03-01-preview" + name = var.apim_name + parent_id = var.resource_group_id + location = var.location + identity { + type = "SystemAssigned" + } + schema_validation_enabled = false # requiered for now + body = { + sku = { + name = "StandardV2" + capacity = 1 + } + zones = [] + properties = { + publisherEmail = var.publisher_email + publisherName = var.publisher_name + apiVersionConstraint = {} + developerPortalStatus = "Disabled" + virtualNetworkType = "External" + virtualNetworkConfiguration = { + subnetResourceId = var.apim_subnet_id + } + } + } + response_export_values = [ + "identity.principalId", + "properties.gatewayUrl" + ] +} + +resource "azurerm_api_management_logger" "appi_logger" { + name = local.logger_name + api_management_name = azapi_resource.apim.name + resource_group_name = var.resource_group_name + resource_id = var.appi_resource_id + + application_insights { + instrumentation_key = var.appi_instrumentation_key + } +} diff --git a/modules/apim/providers.tf b/modules/apim/providers.tf new file mode 100644 index 0000000..c80c775 --- /dev/null +++ b/modules/apim/providers.tf @@ -0,0 +1,10 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + } + azapi = { + source = "azure/azapi" + } + } +} diff --git a/modules/apim/variables.tf b/modules/apim/variables.tf new file mode 100644 index 0000000..4ef1f32 --- /dev/null +++ b/modules/apim/variables.tf @@ -0,0 +1,10 @@ +variable "resource_group_name" {} +variable "resource_group_id" {} +variable "location" {} +variable "apim_name" {} +variable "publisher_name" {} +variable "publisher_email" {} +variable "apim_subnet_id" {} +variable "appi_resource_id" {} +variable "appi_instrumentation_key" {} +variable "function_fqdn" {} \ No newline at end of file diff --git a/modules/nsg/main.tf b/modules/nsg/main.tf index c854a08..f8299eb 100644 --- a/modules/nsg/main.tf +++ b/modules/nsg/main.tf @@ -17,7 +17,7 @@ resource "azurerm_network_security_group" "nsg" { protocol = "*" source_port_range = "*" destination_port_range = "*" - source_address_prefix = "10.6.2.0/24" + source_address_prefixes = ["10.6.2.0/24", "10.6.6.0/24"] destination_address_prefix = "10.6.3.0/24" } diff --git a/modules/udr/main.tf b/modules/udr/main.tf index d754506..07be775 100644 --- a/modules/udr/main.tf +++ b/modules/udr/main.tf @@ -37,6 +37,12 @@ resource "azurerm_subnet_route_table_association" "restrict_contoso_tests" { route_table_id = azurerm_route_table.restrict.id } +# Attach UDR to the APIM subnet +resource "azurerm_subnet_route_table_association" "restrict_apim" { + subnet_id = var.apim_subnet_id + route_table_id = azurerm_route_table.restrict.id +} + # Create UDR for the gateway subnet resource "azurerm_route_table" "gateway" { name = "${var.udr_name}-gateway" @@ -58,9 +64,9 @@ resource "azurerm_route_table" "gateway" { dynamic "route" { for_each = local.routes_to_internet content { - name = "to-internet" - address_prefix = "0.0.0.0/0" - next_hop_type = "Internet" + name = "to-internet" + address_prefix = "0.0.0.0/0" + next_hop_type = "Internet" } } diff --git a/modules/udr/variables.tf b/modules/udr/variables.tf index 5391ffa..e8f939a 100644 --- a/modules/udr/variables.tf +++ b/modules/udr/variables.tf @@ -8,7 +8,8 @@ variable "contoso_tests_subnet_id" {} variable "contoso_address_prefixes" {} variable "spoke_address_prefixes" {} variable "gateway_subnet_id" {} +variable "apim_subnet_id" {} variable "enable_gateway_route_to_firewall" {} variable "tags" { default = {} -} \ No newline at end of file +} diff --git a/modules/vnet/outputs.tf b/modules/vnet/outputs.tf index 0bc7e30..97730cf 100644 --- a/modules/vnet/outputs.tf +++ b/modules/vnet/outputs.tf @@ -22,6 +22,10 @@ output "subnet_dns_address_prefixes" { value = azurerm_subnet.dns.address_prefixes } +output"subnet_apim_address_prefixes" { + value = azurerm_subnet.apim.address_prefixes +} + output "vnet_contoso_address_space" { value = azurerm_virtual_network.contoso.address_space } @@ -50,6 +54,10 @@ output "subnet_flexible_server_id" { value = azurerm_subnet.flexible_server.id } +output "subnet_apim_id" { + value = azurerm_subnet.apim.id +} + output "vnet_hub_id" { value = azurerm_virtual_network.hub.id } diff --git a/modules/vnet/variables.tf b/modules/vnet/variables.tf index b1485b5..55b64f2 100644 --- a/modules/vnet/variables.tf +++ b/modules/vnet/variables.tf @@ -50,6 +50,10 @@ variable "flexible_server_address_prefixes" { default = [] } +variable "apim_address_prefixes" { + default = [] +} + variable "contoso_address_space" { default = [] } diff --git a/modules/vnet/vnet.tf b/modules/vnet/vnet.tf index 048e28a..a8a703a 100644 --- a/modules/vnet/vnet.tf +++ b/modules/vnet/vnet.tf @@ -133,6 +133,24 @@ resource "azurerm_subnet" "flexible_server" { } } +# Create the Subnet for APIM +resource "azurerm_subnet" "apim" { + name = "apim" + resource_group_name = var.resource_group_name + virtual_network_name = azurerm_virtual_network.spoke.name + address_prefixes = var.apim_address_prefixes + + delegation { + name = "apim-delegation" + service_delegation { + name = "Microsoft.Web/serverFarms" + actions = [ + "Microsoft.Network/virtualNetworks/subnets/action", + ] + } + } +} + # Create on-premises resource "azurerm_virtual_network" "contoso" { name = "vnet-contoso" diff --git a/variables.tf b/variables.tf index cf4b512..8229fc8 100644 --- a/variables.tf +++ b/variables.tf @@ -5,7 +5,7 @@ variable "resource_group" { # Location variable "location" { - default = "westeurope" + default = "northeurope" } # Cosmos DB database name @@ -119,6 +119,10 @@ variable "enable_network_policy_for_private_endpoints" { default = true } +variable "enable_apim" { + default = true +} + variable "hub_address_space" { default = ["10.5.0.0/16"] } @@ -167,6 +171,10 @@ variable "flexible_server_address_prefixes" { default = ["10.6.5.0/24"] } +variable "apim_address_prefixes" { + default = ["10.6.6.0/24"] +} + variable "contoso_address_space" { default = ["192.168.0.0/16"] } @@ -179,6 +187,18 @@ variable "contoso_tests_address_prefixes" { default = ["192.168.2.0/24"] } +variable "publisher_name" { + default = "contoso" +} + +variable "publisher_email" { + default = "admin@contoso.com" +} + +variable "apim_name" { + default = "apim-v2" +} + # Resource Tags variable "tags" { default = {