Skip to content

Commit 106ba30

Browse files
Allenz5himani2411
andauthored
[Efs encryption][Draft] Support HeadNode Efs SharedStorage Encryption (#6914)
* [Efs Encryption] Add HeadNode/SharedStorageSettings/Encrypted * [Efs Encryption] Update SharedStorageEfsSettingsEncryptedValidator to check that SharedStorageEfsSettings can only be used when SharedStorageType is specified as Efs * [Efs Encryption] Add unit tests for SharedStorageEfsSettingsEncryptedValidator's behavior and registration * [Efs Encryption] Fix parameter name in cluster_schema.py * [Efs Encryption] Fix parameter naming * [Efs Encryption] Add more test cases in `test_shared_storage_efs_settings_validator` * [Efs Encryption] Update the comments of `SharedStorageEfsSettings` and `SharedStorageEfsSettingsSchema` class to make them clearer. * [Efs Encryption] Move SharedStorageType Enum from cluster_config.py to common.py. * [Efs Encryption] Change hardcoded ShareStorageType to an enum in the validator and unit test * [Efs Encryption] Fix format issues * [Efs Encryption] Move the addition of internal EFS shared storage away from _add_resources to decrease complexity * [Efs Encryption] Add SharedStorageEfsSettings section to the test_cluster_config_limits unit test * [Efs Encryption] Fix SharedStorageEfsSettingsValidator type issue * [Efs Encryption] Add id for unit tests of shared_storage_efs_settings_validator * [Efs Encryption] Remove setting default value of encrypted in cluster_stack.py * [Efs Encryption] Cover case where shared_storage_efs_settings is injected in test_slurm_all_validators_are_called * [Efs Encryption] Add unit test to verify EFS encryption in cluster stack * [Efs Encryption] Fix format issues * [Efs Encryption] Rename unit test for clarity * [Efs Encryption] Update test_internal_efs to verify that the internal shared efs is correctly encrypted * [Efs Encryption] Remove the unencrypted Efs shared storage test case from integration test * [Efs Encryption] Simplify the SharedStorageEfsSettingsValidator error message * [Efs Encryption] Simplify the SharedStorageEfsSettingsValidator error message * [Efs Encryption] Fix format issues * [Efs Encryption] Update CHANGELOG.md * [Efs Encryption] Update CHANGELOG.md --------- Co-authored-by: Himani Anil Deshpande <[email protected]>
1 parent 6d4e24d commit 106ba30

File tree

24 files changed

+284
-30
lines changed

24 files changed

+284
-30
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
- Support DCV on Amazon Linux 2023.
1111
- Upgrade Python runtime used by Lambda functions to python3.12 (from python3.9).
1212
- Remove `berkshelf`. All cookbooks are local and do not need `berkshelf` dependency management.
13+
- Add the configuration parameter `HeadNode/SharedStorageEfsSettings/Encrypted` to enable encryption on the EFS file system used for the head node internal shared storage.
1314

1415
**BUG FIXES**
1516
- Fix an issue where Security Group validation failed when a rule contained both IPv4 ranges (IpRanges) and security group references (UserIdGroupPairs).

cli/src/pcluster/config/cluster_config.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from pcluster.config.common import Imds as TopLevelImds
3434
from pcluster.config.common import (
3535
Resource,
36+
SharedStorageType,
3637
)
3738
from pcluster.constants import (
3839
CIDR_ALL_IPS,
@@ -114,6 +115,7 @@
114115
SchedulerValidator,
115116
SharedEbsPerformanceBottleNeckValidator,
116117
SharedFileCacheNotHomeValidator,
118+
SharedStorageEfsSettingsValidator,
117119
SharedStorageMountDirValidator,
118120
SharedStorageNameValidator,
119121
UnmanagedFsxMultiAzValidator,
@@ -291,15 +293,6 @@ def __init__(self, root_volume: RootVolume = None, ephemeral_volume: EphemeralVo
291293
self.ephemeral_volume = ephemeral_volume
292294

293295

294-
class SharedStorageType(Enum):
295-
"""Define storage types to be used as shared storage."""
296-
297-
EBS = "ebs"
298-
RAID = "raid"
299-
EFS = "efs"
300-
FSX = "fsx"
301-
302-
303296
class SharedEbs(Ebs):
304297
"""Represent a shared EBS, inherits from both _SharedStorage and Ebs classes."""
305298

@@ -851,6 +844,14 @@ def __init__(self, allowed_ips: str = None, **kwargs):
851844
self.allowed_ips = Resource.init_param(allowed_ips)
852845

853846

847+
class SharedStorageEfsSettings(Resource):
848+
"""Represent the settings of Efs shared storage used by HeadNode."""
849+
850+
def __init__(self, encrypted: bool = False):
851+
super().__init__()
852+
self.encrypted = encrypted
853+
854+
854855
class Dcv(Resource):
855856
"""Represent the DCV configuration."""
856857

@@ -1434,6 +1435,7 @@ def __init__(
14341435
disable_simultaneous_multithreading: bool = None,
14351436
local_storage: LocalStorage = None,
14361437
shared_storage_type: str = None,
1438+
shared_storage_efs_settings: SharedStorageEfsSettings = None,
14371439
dcv: Dcv = None,
14381440
custom_actions: CustomActions = None,
14391441
iam: Iam = None,
@@ -1452,6 +1454,7 @@ def __init__(
14521454
shared_storage_type,
14531455
default="Ebs",
14541456
)
1457+
self.shared_storage_efs_settings = shared_storage_efs_settings
14551458
self.dcv = dcv
14561459
self.custom_actions = custom_actions
14571460
self.iam = iam or Iam(implied=True)
@@ -1461,6 +1464,11 @@ def __init__(
14611464

14621465
def _register_validators(self, context: ValidatorContext = None): # noqa: D102 #pylint: disable=unused-argument
14631466
self._register_validator(InstanceTypeValidator, instance_type=self.instance_type)
1467+
self._register_validator(
1468+
SharedStorageEfsSettingsValidator,
1469+
shared_storage_type=self.shared_storage_type,
1470+
shared_storage_efs_settings=self.shared_storage_efs_settings,
1471+
)
14641472

14651473
@property
14661474
def architecture(self) -> str:

cli/src/pcluster/config/common.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,3 +434,12 @@ def dump_json(self):
434434
attribute_json = {"cluster": self._cluster_attributes}
435435
attribute_json.update(self._extra_attributes)
436436
return json.dumps(attribute_json, sort_keys=True)
437+
438+
439+
class SharedStorageType(Enum):
440+
"""Define storage types to be used as shared storage."""
441+
442+
EBS = "ebs"
443+
RAID = "raid"
444+
EFS = "efs"
445+
FSX = "fsx"

cli/src/pcluster/schemas/cluster_schema.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
SharedEbs,
8686
SharedEfs,
8787
SharedFsxLustre,
88+
SharedStorageEfsSettings,
8889
SlurmClusterConfig,
8990
SlurmComputeResource,
9091
SlurmComputeResourceNetworking,
@@ -792,6 +793,17 @@ def make_resource(self, data, **kwargs):
792793
return HeadNodeSsh(**data)
793794

794795

796+
class SharedStorageEfsSettingsSchema(BaseSchema):
797+
"""Represent the schema of SharedStorageEfsSettings for the HeadNode."""
798+
799+
encrypted = fields.Bool(metadata={"update_policy": UpdatePolicy.UNSUPPORTED})
800+
801+
@post_load
802+
def make_resource(self, data, **kwargs):
803+
"""Generate resource."""
804+
return SharedStorageEfsSettings(**data)
805+
806+
795807
class DcvSchema(BaseSchema):
796808
"""Represent the schema of DCV."""
797809

@@ -1363,6 +1375,9 @@ class HeadNodeSchema(BaseSchema):
13631375
metadata={"update_policy": UpdatePolicy.UNSUPPORTED},
13641376
validate=validate.OneOf(["Ebs", "Efs"]),
13651377
)
1378+
shared_storage_efs_settings = fields.Nested(
1379+
SharedStorageEfsSettingsSchema, metadata={"update_policy": UpdatePolicy.UNSUPPORTED}
1380+
)
13661381
dcv = fields.Nested(DcvSchema, metadata={"update_policy": UpdatePolicy.UNSUPPORTED})
13671382
custom_actions = fields.Nested(HeadNodeCustomActionsSchema, metadata={"update_policy": UpdatePolicy.IGNORED})
13681383
iam = fields.Nested(HeadNodeIamSchema, metadata={"update_policy": UpdatePolicy.SUPPORTED})

cli/src/pcluster/templates/awsbatch_builder.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
from aws_cdk.aws_ec2 import CfnSecurityGroup
2323
from aws_cdk.core import CfnOutput, CfnResource, Construct, Fn, Stack
2424

25-
from pcluster.config.cluster_config import AwsBatchClusterConfig, CapacityType, SharedStorageType
25+
from pcluster.config.cluster_config import AwsBatchClusterConfig, CapacityType
26+
from pcluster.config.common import SharedStorageType
2627
from pcluster.constants import AWSBATCH_CLI_REQUIREMENTS, CW_LOG_GROUP_NAME_PREFIX, IAM_ROLE_PATH
2728
from pcluster.models.s3_bucket import S3Bucket
2829
from pcluster.templates.cdk_builder_utils import (

cli/src/pcluster/templates/cdk_builder_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929
BaseQueue,
3030
HeadNode,
3131
LoginNodesPool,
32-
SharedStorageType,
3332
SlurmClusterConfig,
3433
SlurmComputeResource,
3534
SlurmQueue,
3635
)
36+
from pcluster.config.common import SharedStorageType
3737
from pcluster.constants import (
3838
COOKBOOK_PACKAGES_VERSIONS,
3939
CW_LOGS_RETENTION_DAYS_DEFAULT,

cli/src/pcluster/templates/cluster_stack.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,9 @@
5353
SharedEbs,
5454
SharedEfs,
5555
SharedFsxLustre,
56-
SharedStorageType,
5756
SlurmClusterConfig,
5857
)
59-
from pcluster.config.common import DefaultUserHomeType
58+
from pcluster.config.common import DefaultUserHomeType, SharedStorageType
6059
from pcluster.constants import (
6160
ALL_PORTS_RANGE,
6261
CW_ALARM_DATAPOINTS_TO_ALARM_DEFAULT,
@@ -264,12 +263,9 @@ def _add_resources(self):
264263
# Add the internal use shared storage to the stack
265264
# This FS will be mounted, the shared dirs will be added,
266265
# then it will be unmounted and the shared dirs will be
267-
# mounted. We need to create the additional mount points first.
266+
# mounted. We need to create the additional mount points first.
268267
if self.config.head_node.shared_storage_type.lower() == SharedStorageType.EFS.value:
269-
internal_efs_storage_shared = SharedEfs(
270-
mount_dir="/opt/parallelcluster/init_shared", name="internal_pcluster_shared", throughput_mode="elastic"
271-
)
272-
self._add_shared_storage(internal_efs_storage_shared)
268+
self._add_internal_efs_shared_storage()
273269

274270
# Add user configured shared storage
275271
if self.config.shared_storage:
@@ -335,6 +331,19 @@ def _add_resources(self):
335331
head_node_alarms=self.head_node_alarms,
336332
)
337333

334+
def _add_internal_efs_shared_storage(self):
335+
if self.config.head_node.shared_storage_efs_settings:
336+
encrypted = self.config.head_node.shared_storage_efs_settings.encrypted
337+
else:
338+
encrypted = None
339+
internal_efs_storage_shared = SharedEfs(
340+
mount_dir="/opt/parallelcluster/init_shared",
341+
name="internal_pcluster_shared",
342+
throughput_mode="elastic",
343+
encrypted=encrypted,
344+
)
345+
self._add_shared_storage(internal_efs_storage_shared)
346+
338347
def _cw_metric_head_node(
339348
self, namespace, metric_name, statistic="Maximum", period_seconds=CW_ALARM_PERIOD_DEFAULT, extra_dimensions=None
340349
):

cli/src/pcluster/templates/cw_dashboard_builder.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
from aws_cdk.aws_cloudwatch import IAlarm
1818
from aws_cdk.core import Construct, Duration, Stack
1919

20-
from pcluster.config.cluster_config import BaseClusterConfig, ExistingFileCache, SharedFsxLustre, SharedStorageType
20+
from pcluster.config.cluster_config import BaseClusterConfig, ExistingFileCache, SharedFsxLustre
21+
from pcluster.config.common import SharedStorageType
2122
from pcluster.constants import Feature
2223
from pcluster.utils import is_feature_supported
2324

cli/src/pcluster/templates/login_nodes_stack.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from aws_cdk.core import CfnTag, Construct, Fn, NestedStack, Stack, Tags
99

1010
from pcluster.aws.aws_api import AWSApi
11-
from pcluster.config.cluster_config import LoginNodesPool, SharedStorageType, SlurmClusterConfig
12-
from pcluster.config.common import DefaultUserHomeType
11+
from pcluster.config.cluster_config import LoginNodesPool, SlurmClusterConfig
12+
from pcluster.config.common import DefaultUserHomeType, SharedStorageType
1313
from pcluster.constants import (
1414
DEFAULT_EPHEMERAL_DIR,
1515
NODE_BOOTSTRAP_TIMEOUT,

cli/src/pcluster/templates/queues_stack.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
from constructs import Construct
88

99
from pcluster.aws.aws_api import AWSApi
10-
from pcluster.config.cluster_config import SharedStorageType, SlurmClusterConfig, SlurmComputeResource, SlurmQueue
11-
from pcluster.config.common import DefaultUserHomeType
10+
from pcluster.config.cluster_config import SlurmClusterConfig, SlurmComputeResource, SlurmQueue
11+
from pcluster.config.common import DefaultUserHomeType, SharedStorageType
1212
from pcluster.constants import (
1313
DEFAULT_EPHEMERAL_DIR,
1414
NODE_BOOTSTRAP_TIMEOUT,

0 commit comments

Comments
 (0)