From 424639042402598b83abf909becda1ff1492fc57 Mon Sep 17 00:00:00 2001 From: James Robinson Date: Wed, 17 Jul 2024 11:48:55 +0100 Subject: [PATCH 1/8] :bug: Add location specifiers to VirtualNetworks and NSGs as these will otherwise use the default location (which may not be correct). --- .../infrastructure/programs/sre/dns_server.py | 2 ++ .../infrastructure/programs/sre/networking.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/data_safe_haven/infrastructure/programs/sre/dns_server.py b/data_safe_haven/infrastructure/programs/sre/dns_server.py index 574089e2fe..da0daf9b81 100644 --- a/data_safe_haven/infrastructure/programs/sre/dns_server.py +++ b/data_safe_haven/infrastructure/programs/sre/dns_server.py @@ -100,6 +100,7 @@ def __init__( # Define network security group nsg = network.NetworkSecurityGroup( f"{self._name}_nsg_dns", + location=props.location, network_security_group_name=f"{stack_name}-nsg-dns", resource_group_name=resource_group.name, security_rules=[ @@ -165,6 +166,7 @@ def __init__( address_space=network.AddressSpaceArgs( address_prefixes=[SREDnsIpRanges.vnet.prefix], ), + location=props.location, resource_group_name=resource_group.name, subnets=[ # Note that we define subnets inline to avoid creation order issues # DNS subnet diff --git a/data_safe_haven/infrastructure/programs/sre/networking.py b/data_safe_haven/infrastructure/programs/sre/networking.py index f36bfaf9e4..a48c870f4f 100644 --- a/data_safe_haven/infrastructure/programs/sre/networking.py +++ b/data_safe_haven/infrastructure/programs/sre/networking.py @@ -95,6 +95,7 @@ def __init__( # Define NSGs nsg_application_gateway = network.NetworkSecurityGroup( f"{self._name}_nsg_application_gateway", + location=props.location, network_security_group_name=f"{stack_name}-nsg-application-gateway", resource_group_name=resource_group.name, security_rules=[ @@ -208,6 +209,7 @@ def __init__( ) nsg_apt_proxy_server = network.NetworkSecurityGroup( f"{self._name}_nsg_apt_proxy_server", + location=props.location, network_security_group_name=f"{stack_name}-nsg-apt-proxy-server", resource_group_name=resource_group.name, security_rules=[ @@ -303,6 +305,7 @@ def __init__( ) nsg_data_configuration = network.NetworkSecurityGroup( f"{self._name}_nsg_data_configuration", + location=props.location, network_security_group_name=f"{stack_name}-nsg-data-configuration", resource_group_name=resource_group.name, security_rules=[ @@ -398,6 +401,7 @@ def __init__( ) nsg_data_private = network.NetworkSecurityGroup( f"{self._name}_nsg_data_private", + location=props.location, network_security_group_name=f"{stack_name}-nsg-data-private", resource_group_name=resource_group.name, security_rules=[ @@ -457,6 +461,7 @@ def __init__( ) nsg_guacamole_containers = network.NetworkSecurityGroup( f"{self._name}_nsg_guacamole_containers", + location=props.location, network_security_group_name=f"{stack_name}-nsg-guacamole-containers", resource_group_name=resource_group.name, security_rules=[ @@ -588,6 +593,7 @@ def __init__( ) nsg_guacamole_containers_support = network.NetworkSecurityGroup( f"{self._name}_nsg_guacamole_containers_support", + location=props.location, network_security_group_name=f"{stack_name}-nsg-guacamole-containers-support", resource_group_name=resource_group.name, security_rules=[ @@ -647,6 +653,7 @@ def __init__( ) nsg_identity_containers = network.NetworkSecurityGroup( f"{self._name}_nsg_identity_containers", + location=props.location, network_security_group_name=f"{stack_name}-nsg-identity-containers", resource_group_name=resource_group.name, security_rules=[ @@ -766,6 +773,7 @@ def __init__( ) nsg_monitoring = network.NetworkSecurityGroup( f"{self._name}_nsg_monitoring", + location=props.location, network_security_group_name=f"{stack_name}-nsg-monitoring", resource_group_name=resource_group.name, security_rules=[ @@ -849,6 +857,7 @@ def __init__( ) nsg_user_services_containers = network.NetworkSecurityGroup( f"{self._name}_nsg_user_services_containers", + location=props.location, network_security_group_name=f"{stack_name}-nsg-user-services-containers", resource_group_name=resource_group.name, security_rules=[ @@ -956,6 +965,7 @@ def __init__( ) nsg_user_services_containers_support = network.NetworkSecurityGroup( f"{self._name}_nsg_user_services_containers_support", + location=props.location, network_security_group_name=f"{stack_name}-nsg-user-services-containers-support", resource_group_name=resource_group.name, security_rules=[ @@ -1015,6 +1025,7 @@ def __init__( ) nsg_user_services_databases = network.NetworkSecurityGroup( f"{self._name}_nsg_user_services_databases", + location=props.location, network_security_group_name=f"{stack_name}-nsg-user-services-databases", resource_group_name=resource_group.name, security_rules=[ @@ -1098,6 +1109,7 @@ def __init__( ) nsg_user_services_software_repositories = network.NetworkSecurityGroup( f"{self._name}_nsg_user_services_software_repositories", + location=props.location, network_security_group_name=f"{stack_name}-nsg-user-services-software-repositories", resource_group_name=resource_group.name, security_rules=[ @@ -1193,6 +1205,7 @@ def __init__( ) nsg_workspaces = network.NetworkSecurityGroup( f"{self._name}_nsg_workspaces", + location=props.location, network_security_group_name=f"{stack_name}-nsg-workspaces", resource_group_name=resource_group.name, security_rules=[ @@ -1398,6 +1411,7 @@ def __init__( address_prefixes=[SREIpRanges.vnet.prefix], ), dhcp_options=network.DhcpOptionsArgs(dns_servers=[props.dns_server_ip]), + location=props.location, resource_group_name=resource_group.name, # Note that we define subnets inline to avoid creation order issues subnets=[ From 0af9f339f468dc9aa2a296119e6f6f209df14392 Mon Sep 17 00:00:00 2001 From: James Robinson Date: Wed, 17 Jul 2024 12:21:12 +0100 Subject: [PATCH 2/8] :bug: Add location to PublicIPAddresses --- .../infrastructure/components/composite/virtual_machine.py | 1 + data_safe_haven/infrastructure/programs/declarative_sre.py | 1 + .../infrastructure/programs/sre/application_gateway.py | 3 +++ data_safe_haven/infrastructure/programs/sre/firewall.py | 2 ++ 4 files changed, 7 insertions(+) diff --git a/data_safe_haven/infrastructure/components/composite/virtual_machine.py b/data_safe_haven/infrastructure/components/composite/virtual_machine.py index 18ccdda00e..23ed562403 100644 --- a/data_safe_haven/infrastructure/components/composite/virtual_machine.py +++ b/data_safe_haven/infrastructure/components/composite/virtual_machine.py @@ -161,6 +161,7 @@ def __init__( if props.ip_address_public: public_ip = network.PublicIPAddress( f"{name_underscored}_public_ip", + location=props.location, public_ip_address_name=Output.concat(props.vm_name, "-public-ip"), public_ip_allocation_method="Static", resource_group_name=props.resource_group_name, diff --git a/data_safe_haven/infrastructure/programs/declarative_sre.py b/data_safe_haven/infrastructure/programs/declarative_sre.py index b4240c7d5a..1a44b99098 100644 --- a/data_safe_haven/infrastructure/programs/declarative_sre.py +++ b/data_safe_haven/infrastructure/programs/declarative_sre.py @@ -250,6 +250,7 @@ def __call__(self) -> None: SREApplicationGatewayProps( key_vault_certificate_id=data.sre_fqdn_certificate_secret_id, key_vault_identity=data.managed_identity, + location=self.config.azure.location, resource_group=networking.resource_group, subnet_application_gateway=networking.subnet_application_gateway, subnet_guacamole_containers=networking.subnet_guacamole_containers, diff --git a/data_safe_haven/infrastructure/programs/sre/application_gateway.py b/data_safe_haven/infrastructure/programs/sre/application_gateway.py index 5e211fbcd3..2adc6a4f58 100644 --- a/data_safe_haven/infrastructure/programs/sre/application_gateway.py +++ b/data_safe_haven/infrastructure/programs/sre/application_gateway.py @@ -23,12 +23,14 @@ def __init__( self, key_vault_certificate_id: Input[str], key_vault_identity: Input[managedidentity.UserAssignedIdentity], + location: Input[str], resource_group: Input[resources.ResourceGroup], sre_fqdn: Input[str], subnet_application_gateway: Input[network.GetSubnetResult], subnet_guacamole_containers: Input[network.GetSubnetResult], ) -> None: self.key_vault_certificate_id = key_vault_certificate_id + self.location = location self.resource_group_id = Output.from_input(resource_group).apply(get_id_from_rg) self.resource_group_name = Output.from_input(resource_group).apply( get_name_from_rg @@ -64,6 +66,7 @@ def __init__( # Define public IP address public_ip = network.PublicIPAddress( f"{self._name}_public_ip", + location=props.location, public_ip_address_name=f"{stack_name}-public-ip", public_ip_allocation_method=network.IpAllocationMethod.STATIC, resource_group_name=props.resource_group_name, diff --git a/data_safe_haven/infrastructure/programs/sre/firewall.py b/data_safe_haven/infrastructure/programs/sre/firewall.py index d274cc7176..10919400a8 100644 --- a/data_safe_haven/infrastructure/programs/sre/firewall.py +++ b/data_safe_haven/infrastructure/programs/sre/firewall.py @@ -77,6 +77,7 @@ def __init__( # Deploy IP address public_ip = network.PublicIPAddress( f"{self._name}_pip_firewall", + location=props.location, public_ip_address_name=f"{stack_name}-pip-firewall", public_ip_allocation_method=network.IPAllocationMethod.STATIC, resource_group_name=props.resource_group_name, @@ -92,6 +93,7 @@ def __init__( # from Microsoft. public_ip_management = network.PublicIPAddress( f"{self._name}_pip_firewall_management", + location=props.location, public_ip_address_name=f"{stack_name}-pip-firewall-management", public_ip_allocation_method=network.IPAllocationMethod.STATIC, resource_group_name=props.resource_group_name, From 04034b06fd4c3b6d91425451afd70fbaf1edcceb Mon Sep 17 00:00:00 2001 From: James Robinson Date: Wed, 17 Jul 2024 13:38:17 +0100 Subject: [PATCH 3/8] :white_check_mark: Fix SREApplicationGateway tests --- tests/infrastructure/programs/sre/test_application_gateway.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/infrastructure/programs/sre/test_application_gateway.py b/tests/infrastructure/programs/sre/test_application_gateway.py index ee2a989d90..0f20d83b28 100644 --- a/tests/infrastructure/programs/sre/test_application_gateway.py +++ b/tests/infrastructure/programs/sre/test_application_gateway.py @@ -15,6 +15,7 @@ @pytest.fixture def application_gateway_props( identity_key_vault_reader, + location, resource_group, sre_fqdn, subnet_application_gateway, @@ -23,6 +24,7 @@ def application_gateway_props( return SREApplicationGatewayProps( key_vault_certificate_id="key_vault_certificate_id", key_vault_identity=identity_key_vault_reader, + location=location, resource_group=resource_group, sre_fqdn=sre_fqdn, subnet_application_gateway=subnet_application_gateway, From affbbeaa4c17cfef0a47fbcfd4001b59d6a1f5b3 Mon Sep 17 00:00:00 2001 From: James Robinson Date: Wed, 17 Jul 2024 13:41:01 +0100 Subject: [PATCH 4/8] :bug: Add location specifiers to ContainerGroups --- data_safe_haven/infrastructure/programs/sre/apt_proxy_server.py | 1 + data_safe_haven/infrastructure/programs/sre/dns_server.py | 1 + data_safe_haven/infrastructure/programs/sre/gitea_server.py | 1 + data_safe_haven/infrastructure/programs/sre/hedgedoc_server.py | 1 + data_safe_haven/infrastructure/programs/sre/identity.py | 1 + data_safe_haven/infrastructure/programs/sre/remote_desktop.py | 1 + .../infrastructure/programs/sre/software_repositories.py | 1 + 7 files changed, 7 insertions(+) diff --git a/data_safe_haven/infrastructure/programs/sre/apt_proxy_server.py b/data_safe_haven/infrastructure/programs/sre/apt_proxy_server.py index 27bab973d5..e7a6e8ef66 100644 --- a/data_safe_haven/infrastructure/programs/sre/apt_proxy_server.py +++ b/data_safe_haven/infrastructure/programs/sre/apt_proxy_server.py @@ -148,6 +148,7 @@ def __init__( ], type=containerinstance.ContainerGroupIpAddressType.PRIVATE, ), + location=props.location, os_type=containerinstance.OperatingSystemTypes.LINUX, resource_group_name=resource_group.name, restart_policy=containerinstance.ContainerGroupRestartPolicy.ALWAYS, diff --git a/data_safe_haven/infrastructure/programs/sre/dns_server.py b/data_safe_haven/infrastructure/programs/sre/dns_server.py index da0daf9b81..ed6bfe7c0a 100644 --- a/data_safe_haven/infrastructure/programs/sre/dns_server.py +++ b/data_safe_haven/infrastructure/programs/sre/dns_server.py @@ -262,6 +262,7 @@ def __init__( ], type=containerinstance.ContainerGroupIpAddressType.PRIVATE, ), + location=props.location, os_type=containerinstance.OperatingSystemTypes.LINUX, resource_group_name=resource_group.name, restart_policy=containerinstance.ContainerGroupRestartPolicy.ALWAYS, diff --git a/data_safe_haven/infrastructure/programs/sre/gitea_server.py b/data_safe_haven/infrastructure/programs/sre/gitea_server.py index 40042fc346..71e312793c 100644 --- a/data_safe_haven/infrastructure/programs/sre/gitea_server.py +++ b/data_safe_haven/infrastructure/programs/sre/gitea_server.py @@ -297,6 +297,7 @@ def __init__( ], type=containerinstance.ContainerGroupIpAddressType.PRIVATE, ), + location=props.location, os_type=containerinstance.OperatingSystemTypes.LINUX, resource_group_name=props.user_services_resource_group_name, restart_policy=containerinstance.ContainerGroupRestartPolicy.ALWAYS, diff --git a/data_safe_haven/infrastructure/programs/sre/hedgedoc_server.py b/data_safe_haven/infrastructure/programs/sre/hedgedoc_server.py index e304406d7e..909a3dacef 100644 --- a/data_safe_haven/infrastructure/programs/sre/hedgedoc_server.py +++ b/data_safe_haven/infrastructure/programs/sre/hedgedoc_server.py @@ -277,6 +277,7 @@ def __init__( ], type=containerinstance.ContainerGroupIpAddressType.PRIVATE, ), + location=props.location, os_type=containerinstance.OperatingSystemTypes.LINUX, resource_group_name=props.user_services_resource_group_name, restart_policy=containerinstance.ContainerGroupRestartPolicy.ALWAYS, diff --git a/data_safe_haven/infrastructure/programs/sre/identity.py b/data_safe_haven/infrastructure/programs/sre/identity.py index 17eec8eca4..d8c22de970 100644 --- a/data_safe_haven/infrastructure/programs/sre/identity.py +++ b/data_safe_haven/infrastructure/programs/sre/identity.py @@ -216,6 +216,7 @@ def __init__( ], type=containerinstance.ContainerGroupIpAddressType.PRIVATE, ), + location=props.location, os_type=containerinstance.OperatingSystemTypes.LINUX, resource_group_name=resource_group.name, restart_policy=containerinstance.ContainerGroupRestartPolicy.ALWAYS, diff --git a/data_safe_haven/infrastructure/programs/sre/remote_desktop.py b/data_safe_haven/infrastructure/programs/sre/remote_desktop.py index 505d9d6ee2..80d009c95d 100644 --- a/data_safe_haven/infrastructure/programs/sre/remote_desktop.py +++ b/data_safe_haven/infrastructure/programs/sre/remote_desktop.py @@ -396,6 +396,7 @@ def __init__( ], type=containerinstance.ContainerGroupIpAddressType.PRIVATE, ), + location=props.location, os_type=containerinstance.OperatingSystemTypes.LINUX, resource_group_name=resource_group.name, restart_policy=containerinstance.ContainerGroupRestartPolicy.ALWAYS, diff --git a/data_safe_haven/infrastructure/programs/sre/software_repositories.py b/data_safe_haven/infrastructure/programs/sre/software_repositories.py index f81ef7c280..3d6b3bf747 100644 --- a/data_safe_haven/infrastructure/programs/sre/software_repositories.py +++ b/data_safe_haven/infrastructure/programs/sre/software_repositories.py @@ -278,6 +278,7 @@ def __init__( ], type=containerinstance.ContainerGroupIpAddressType.PRIVATE, ), + location=props.location, os_type=containerinstance.OperatingSystemTypes.LINUX, resource_group_name=props.user_services_resource_group_name, restart_policy=containerinstance.ContainerGroupRestartPolicy.ALWAYS, From e88beae57477458e3900968ddb53735aa1d6d43c Mon Sep 17 00:00:00 2001 From: James Robinson Date: Wed, 17 Jul 2024 13:44:55 +0100 Subject: [PATCH 5/8] :bug: Add location specifiers to ApplicationGateway --- .../infrastructure/programs/sre/application_gateway.py | 1 + 1 file changed, 1 insertion(+) diff --git a/data_safe_haven/infrastructure/programs/sre/application_gateway.py b/data_safe_haven/infrastructure/programs/sre/application_gateway.py index 2adc6a4f58..3ba13e0723 100644 --- a/data_safe_haven/infrastructure/programs/sre/application_gateway.py +++ b/data_safe_haven/infrastructure/programs/sre/application_gateway.py @@ -192,6 +192,7 @@ def __init__( type=network.ResourceIdentityType.USER_ASSIGNED, user_assigned_identities=props.user_assigned_identities, ), + location=props.location, redirect_configurations=[ # Guacamole HTTP redirect network.ApplicationGatewayRedirectConfigurationArgs( From f54ccf2339b3dc1d82ee90d522cca7a94455159a Mon Sep 17 00:00:00 2001 From: James Robinson Date: Wed, 17 Jul 2024 13:59:10 +0100 Subject: [PATCH 6/8] :bug: Ensure that PrivateEndpoints use location --- .../components/composite/microsoft_sql_database.py | 1 + .../infrastructure/components/composite/postgresql_database.py | 1 + 2 files changed, 2 insertions(+) diff --git a/data_safe_haven/infrastructure/components/composite/microsoft_sql_database.py b/data_safe_haven/infrastructure/components/composite/microsoft_sql_database.py index 952ff966ca..47f24b293f 100644 --- a/data_safe_haven/infrastructure/components/composite/microsoft_sql_database.py +++ b/data_safe_haven/infrastructure/components/composite/microsoft_sql_database.py @@ -82,6 +82,7 @@ def __init__( # Deploy a private endpoint for the PostgreSQL server private_endpoint = network.PrivateEndpoint( f"{self._name}_private_endpoint", + location=props.location, private_endpoint_name=Output.concat( props.database_server_name, "-endpoint" ), diff --git a/data_safe_haven/infrastructure/components/composite/postgresql_database.py b/data_safe_haven/infrastructure/components/composite/postgresql_database.py index 8723c5ac17..a817eb2974 100644 --- a/data_safe_haven/infrastructure/components/composite/postgresql_database.py +++ b/data_safe_haven/infrastructure/components/composite/postgresql_database.py @@ -95,6 +95,7 @@ def __init__( # Deploy a private endpoint for the PostgreSQL server private_endpoint = network.PrivateEndpoint( f"{self._name}_private_endpoint", + location=props.location, private_endpoint_name=Output.concat( props.database_server_name, "-endpoint" ), From a17d46734df36bcb951e5a6b528d1c698ca48ef9 Mon Sep 17 00:00:00 2001 From: James Robinson Date: Wed, 17 Jul 2024 14:00:09 +0100 Subject: [PATCH 7/8] :bug: Ensure that NetworkInterfaces use location --- .../infrastructure/components/composite/virtual_machine.py | 1 + 1 file changed, 1 insertion(+) diff --git a/data_safe_haven/infrastructure/components/composite/virtual_machine.py b/data_safe_haven/infrastructure/components/composite/virtual_machine.py index 23ed562403..dab0b86480 100644 --- a/data_safe_haven/infrastructure/components/composite/virtual_machine.py +++ b/data_safe_haven/infrastructure/components/composite/virtual_machine.py @@ -190,6 +190,7 @@ def __init__( **network_interface_ip_params, ) ], + location=props.location, network_interface_name=Output.concat(props.vm_name, "-nic"), resource_group_name=props.resource_group_name, opts=child_opts, From 2b58df1d6a55b2d532157b2995f137c3db0fd7cb Mon Sep 17 00:00:00 2001 From: James Robinson Date: Thu, 18 Jul 2024 10:09:42 +0100 Subject: [PATCH 8/8] :white_check_mark: Test for now-available location property on SREApplicationGatewayComponent --- .../infrastructure/programs/sre/test_application_gateway.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/infrastructure/programs/sre/test_application_gateway.py b/tests/infrastructure/programs/sre/test_application_gateway.py index 0f20d83b28..d250b72f40 100644 --- a/tests/infrastructure/programs/sre/test_application_gateway.py +++ b/tests/infrastructure/programs/sre/test_application_gateway.py @@ -408,10 +408,12 @@ def test_application_gateway_load_distribution_policies( @pulumi.runtime.test def test_application_gateway_location( - self, application_gateway_component: SREApplicationGatewayComponent + self, + application_gateway_component: SREApplicationGatewayComponent, + location: str, ): application_gateway_component.application_gateway.location.apply( - partial(assert_equal, None), + partial(assert_equal, location), run_with_unknowns=True, )