From 5c23102499db8b5dd2737a1a763b1d942e044047 Mon Sep 17 00:00:00 2001 From: Jim Madge Date: Tue, 17 Sep 2024 10:28:12 +0100 Subject: [PATCH] Add NFSV3StorageAccount component --- .../infrastructure/components/__init__.py | 2 + .../components/wrapped/__init__.py | 2 + .../infrastructure/programs/sre/data.py | 43 ++----------------- .../programs/sre/desired_state.py | 42 ++---------------- 4 files changed, 12 insertions(+), 77 deletions(-) diff --git a/data_safe_haven/infrastructure/components/__init__.py b/data_safe_haven/infrastructure/components/__init__.py index cc6bcb15a4..5273fade9b 100644 --- a/data_safe_haven/infrastructure/components/__init__.py +++ b/data_safe_haven/infrastructure/components/__init__.py @@ -19,6 +19,7 @@ SSLCertificateProps, ) from .wrapped import ( + NFSV3StorageAccount, WrappedLogAnalyticsWorkspace, ) @@ -34,6 +35,7 @@ "LocalDnsRecordProps", "MicrosoftSQLDatabaseComponent", "MicrosoftSQLDatabaseProps", + "NFSV3StorageAccount", "PostgresqlDatabaseComponent", "PostgresqlDatabaseProps", "SSLCertificate", diff --git a/data_safe_haven/infrastructure/components/wrapped/__init__.py b/data_safe_haven/infrastructure/components/wrapped/__init__.py index fc5f8c8f61..48c5570168 100644 --- a/data_safe_haven/infrastructure/components/wrapped/__init__.py +++ b/data_safe_haven/infrastructure/components/wrapped/__init__.py @@ -1,5 +1,7 @@ from .log_analytics_workspace import WrappedLogAnalyticsWorkspace +from .nfsv3_storage_account import NFSV3StorageAccount __all__ = [ + "NFSV3StorageAccount", "WrappedLogAnalyticsWorkspace", ] diff --git a/data_safe_haven/infrastructure/programs/sre/data.py b/data_safe_haven/infrastructure/programs/sre/data.py index cff4045db3..6cf5edb869 100644 --- a/data_safe_haven/infrastructure/programs/sre/data.py +++ b/data_safe_haven/infrastructure/programs/sre/data.py @@ -31,6 +31,7 @@ from data_safe_haven.infrastructure.components import ( BlobContainerAcl, BlobContainerAclProps, + NFSV3StorageAccount, SSLCertificate, SSLCertificateProps, ) @@ -459,52 +460,16 @@ def __init__( # Deploy sensitive data blob storage account # - This holds the /data and /output containers that are mounted by workspaces # - Azure blobs have worse NFS support but can be accessed with Azure Storage Explorer - storage_account_data_private_sensitive = storage.StorageAccount( + storage_account_data_private_sensitive = NFSV3StorageAccount( f"{self._name}_storage_account_data_private_sensitive", # Storage account names have a maximum of 24 characters account_name=alphanumeric( f"{''.join(truncate_tokens(stack_name.split('-'), 11))}sensitivedata{sha256hash(self._name)}" )[:24], - enable_https_traffic_only=True, - enable_nfs_v3=True, - encryption=storage.EncryptionArgs( - key_source=storage.KeySource.MICROSOFT_STORAGE, - services=storage.EncryptionServicesArgs( - blob=storage.EncryptionServiceArgs( - enabled=True, key_type=storage.KeyType.ACCOUNT - ), - file=storage.EncryptionServiceArgs( - enabled=True, key_type=storage.KeyType.ACCOUNT - ), - ), - ), - kind=storage.Kind.BLOCK_BLOB_STORAGE, - is_hns_enabled=True, + allowed_ip_addresses=props.data_private_sensitive_ip_addresses, location=props.location, - minimum_tls_version=storage.MinimumTlsVersion.TLS1_2, - network_rule_set=storage.NetworkRuleSetArgs( - bypass=storage.Bypass.AZURE_SERVICES, - default_action=storage.DefaultAction.DENY, - ip_rules=Output.from_input( - props.data_private_sensitive_ip_addresses - ).apply( - lambda ip_ranges: [ - storage.IPRuleArgs( - action=storage.Action.ALLOW, - i_p_address_or_range=str(ip_address), - ) - for ip_range in sorted(ip_ranges) - for ip_address in AzureIPv4Range.from_cidr(ip_range).all_ips() - ] - ), - virtual_network_rules=[ - storage.VirtualNetworkRuleArgs( - virtual_network_resource_id=props.subnet_data_private_id, - ) - ], - ), + subnet_id=props.subnet_data_private_id, resource_group_name=props.resource_group_name, - sku=storage.SkuArgs(name=storage.SkuName.PREMIUM_ZRS), opts=child_opts, tags=child_tags, ) diff --git a/data_safe_haven/infrastructure/programs/sre/desired_state.py b/data_safe_haven/infrastructure/programs/sre/desired_state.py index 8700939af0..8e1fc6c8a0 100644 --- a/data_safe_haven/infrastructure/programs/sre/desired_state.py +++ b/data_safe_haven/infrastructure/programs/sre/desired_state.py @@ -17,7 +17,6 @@ storage, ) -from data_safe_haven.external import AzureIPv4Range from data_safe_haven.functions import ( alphanumeric, replace_separators, @@ -32,6 +31,7 @@ from data_safe_haven.infrastructure.components import ( BlobContainerAcl, BlobContainerAclProps, + NFSV3StorageAccount, ) from data_safe_haven.resources import resources_path from data_safe_haven.types import AzureDnsZoneNames @@ -84,49 +84,15 @@ def __init__( # Deploy desired state storage account # - This holds the /desired_state container that is mounted by workspaces # - Azure blobs have worse NFS support but can be accessed with Azure Storage Explorer - storage_account = storage.StorageAccount( + storage_account = NFSV3StorageAccount( f"{self._name}_storage_account", - # Storage account names have a maximum of 24 characters account_name=alphanumeric( f"{''.join(truncate_tokens(stack_name.split('-'), 11))}desiredstate{sha256hash(self._name)}" )[:24], - enable_https_traffic_only=True, - enable_nfs_v3=True, - encryption=storage.EncryptionArgs( - key_source=storage.KeySource.MICROSOFT_STORAGE, - services=storage.EncryptionServicesArgs( - blob=storage.EncryptionServiceArgs( - enabled=True, key_type=storage.KeyType.ACCOUNT - ), - file=storage.EncryptionServiceArgs( - enabled=True, key_type=storage.KeyType.ACCOUNT - ), - ), - ), - kind=storage.Kind.BLOCK_BLOB_STORAGE, - is_hns_enabled=True, + allowed_ip_addresses=props.admin_ip_addresses, location=props.location, - network_rule_set=storage.NetworkRuleSetArgs( - bypass=storage.Bypass.AZURE_SERVICES, - default_action=storage.DefaultAction.DENY, - ip_rules=Output.from_input(props.admin_ip_addresses).apply( - lambda ip_ranges: [ - storage.IPRuleArgs( - action=storage.Action.ALLOW, - i_p_address_or_range=str(ip_address), - ) - for ip_range in sorted(ip_ranges) - for ip_address in AzureIPv4Range.from_cidr(ip_range).all_ips() - ] - ), - virtual_network_rules=[ - storage.VirtualNetworkRuleArgs( - virtual_network_resource_id=props.subnet_desired_state_id, - ) - ], - ), resource_group_name=props.resource_group_name, - sku=storage.SkuArgs(name=storage.SkuName.PREMIUM_ZRS), + subnet_id=props.subnet_desired_state_id, opts=child_opts, tags=child_tags, )