Skip to content

Commit

Permalink
Merge pull request #1417 from jemrobinson/1414-shm-bastion
Browse files Browse the repository at this point in the history
Add SHM bastion
  • Loading branch information
jemrobinson authored Mar 14, 2023
2 parents 64a86c0 + e81a859 commit 2c45d3d
Show file tree
Hide file tree
Showing 21 changed files with 457 additions and 127 deletions.
9 changes: 0 additions & 9 deletions data_safe_haven/commands/deploy_shm_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,6 @@ def handle(self) -> int:
stack_yaml = yaml.safe_load(f_stack)
config.pulumi.stacks[stack.stack_name] = stack_yaml

# Add Pulumi secrets to the config file
for secret_name in [
"password-domain-admin",
"password-domain-azure-ad-connect",
"password-domain-ldap-searcher",
"password-update-server-linux-admin",
]:
config.add_secret(secret_name, stack.secret(secret_name))

# Upload config to blob storage
config.upload()

Expand Down
6 changes: 0 additions & 6 deletions data_safe_haven/commands/deploy_sre_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,6 @@ def handle(self) -> int:
stack_yaml = yaml.safe_load(f_stack)
config.pulumi.stacks[stack.stack_name] = stack_yaml

# Add Pulumi secrets to the config file
secret_name = "password-user-database-admin"
config.add_secret(
f"sre-{self.sre_name}-{secret_name}", stack.secret(secret_name)
)

# Upload config to blob storage
config.upload()

Expand Down
4 changes: 3 additions & 1 deletion data_safe_haven/provisioning/sre_provisioning_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ def __init__(
# Construct VM parameters
self.research_desktops = {}
for vm in sre_stack.output("research_desktops")["vm_outputs"]:
vm_short_name = [n for n in self.research_desktops.keys() if n in vm["name"]][0]
vm_short_name = [
n for n in self.research_desktops.keys() if n in vm["name"]
][0]
self.research_desktops[vm_short_name] = {
"cpus": int(available_vm_skus[vm["sku"]]["vCPUs"]),
"gpus": int(available_vm_skus[vm["sku"]]["GPUs"]),
Expand Down
Empty file.
27 changes: 27 additions & 0 deletions data_safe_haven/pulumi/common/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from enum import Enum


class NetworkingPriorities(int, Enum):
"""Priorities for network security group rules."""

# Azure services: 0 - 999
AZURE_CLOUD = 100
AZURE_GATEWAY_MANAGER = 200
AZURE_LOAD_BALANCER = 300
# Internal connections: 1000-1999
INTERNAL_SELF = 1000
INTERNAL_SHM_BASTION = 1100
INTERNAL_SHM_LDAP_TCP = 1200
INTERNAL_SHM_LDAP_UDP = 1250
INTERNAL_SHM_MONITORING_TOOLS = 1300
INTERNAL_SHM_UPDATE_SERVERS = 1400
INTERNAL_SRE_REMOTE_DESKTOP = 1500
INTERNAL_DSH_VIRTUAL_NETWORK = 1999
# Authorised external IPs: 2000-2999
AUTHORISED_EXTERNAL_ADMIN_IPS = 2000
AUTHORISED_EXTERNAL_USER_IPS = 2100
# Wider internet: 3000-3999
EXTERNAL_LINUX_UPDATES = 3600
EXTERNAL_INTERNET = 3999
# Deny all other: 4096
ALL_OTHER = 4096
File renamed without changes.
70 changes: 70 additions & 0 deletions data_safe_haven/pulumi/components/shm_bastion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Pulumi component for SHM monitoring"""
# Standard library import
from typing import Optional

# Third party imports
from pulumi import ComponentResource, Input, Output, ResourceOptions
from pulumi_azure_native import network

# Local imports
from data_safe_haven.helpers.functions import time_as_string


class SHMBastionProps:
"""Properties for SHMBastionComponent"""

def __init__(
self,
location: Input[str],
resource_group_name: Input[str],
subnet: Input[network.GetSubnetResult],
) -> None:
# self.automation_account_name = automation_account_name
self.location = location
self.resource_group_name = resource_group_name
self.subnet_id = Output.from_input(subnet).apply(lambda s: s.id)


class SHMBastionComponent(ComponentResource):
"""Deploy SHM bastion with Pulumi"""

def __init__(
self,
name: str,
stack_name: str,
shm_name: str,
props: SHMBastionProps,
opts: Optional[ResourceOptions] = None,
):
super().__init__("dsh:shm:SHMBastionComponent", name, {}, opts)
child_opts = ResourceOptions.merge(ResourceOptions(parent=self), opts)

# Deploy IP address
public_ip = network.PublicIPAddress(
f"{self._name}_pip_bastion",
public_ip_address_name=f"{stack_name}-pip-bastion",
public_ip_allocation_method=network.IPAllocationMethod.STATIC,
resource_group_name=props.resource_group_name,
sku=network.PublicIPAddressSkuArgs(
name=network.PublicIPAddressSkuName.STANDARD
),
opts=child_opts,
)

# Deploy bastion host
bastion_host = network.BastionHost(
f"{self._name}_bastion_host",
bastion_host_name=f"{stack_name}-bas",
ip_configurations=[
network.BastionHostIPConfigurationArgs(
public_ip_address=network.SubResourceArgs(id=public_ip.id),
subnet=network.SubResourceArgs(id=props.subnet_id),
name=f"{stack_name}-bas-ipcfg",
private_ip_allocation_method=network.IPAllocationMethod.DYNAMIC,
)
],
resource_group_name=props.resource_group_name,
)

# Register outputs
self.bastion_host = bastion_host
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# Local
from data_safe_haven.helpers import FileReader
from data_safe_haven.pulumi.transformations import get_name_from_subnet
from data_safe_haven.pulumi.common.transformations import get_name_from_subnet
from ..dynamic.remote_powershell import RemoteScript, RemoteScriptProps
from .automation_dsc_node import AutomationDscNode, AutomationDscNodeProps
from .virtual_machine import VMComponent, WindowsVMProps
Expand Down
30 changes: 6 additions & 24 deletions data_safe_haven/pulumi/components/shm_firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pulumi_azure_native import network

# Local imports
from data_safe_haven.pulumi.transformations import get_id_from_subnet
from data_safe_haven.pulumi.common.transformations import get_id_from_subnet


class SHMFirewallProps:
Expand Down Expand Up @@ -76,9 +76,11 @@ def __init__(
public_ip = network.PublicIPAddress(
f"{self._name}_pip_firewall",
public_ip_address_name=f"{stack_name}-pip-firewall",
public_ip_allocation_method="Static",
public_ip_allocation_method=network.IPAllocationMethod.STATIC,
resource_group_name=props.resource_group_name,
sku=network.PublicIPAddressSkuArgs(name="Standard"),
sku=network.PublicIPAddressSkuArgs(
name=network.PublicIPAddressSkuName.STANDARD
),
opts=child_opts,
)

Expand Down Expand Up @@ -1072,27 +1074,6 @@ def __init__(
)
],
location=props.location,
nat_rule_collections=[
network.AzureFirewallNatRuleCollectionArgs(
action=network.AzureFirewallNatRCActionArgs(type="Dnat"),
name="RDPTrafficToDomainController",
priority=100,
rules=[
network.AzureFirewallNatRuleArgs(
description="Redirect RDP traffic to domain controller",
destination_addresses=public_ip.ip_address.apply(
lambda ip: [ip] if ip else []
),
destination_ports=["3389"],
name="dc-rdp-traffic",
protocols=["TCP"],
source_addresses=["*"],
translated_address=props.domain_controller_private_ip,
translated_port="3389",
),
],
)
],
network_rule_collections=[
network.AzureFirewallNetworkRuleCollectionArgs(
action=network.AzureFirewallRCActionArgs(type="Allow"),
Expand Down Expand Up @@ -1176,3 +1157,4 @@ def __init__(
self.external_dns_resolver = external_dns_resolver
self.ntp_fqdns = ntp_fqdns
self.ntp_ip_addresses = ntp_ip_addresses
self.public_ip_id = public_ip.id
2 changes: 1 addition & 1 deletion data_safe_haven/pulumi/components/shm_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
replace_separators,
time_as_string,
)
from data_safe_haven.pulumi.transformations import get_id_from_subnet
from data_safe_haven.pulumi.common.transformations import get_id_from_subnet


class SHMMonitoringProps:
Expand Down
Loading

0 comments on commit 2c45d3d

Please sign in to comment.