Skip to content

Commit

Permalink
Support ip group names in dynamic firewall rules (#3089)
Browse files Browse the repository at this point in the history
* Support ip group names in firewall rules

* changelog

* tf lint

* remove unused resources

* fix nexus test

* update test

* fix test

* update bundle versions

* fix certs

* fix certs

* disable certs_nexus test
  • Loading branch information
tamirkamara authored Jan 23, 2023
1 parent 3540489 commit 95654cd
Show file tree
Hide file tree
Showing 19 changed files with 380 additions and 122 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
FEATURES:

ENHANCEMENTS:
* Add support for referencing IP Groups from the Core Resource Group in firewall rules created via the pipeline [#3089](https://github.com/microsoft/AzureTRE/pull/3089)

BUG FIXES:

Expand Down
7 changes: 4 additions & 3 deletions core/terraform/keyvault.tf
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ resource "azurerm_key_vault_secret" "application_admin_client_secret" {
}

resource "azurerm_monitor_diagnostic_setting" "kv" {
name = "diagnostics-kv-${var.tre_id}"
target_resource_id = azurerm_key_vault.kv.id
log_analytics_workspace_id = module.azure_monitor.log_analytics_workspace_id
name = "diagnostics-kv-${var.tre_id}"
target_resource_id = azurerm_key_vault.kv.id
log_analytics_workspace_id = module.azure_monitor.log_analytics_workspace_id
log_analytics_destination_type = "AzureDiagnostics"

dynamic "log" {
for_each = toset(["AuditEvent", "AzurePolicyEvaluationDetails"])
Expand Down
9 changes: 9 additions & 0 deletions core/terraform/network/network.tf
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,12 @@ resource "azurerm_subnet" "airlock_events" {
# https://docs.microsoft.com/en-us/azure/event-grid/consume-private-endpoints
service_endpoints = ["Microsoft.ServiceBus"]
}

resource "azurerm_ip_group" "resource_processor" {
name = "ipg-resource-processor"
location = var.location
resource_group_name = var.resource_group_name
cidrs = [local.resource_processor_subnet_address_prefix]
tags = local.tre_core_tags
lifecycle { ignore_changes = [tags] }
}
2 changes: 1 addition & 1 deletion core/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.5.2"
__version__ = "0.5.3"
102 changes: 74 additions & 28 deletions e2e_tests/test_shared_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,26 +89,14 @@ async def test_patch_firewall(verify):

shared_service_templates_to_create = [
strings.GITEA_SHARED_SERVICE,

# TODO: https://github.com/microsoft/AzureTRE/issues/2328
# strings.CERTS_SHARED_SERVICE,

strings.ADMIN_VM_SHARED_SERVICE,

strings.AIRLOCK_NOTIFIER_SHARED_SERVICE,

# TODO: Until this is resolved we can't install nexus in parallel with others: https://github.com/microsoft/AzureTRE/issues/2328
# strings.NEXUS_SHARED_SERVICE,

# TODO: fix cyclecloud and enable this
# strings.CYCLECLOUD_SHARED_SERVICE,
]

create_certs_properties = {
"domain_prefix": "foo",
"cert_name": "cert-foo",
}

create_airlock_notifier_properties = {
"smtp_server_address": "10.1.2.3",
"smtp_username": "smtp_user",
Expand All @@ -121,19 +109,7 @@ async def test_patch_firewall(verify):
@pytest.mark.timeout(40 * 60)
@pytest.mark.parametrize("template_name", shared_service_templates_to_create)
async def test_create_shared_service(template_name, verify) -> None:
admin_token = await get_admin_token(verify)
# Check that the shared service hasn't already been created
shared_service = await get_shared_service_by_name(
template_name, verify, admin_token
)
if shared_service:
id = shared_service["id"]
LOGGER.info(
f"Shared service {template_name} already exists (id {id}), deleting it first..."
)
await disable_and_delete_resource(
f"/api/shared-services/{id}", admin_token, verify
)
await disable_and_delete_shared_service_if_exists(template_name, verify)

post_payload = {
"templateName": template_name,
Expand All @@ -143,11 +119,11 @@ async def test_create_shared_service(template_name, verify) -> None:
},
}

if template_name == strings.CERTS_SHARED_SERVICE:
post_payload["properties"].update(create_certs_properties)
elif template_name == strings.AIRLOCK_NOTIFIER_SHARED_SERVICE:
if template_name == strings.AIRLOCK_NOTIFIER_SHARED_SERVICE:
post_payload["properties"].update(create_airlock_notifier_properties)

admin_token = await get_admin_token(verify)

shared_service_path, _ = await post_resource(
payload=post_payload,
endpoint="/api/shared-services",
Expand All @@ -159,3 +135,73 @@ async def test_create_shared_service(template_name, verify) -> None:
await disable_and_delete_resource(
f"/api{shared_service_path}", admin_token, verify
)


# @pytest.mark.shared_services
@pytest.mark.timeout(45 * 60)
async def test_create_certs_nexus_shared_service(verify) -> None:
await disable_and_delete_shared_service_if_exists(strings.NEXUS_SHARED_SERVICE, verify)
await disable_and_delete_shared_service_if_exists(strings.CERTS_SHARED_SERVICE, verify)

cert_domain = "nexus"
cert_name = f"${cert_domain}-ssl"

certs_post_payload = {
"templateName": strings.CERTS_SHARED_SERVICE,
"properties": {
"display_name": f"Shared service {strings.CERTS_SHARED_SERVICE}",
"description": f"{strings.CERTS_SHARED_SERVICE} deployed via e2e tests",
"domain_prefix": cert_domain,
"cert_name": cert_name,
},
}

nexus_post_payload = {
"templateName": strings.NEXUS_SHARED_SERVICE,
"properties": {
"display_name": f"Shared service {strings.NEXUS_SHARED_SERVICE}",
"description": f"{strings.NEXUS_SHARED_SERVICE} deployed via e2e tests",
"ssl_cert_name": cert_name,
},
}

admin_token = await get_admin_token(verify)

certs_shared_service_path, _ = await post_resource(
payload=certs_post_payload,
endpoint="/api/shared-services",
access_token=admin_token,
verify=verify,
)

nexus_shared_service_path, _ = await post_resource(
payload=nexus_post_payload,
endpoint="/api/shared-services",
access_token=admin_token,
verify=verify,
)

await disable_and_delete_resource(
f"/api{nexus_shared_service_path}", admin_token, verify
)

await nexus_shared_service_path(
f"/api{certs_shared_service_path}", admin_token, verify
)


async def disable_and_delete_shared_service_if_exists(shared_service_name, verify) -> None:
admin_token = await get_admin_token(verify)

# Check that the shared service hasn't already been created
shared_service = await get_shared_service_by_name(
shared_service_name, verify, admin_token
)
if shared_service:
id = shared_service["id"]
LOGGER.info(
f"Shared service {shared_service_name} already exists (id {id}), deleting it first..."
)
await disable_and_delete_resource(
f"/api/shared-services/{id}", admin_token, verify
)
2 changes: 1 addition & 1 deletion templates/shared_services/airlock_notifier/porter.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
schemaVersion: 1.0.0
name: tre-shared-service-airlock-notifier
version: 0.3.1
version: 0.4.0
description: "A shared service notifying on Airlock Operations"
registry: azuretre
dockerfile: Dockerfile.tmpl
Expand Down
97 changes: 97 additions & 0 deletions templates/shared_services/airlock_notifier/template_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,107 @@
},
"pipeline": {
"install": [
{
"stepId": "e8360838-008c-40d4-8135-65cdbead5392",
"stepTitle": "Add network firewall rules for airlock notifier deployment",
"resourceTemplateName": "tre-shared-service-firewall",
"resourceType": "shared-service",
"resourceAction": "upgrade",
"properties": [
{
"name": "network_rule_collections",
"type": "array",
"arraySubstitutionAction": "replace",
"arrayMatchField": "name",
"value": {
"name": "nrc_svc_{{ resource.id }}_rp_airlock_notifier_deployment",
"action": "Allow",
"rules": [
{
"name": "AppService",
"description": "Resource Processor to interact with AppService",
"source_ip_groups_in_core": ["ipg-resource-processor"],
"destination_addresses": [
"AppService"
],
"destination_ports": [
"443"
],
"protocols": [
"TCP"
]
}
]
}
}
]
},
{
"stepId": "main"
}
],
"upgrade": [
{
"stepId": "b757f0e1-3e38-4231-8227-6ab43dc2b1f3",
"stepTitle": "Update network firewall rules for airlock notifier deployment",
"resourceTemplateName": "tre-shared-service-firewall",
"resourceType": "shared-service",
"resourceAction": "upgrade",
"properties": [
{
"name": "network_rule_collections",
"type": "array",
"arraySubstitutionAction": "replace",
"arrayMatchField": "name",
"value": {
"name": "nrc_svc_{{ resource.id }}_rp_airlock_notifier_deployment",
"action": "Allow",
"rules": [
{
"name": "AppService",
"description": "Resource Processor to interact with AppService",
"source_ip_groups_in_core": ["ipg-resource-processor"],
"destination_addresses": [
"AppService"
],
"destination_ports": [
"443"
],
"protocols": [
"TCP"
]
}
]
}
}
]
},
{
"stepId": "main"
}
],
"uninstall": [
{
"stepId": "main"
},
{
"stepId": "040c788a-babf-49cd-824d-535efd631150",
"stepTitle": "Remove network firewall rules for airlock notifier deployment",
"resourceTemplateName": "tre-shared-service-firewall",
"resourceType": "shared-service",
"resourceAction": "upgrade",
"properties": [
{
"name": "network_rule_collections",
"type": "array",
"arraySubstitutionAction": "remove",
"arrayMatchField": "name",
"value": {
"name": "nrc_svc_{{ resource.id }}_rp_airlock_notifier_deployment"
}
}
]
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,3 @@
resource "azurerm_firewall_network_rule_collection" "resource_processor_subnet_allow_appservice" {
name = "nrc-resource_processor_allow_appservice_subnet"
azure_firewall_name = data.azurerm_firewall.fw.name
resource_group_name = data.azurerm_firewall.fw.resource_group_name
priority = 110
action = "Allow"

rule {
name = "AzureServiceTags"

protocols = [
"TCP"
]

destination_addresses = [
"AppService"
]

destination_ports = [
"443"
]
source_addresses = data.azurerm_subnet.resource_processor.address_prefixes
}
}

resource "azurerm_service_plan" "notifier_plan" {
name = "airlock-notifier-plan-${var.tre_id}"
resource_group_name = data.azurerm_resource_group.core.name
Expand Down
11 changes: 0 additions & 11 deletions templates/shared_services/airlock_notifier/terraform/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,3 @@ data "azurerm_subnet" "airlock_notification" {
virtual_network_name = local.core_vnet
resource_group_name = local.core_resource_group_name
}

data "azurerm_firewall" "fw" {
name = "fw-${var.tre_id}"
resource_group_name = "rg-${var.tre_id}"
}

data "azurerm_subnet" "resource_processor" {
resource_group_name = local.core_resource_group_name
virtual_network_name = local.core_vnet
name = "ResourceProcessorSubnet"
}
2 changes: 1 addition & 1 deletion templates/shared_services/certs/porter.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
schemaVersion: 1.0.0
name: tre-shared-service-certs
version: 0.3.1
version: 0.3.40
description: "An Azure TRE shared service to generate certificates for a specified internal domain using Letsencrypt"
registry: azuretre
dockerfile: Dockerfile.tmpl
Expand Down
Loading

0 comments on commit 95654cd

Please sign in to comment.