Airlock processor networking (vnet integration and airlock subnet) (#2040)

* Airlock networking, including:

1. Airlock subnet in the core vnet
2. Airlock processor is now vnet integrated

* moving the airlock storage accounts to a dedicated subnet

* adding private endpoint for all event grid topics

* adding inbound rule to allow airlock processor to reach the workspaces

* Adding an AirlockEventSubnet
All eventgrids are in the AirlockEventSubnets
All airlock storage are in the AirlockStorageSubnet
The airlock function is in the AirlockProcessorSubnet
This commit is contained in:
Elad Iwanir 2022-06-16 21:40:24 +03:00 коммит произвёл GitHub
Родитель 5c3e4738ad
Коммит 0a4e0d482f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 247 добавлений и 60 удалений

Просмотреть файл

@ -1 +1 @@
__version__ = "0.0.3"
__version__ = "0.0.4"

Просмотреть файл

@ -6,17 +6,27 @@ locals {
version = replace(replace(replace(data.local_file.airlock_processor_version.content, "__version__ = \"", ""), "\"", ""), "\n", "")
}
# re-using the web api app plan
data "azurerm_app_service_plan" "core" {
name = "plan-${var.tre_id}"
resource_group_name = var.resource_group_name
}
data "azurerm_application_insights" "core" {
name = "appi-${var.tre_id}"
resource_group_name = var.resource_group_name
}
resource "azurerm_service_plan" "airlock_plan" {
name = "plan-airlock-${var.tre_id}"
resource_group_name = var.resource_group_name
location = var.location
os_type = "Linux"
sku_name = var.airlock_app_service_plan_sku_size
tags = local.tre_core_tags
worker_count = 1
lifecycle { ignore_changes = [tags] }
}
resource "azurerm_app_service_virtual_network_swift_connection" "airlock-integrated-vnet" {
app_service_id = azurerm_linux_function_app.airlock_function_app.id
subnet_id = var.airlock_processor_subnet_id
}
resource "azurerm_storage_account" "sa_airlock_processor_func_app" {
name = local.airlock_function_sa_name
@ -35,7 +45,7 @@ resource "azurerm_linux_function_app" "airlock_function_app" {
location = var.location
storage_account_name = azurerm_storage_account.sa_airlock_processor_func_app.name
service_plan_id = data.azurerm_app_service_plan.core.id
service_plan_id = azurerm_service_plan.airlock_plan.id
storage_account_access_key = azurerm_storage_account.sa_airlock_processor_func_app.primary_access_key
tags = local.tre_core_tags
@ -57,12 +67,15 @@ resource "azurerm_linux_function_app" "airlock_function_app" {
"MANAGED_IDENTITY_CLIENT_ID" = azurerm_user_assigned_identity.airlock_id.client_id
"AZURE_SUBSCRIPTION_ID" = var.arm_subscription_id
"TRE_ID" = var.tre_id
"WEBSITE_CONTENTOVERVNET" = 1
}
site_config {
always_on = var.enable_local_debugging ? true : false
container_registry_managed_identity_client_id = azurerm_user_assigned_identity.airlock_id.client_id
container_registry_use_managed_identity = true
vnet_route_all_enabled = true
application_stack {
docker {
registry_url = var.docker_registry_server

Просмотреть файл

@ -1,14 +1,42 @@
data "azurerm_private_dns_zone" "eventgrid" {
name = "privatelink.eventgrid.azure.net"
resource_group_name = var.resource_group_name
}
# Event grid topics
resource "azurerm_eventgrid_topic" "step_result" {
name = local.step_result_topic_name
location = var.location
resource_group_name = var.resource_group_name
name = local.step_result_topic_name
location = var.location
resource_group_name = var.resource_group_name
public_network_access_enabled = false
tags = {
Publishers = "Airlock Orchestrator;"
Publishers = "Airlock Processor;"
}
}
resource "azurerm_private_endpoint" "eg_step_result" {
name = "pe-eg-step-result-${var.tre_id}"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = var.airlock_events_subnet_id
lifecycle { ignore_changes = [tags] }
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [data.azurerm_private_dns_zone.eventgrid.id]
}
private_service_connection {
name = "psc-eg-${var.tre_id}"
private_connection_resource_id = azurerm_eventgrid_topic.step_result.id
is_manual_connection = false
subresource_names = ["topic"]
}
}
resource "azurerm_eventgrid_topic" "status_changed" {
name = local.status_changed_topic_name
location = var.location
@ -20,23 +48,17 @@ resource "azurerm_eventgrid_topic" "status_changed" {
}
}
# Event grid status_changed private endpoint
resource "azurerm_private_dns_zone" "eventgrid" {
name = "privatelink.eventgrid.azure.net"
resource_group_name = var.resource_group_name
lifecycle { ignore_changes = [tags] }
}
resource "azurerm_private_endpoint" "egpe" {
name = "pe-eg-${var.tre_id}"
resource "azurerm_private_endpoint" "eg_status_changed" {
name = "pe-eg-status-changed-${var.tre_id}"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = var.shared_subnet_id
subnet_id = var.airlock_events_subnet_id
lifecycle { ignore_changes = [tags] }
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [azurerm_private_dns_zone.eventgrid.id]
private_dns_zone_ids = [data.azurerm_private_dns_zone.eventgrid.id]
}
private_service_connection {
@ -47,13 +69,6 @@ resource "azurerm_private_endpoint" "egpe" {
}
}
resource "azurerm_private_dns_zone_virtual_network_link" "eg_topic_dns_link" {
name = "eg_topic_dns_link"
resource_group_name = var.resource_group_name
private_dns_zone_name = azurerm_private_dns_zone.eventgrid.name
virtual_network_id = var.virtual_network_id
lifecycle { ignore_changes = [tags] }
}
# System topic
resource "azurerm_eventgrid_system_topic" "import_inprogress_blob_created" {
@ -114,9 +129,11 @@ resource "azurerm_eventgrid_system_topic" "export_approved_blob_created" {
# Custom topic (for scanning)
resource "azurerm_eventgrid_topic" "scan_result" {
name = local.scan_result_topic_name
location = var.location
resource_group_name = var.resource_group_name
name = local.scan_result_topic_name
location = var.location
resource_group_name = var.resource_group_name
public_network_access_enabled = false
tags = {
Publishers = "airlock;custom scanning service;"
@ -125,6 +142,27 @@ resource "azurerm_eventgrid_topic" "scan_result" {
lifecycle { ignore_changes = [tags] }
}
resource "azurerm_private_endpoint" "eg_scan_result" {
name = "pe-eg-scan-result-${var.tre_id}"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = var.airlock_events_subnet_id
lifecycle { ignore_changes = [tags] }
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [data.azurerm_private_dns_zone.eventgrid.id]
}
private_service_connection {
name = "psc-eg-${var.tre_id}"
private_connection_resource_id = azurerm_eventgrid_topic.scan_result.id
is_manual_connection = false
subresource_names = ["topic"]
}
}
## Subscriptions
resource "azurerm_eventgrid_event_subscription" "step_result" {

Просмотреть файл

@ -49,7 +49,7 @@ resource "azurerm_role_assignment" "eventgrid_data_sender" {
}
resource "azurerm_role_assignment" "sa_import_external" {
scope = azurerm_storage_account.sa_external_import.id
scope = azurerm_storage_account.sa_import_external.id
role_definition_name = "Contributor"
principal_id = azurerm_user_assigned_identity.airlock_id.principal_id
}

Просмотреть файл

@ -1,5 +1,5 @@
# 'External' storage account - drop location for import
resource "azurerm_storage_account" "sa_external_import" {
resource "azurerm_storage_account" "sa_import_external" {
name = local.import_external_storage_name
location = var.location
resource_group_name = var.resource_group_name
@ -72,11 +72,11 @@ data "azurerm_private_dns_zone" "blobcore" {
resource_group_name = var.resource_group_name
}
resource "azurerm_private_endpoint" "stg_ip_import_pe" {
resource "azurerm_private_endpoint" "stg_import_inprogress_pe" {
name = "stg-ip-import-blob-${var.tre_id}"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = var.shared_subnet_id
subnet_id = var.airlock_storage_subnet_id
lifecycle { ignore_changes = [tags] }
@ -119,11 +119,11 @@ resource "azurerm_storage_account" "sa_import_rejected" {
lifecycle { ignore_changes = [tags] }
}
resource "azurerm_private_endpoint" "stgipimportpe" {
resource "azurerm_private_endpoint" "stg_import_rejected_pe" {
name = "stg-import-rej-blob-${var.tre_id}"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = var.shared_subnet_id
subnet_id = var.airlock_storage_subnet_id
private_dns_zone_group {
name = "private-dns-zone-group-stg-import-rej"

Просмотреть файл

@ -1,7 +1,8 @@
variable "tre_id" {}
variable "location" {}
variable "resource_group_name" {}
variable "shared_subnet_id" {}
variable "airlock_storage_subnet_id" {}
variable "airlock_events_subnet_id" {}
variable "enable_local_debugging" {}
variable "virtual_network_id" {}
variable "api_principal_id" {}
@ -32,3 +33,10 @@ variable "arm_subscription_id" {
type = string
default = ""
}
variable "airlock_app_service_plan_sku_size" {
type = string
default = "P1v3"
}
variable "airlock_processor_subnet_id" {}

Просмотреть файл

@ -80,18 +80,21 @@ module "appgateway" {
}
module "airlock_resources" {
source = "./airlock"
tre_id = var.tre_id
location = var.location
resource_group_name = azurerm_resource_group.core.name
shared_subnet_id = module.network.shared_subnet_id
virtual_network_id = module.network.core_vnet_id
enable_local_debugging = var.enable_local_debugging
docker_registry_server = var.docker_registry_server
mgmt_resource_group_name = var.mgmt_resource_group_name
mgmt_acr_name = var.acr_name
api_principal_id = azurerm_user_assigned_identity.id.principal_id
arm_subscription_id = var.arm_subscription_id
source = "./airlock"
tre_id = var.tre_id
location = var.location
resource_group_name = azurerm_resource_group.core.name
airlock_storage_subnet_id = module.network.airlock_storage_subnet_id
airlock_events_subnet_id = module.network.airlock_events_subnet_id
virtual_network_id = module.network.core_vnet_id
enable_local_debugging = var.enable_local_debugging
docker_registry_server = var.docker_registry_server
mgmt_resource_group_name = var.mgmt_resource_group_name
mgmt_acr_name = var.acr_name
api_principal_id = azurerm_user_assigned_identity.id.principal_id
arm_subscription_id = var.arm_subscription_id
airlock_app_service_plan_sku_size = var.api_app_service_plan_sku_size
airlock_processor_subnet_id = module.network.airlock_processor_subnet_id
depends_on = [
azurerm_servicebus_namespace.sb,
module.network

Просмотреть файл

@ -225,4 +225,9 @@ moved {
moved {
from = module.bastion.azurerm_bastion_host.bastion
to = azurerm_bastion_host.bastion
}
}
moved {
from = module.airlock.azurerm_private_dns_zone.eventgrid
to = module.network.azurerm_private_dns_zone.eventgrid
}

Просмотреть файл

@ -237,3 +237,22 @@ resource "azurerm_private_dns_zone" "nexus" {
lifecycle { ignore_changes = [tags] }
}
resource "azurerm_private_dns_zone" "eventgrid" {
name = "privatelink.eventgrid.azure.net"
resource_group_name = var.resource_group_name
tags = local.tre_core_tags
lifecycle { ignore_changes = [tags] }
}
resource "azurerm_private_dns_zone_virtual_network_link" "eventgridlink" {
name = "eventgrid-link"
resource_group_name = var.resource_group_name
private_dns_zone_name = azurerm_private_dns_zone.eventgrid.name
virtual_network_id = azurerm_virtual_network.core.id
tags = local.tre_core_tags
lifecycle { ignore_changes = [tags] }
}

Просмотреть файл

@ -1,12 +1,23 @@
locals {
core_services_vnet_subnets = cidrsubnets(var.core_address_space, 4, 4, 4, 4, 2, 2, 2)
firewall_subnet_address_space = local.core_services_vnet_subnets[0] # .0 - .62
app_gw_subnet_address_prefix = local.core_services_vnet_subnets[1] # .64 - .127
bastion_subnet_address_prefix = local.core_services_vnet_subnets[2] # .128 - .191
web_app_subnet_address_prefix = local.core_services_vnet_subnets[3] # .192 - .254
shared_services_subnet_address_prefix = local.core_services_vnet_subnets[4] # .0 - .254
aci_subnet_address_prefix = local.core_services_vnet_subnets[5] # .0 - .254
resource_processor_subnet_address_prefix = local.core_services_vnet_subnets[6] # .0 - .254
core_services_vnet_subnets = cidrsubnets(var.core_address_space, 4, 4, 4, 4, 2, 4, 4, 4, 4, 2)
# .1
firewall_subnet_address_space = local.core_services_vnet_subnets[0] # .0 - .63
app_gw_subnet_address_prefix = local.core_services_vnet_subnets[1] # .64 - .127
bastion_subnet_address_prefix = local.core_services_vnet_subnets[2] # .128 - .191
web_app_subnet_address_prefix = local.core_services_vnet_subnets[3] # .192 - .254
# .2
shared_services_subnet_address_prefix = local.core_services_vnet_subnets[4] # .0 - .254
# replacing the aci
airlock_processor_subnet_address_prefix = local.core_services_vnet_subnets[5] # .0 - .63
airlock_storage_subnet_address_prefix = local.core_services_vnet_subnets[6] # .64 - .127
airlock_events_subnet_address_prefix = local.core_services_vnet_subnets[7] # .128 - .191
# free [8]
# .3
resource_processor_subnet_address_prefix = local.core_services_vnet_subnets[9] # .0 - .254
tre_core_tags = {
tre_id = var.tre_id
tre_core_service_id = var.tre_id

Просмотреть файл

@ -65,3 +65,39 @@ resource "azurerm_subnet" "resource_processor" {
# notice that private endpoints do not adhere to NSG rules
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_subnet" "airlock_processor" {
name = "AirlockProcessorSubnet"
virtual_network_name = azurerm_virtual_network.core.name
resource_group_name = var.resource_group_name
address_prefixes = [local.airlock_processor_subnet_address_prefix]
# notice that private endpoints do not adhere to NSG rules
enforce_private_link_endpoint_network_policies = true
delegation {
name = "delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
}
}
resource "azurerm_subnet" "airlock_storage" {
name = "AirlockStorageSubnet"
virtual_network_name = azurerm_virtual_network.core.name
resource_group_name = var.resource_group_name
address_prefixes = [local.airlock_storage_subnet_address_prefix]
# notice that private endpoints do not adhere to NSG rules
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_subnet" "airlock_events" {
name = "AirlockEventsSubnet"
virtual_network_name = azurerm_virtual_network.core.name
resource_group_name = var.resource_group_name
address_prefixes = [local.airlock_events_subnet_address_prefix]
# notice that private endpoints do not adhere to NSG rules
enforce_private_link_endpoint_network_policies = true
}

Просмотреть файл

@ -169,3 +169,22 @@ resource "azurerm_subnet_network_security_group_association" "resource_processor
subnet_id = azurerm_subnet.resource_processor.id
network_security_group_id = azurerm_network_security_group.default_rules.id
}
resource "azurerm_subnet_network_security_group_association" "airlock_processor" {
subnet_id = azurerm_subnet.airlock_processor.id
network_security_group_id = azurerm_network_security_group.default_rules.id
}
resource "azurerm_subnet_network_security_group_association" "airlock_storage" {
subnet_id = azurerm_subnet.airlock_storage.id
network_security_group_id = azurerm_network_security_group.default_rules.id
}
resource "azurerm_subnet_network_security_group_association" "airlock_events" {
subnet_id = azurerm_subnet.airlock_events.id
network_security_group_id = azurerm_network_security_group.default_rules.id
}

Просмотреть файл

@ -22,6 +22,18 @@ output "shared_subnet_id" {
value = azurerm_subnet.shared.id
}
output "airlock_processor_subnet_id" {
value = azurerm_subnet.airlock_processor.id
}
output "airlock_storage_subnet_id" {
value = azurerm_subnet.airlock_storage.id
}
output "airlock_events_subnet_id" {
value = azurerm_subnet.airlock_events.id
}
output "private_dns_zone_azurewebsites_id" {
value = azurerm_private_dns_zone.azurewebsites.id
}

Просмотреть файл

@ -27,6 +27,12 @@ data "azurerm_subnet" "resourceprocessor" {
name = "ResourceProcessorSubnet"
}
data "azurerm_subnet" "airlockprocessor" {
resource_group_name = local.core_resource_group_name
virtual_network_name = local.core_vnet
name = "AirlockProcessorSubnet"
}
data "azurerm_route_table" "rt" {
name = "rt-${var.tre_id}"
resource_group_name = local.core_resource_group_name

Просмотреть файл

@ -172,6 +172,23 @@ resource "azurerm_network_security_rule" "allow-inbound-from-resourceprocessor"
source_port_range = "*"
}
resource "azurerm_network_security_rule" "allow-inbound-from-airlockprocessor" {
access = "Allow"
destination_address_prefixes = azurerm_subnet.services.address_prefixes
destination_port_range = "443"
direction = "Inbound"
name = "allow-inbound-from-airlockprocessor"
network_security_group_name = azurerm_network_security_group.ws.name
priority = 140
protocol = "Tcp"
resource_group_name = var.ws_resource_group_name
source_address_prefixes = [
data.azurerm_subnet.airlockprocessor.address_prefix
]
source_port_range = "*"
}
resource "azurerm_network_security_rule" "allow-inbound-from-webapp-to-services" {
access = "Allow"
destination_port_ranges = [