// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. @description('The name of the API Management service instance') param apiManagementName string = 'apiservice${uniqueString(resourceGroup().id)}' @description('The email address of the owner of the service') @minLength(1) param publisherEmail string @description('The name of the owner of the service') @minLength(1) param publisherName string @description('The pricing tier of this API Management service') @allowed([ 'Developer' 'Premium' ]) param sku string = 'Premium' @description('The instance size of this API Management service. This should be a multiple of the number of availability zones getting deployed.') param skuCount int = 2 @description('Virtual network name') param virtualNetworkName string = 'apimvnet' @description('Application Insights resource name') param appInsightsName string = 'apim-appi' @description('Application Insights public network access for ingestion') param appInsightsPublicNetworkAccessForIngestion string = 'Disabled' @description('Address prefix') param virtualNetworkAddressPrefix string = '10.0.0.0/12' @description('Subnet prefix') param subnetPrefix string = '10.0.0.0/24' @description('Subnet name') param subnetName string = 'apim' @description('Service endpoints enabled on the API Management subnet') param apimSubnetServiceEndpoints array = [ { service: 'Microsoft.Storage' } { service: 'Microsoft.Sql' } { service: 'Microsoft.EventHub' } ] @description('Azure region where the resources will be deployed') param location string = resourceGroup().location @description('Numbers for availability zones, for example, 1,2,3.') param availabilityZones array = [ '1' '2' ] @description('Name for the public IP address used to access the API Management service.') param publicIpName string = 'apimPublicIP' @description('SKU for the public IP address used to access the API Management service.') @allowed([ 'Standard' ]) param publicIpSku string = 'Standard' @description('Allocation method for the public IP address used to access the API Management service. Standard SKU public IP requires `Static` allocation.') @allowed([ 'Static' ]) param publicIPAllocationMethod string = 'Static' @description('Unique DNS name for the public IP address used to access the API management service.') param dnsLabelPrefix string = toLower('${publicIpName}-${uniqueString(resourceGroup().id)}') @description('The workspace id of the Log Analytics resource.') param logAnalyticsWorkspaceId string var subnetRef = resourceId('Microsoft.Network/virtualNetworks/subnets', virtualNetworkName, subnetName) @description('Name of the NSG for the API Management service.') param nsgName string = 'apim-nsg-${uniqueString(resourceGroup().id)}' resource nsg 'Microsoft.Network/networkSecurityGroups@2020-06-01' = { name: nsgName location: location properties: { securityRules: [ { name: 'Client_communication_to_API_Management' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '80' sourceAddressPrefix: 'Internet' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 100 direction: 'Inbound' } } { name: 'Secure_Client_communication_to_API_Management' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: 'Internet' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 110 direction: 'Inbound' } } { name: 'Management_endpoint_for_Azure_portal_and_Powershell' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '3443' sourceAddressPrefix: 'ApiManagement' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 120 direction: 'Inbound' } } { name: 'Dependency_on_Redis_Cache' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '6381-6383' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 130 direction: 'Inbound' } } { name: 'Dependency_to_sync_Rate_Limit_Inbound' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '4290' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 135 direction: 'Inbound' } } { name: 'Dependency_on_Azure_SQL' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '1433' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'Sql' access: 'Allow' priority: 140 direction: 'Outbound' } } { name: 'Dependency_for_Log_to_event_Hub_policy' properties: { protocol: '*' sourcePortRange: '*' destinationPortRange: '5671' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'EventHub' access: 'Allow' priority: 150 direction: 'Outbound' } } { name: 'Dependency_on_Redis_Cache_outbound' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '6381-6383' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 160 direction: 'Outbound' } } { name: 'Depenedency_To_sync_RateLimit_Outbound' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '4290' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 165 direction: 'Outbound' } } { name: 'Dependency_on_Azure_File_Share_for_GIT' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '445' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'Storage' access: 'Allow' priority: 170 direction: 'Outbound' } } { name: 'Azure_Infrastructure_Load_Balancer' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '6390' sourceAddressPrefix: 'AzureLoadBalancer' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 180 direction: 'Inbound' } } { name: 'Publish_DiagnosticLogs_And_Metrics' properties: { description: 'API Management logs and metrics for consumption by admins and your IT team are all part of the management plane' protocol: 'Tcp' sourcePortRange: '*' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'AzureMonitor' access: 'Allow' priority: 185 direction: 'Outbound' destinationPortRanges: [ '443' '12000' '1886' ] } } { name: 'Connect_To_SMTP_Relay_For_SendingEmails' properties: { description: 'APIM features the ability to generate email traffic as part of the data plane and the management plane' protocol: 'Tcp' sourcePortRange: '*' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'Internet' access: 'Allow' priority: 190 direction: 'Outbound' destinationPortRanges: [ '25' '587' '25028' ] } } { name: 'Authenticate_To_Azure_Active_Directory' properties: { description: 'Connect to Azure Active Directory for developer Portal authentication or for OAuth 2 flow during any proxy authentication' protocol: 'Tcp' sourcePortRange: '*' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'AzureActiveDirectory' access: 'Allow' priority: 200 direction: 'Outbound' destinationPortRanges: [ '80' '443' ] } } { name: 'Dependency_on_Azure_Storage' properties: { description: 'API Management service dependency on Azure blob and Azure table storage' protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'Storage' access: 'Allow' priority: 100 direction: 'Outbound' } } { name: 'Publish_Monitoring_Logs' properties: { protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'AzureCloud' access: 'Allow' priority: 300 direction: 'Outbound' } } { name: 'Deny_All_Internet_Outbound' properties: { protocol: '*' sourcePortRange: '*' destinationPortRange: '*' sourceAddressPrefix: 'VirtualNetwork' destinationAddressPrefix: 'Internet' access: 'Deny' priority: 999 direction: 'Outbound' } } ] } } resource publicIp 'Microsoft.Network/publicIPAddresses@2020-05-01' = { name: publicIpName location: location sku: { name: publicIpSku } properties: { publicIPAllocationMethod: publicIPAllocationMethod publicIPAddressVersion: 'IPv4' dnsSettings: { domainNameLabel: dnsLabelPrefix } } } resource virtualNetwork 'Microsoft.Network/virtualNetworks@2020-06-01' = { name: virtualNetworkName location: location properties: { addressSpace: { addressPrefixes: [ virtualNetworkAddressPrefix ] } subnets: [ { name: subnetName properties: { addressPrefix: subnetPrefix networkSecurityGroup: { id: nsg.id } serviceEndpoints: apimSubnetServiceEndpoints } } ] } } resource apiManagementService 'Microsoft.ApiManagement/service@2021-08-01' = { name: apiManagementName location: location sku: { name: sku capacity: skuCount } zones: ((length(availabilityZones) == 0) ? null : availabilityZones) properties: { publisherEmail: publisherEmail publisherName: publisherName virtualNetworkType: 'External' publicIpAddressId: publicIp.id virtualNetworkConfiguration: { subnetResourceId: subnetRef } customProperties: { 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_128_GCM_SHA256': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_256_CBC_SHA256': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_128_CBC_SHA256': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_256_CBC_SHA': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_128_CBC_SHA': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Ssl30': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls10': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls11': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Ssl30': 'false' 'Microsoft.WindowsAzure.ApiManagement.Gateway.Protocols.Server.Http2': 'false' } } dependsOn: [ virtualNetwork ] } resource apimLogger 'Microsoft.ApiManagement/service/loggers@2022-08-01' = { name: appInsights.name parent: apiManagementService properties: { resourceId: appInsights.id description: 'Application Insights for APIM' loggerType: 'applicationInsights' credentials: { instrumentationKey: appInsights.properties.InstrumentationKey } } } resource apimDiagnostics 'Microsoft.ApiManagement/service/diagnostics@2022-08-01' = { name: 'applicationinsights' parent: apiManagementService properties: { loggerId: apimLogger.id alwaysLog: 'allErrors' verbosity: 'information' sampling: { percentage: 100 samplingType: 'fixed' } } } resource appInsights 'Microsoft.Insights/components@2020-02-02' = { name: appInsightsName location: location kind: 'web' properties: { Application_Type: 'web' WorkspaceResourceId: logAnalyticsWorkspaceId publicNetworkAccessForIngestion: appInsightsPublicNetworkAccessForIngestion publicNetworkAccessForQuery: 'Enabled' } } output apimIPs array = apiManagementService.properties.publicIPAddresses output apimGatewayUrl string = apiManagementService.properties.gatewayUrl output appInsightsName string = appInsights.name output appInsightsId string = appInsights.id output appInsightsConnectionString string = appInsights.properties.ConnectionString output name string = apiManagementService.name output vnetName string = virtualNetwork.name output vnetId string = virtualNetwork.id output defaultSubnetId string = virtualNetwork.properties.subnets[0].id output hostnameConfigs array = apiManagementService.properties.hostnameConfigurations