in stacks/data_sandbox_appstream.py [0:0]
def __init__(self, scope: core.Construct, id: str, aws_region='', vpc='', s3stack='', **kwargs) -> None:
super().__init__(scope, id, **kwargs)
#parameters
appstream_environment_name = self.node.try_get_context("appstream_environment_name")
appstream_image_name = self.node.try_get_context("appstream_image_name")
appstream_instance_type = self.node.try_get_context("appstream_instance_type")
appstream_fleet_type = self.node.try_get_context("appstream_fleet_type")
#build AppStream security
self.appstream_security_group = ec2.SecurityGroup(
self, 'AppStreamSecurityGroup',
vpc=vpc,
security_group_name='appstream-sg'
)
#build AppStream role
self.appstream_role = iam.Role(
self,
id='appstream-role',
description='Role for the AppStream fleet',
max_session_duration=core.Duration.seconds(3600),
assumed_by=iam.ServicePrincipal('appstream.amazonaws.com'),
inline_policies={
'AllowSSMAccess': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=['ssm:GetParameter'],
resources=['*']
)
]
),
'AllowS3Access': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=['s3:GetObject', 's3:ListBucket'],
resources=[f'arn:aws:s3:::{s3stack.bucket_name}/*',
f'arn:aws:s3:::{s3stack.bucket_name}']
)
]
)
}
)
appstream_fleet = appstream.CfnFleet(self, 'AppStreamFleet',
compute_capacity=appstream.CfnFleet.ComputeCapacityProperty(
desired_instances=5),
instance_type=appstream_instance_type,
fleet_type=appstream_fleet_type,
idle_disconnect_timeout_in_seconds=0,
disconnect_timeout_in_seconds=345600,
max_user_duration_in_seconds=345600,
image_name=appstream_image_name,
name=f'{appstream_environment_name}-fleet',
vpc_config=appstream.CfnFleet.VpcConfigProperty(
security_group_ids=[self.appstream_security_group.security_group_id],
subnet_ids=vpc.select_subnets(
subnet_type=ec2.SubnetType.ISOLATED).subnet_ids))
appstream_stack = appstream.CfnStack(self, 'AppStreamStack',
description='AppStream stack for Data Sandbox',
display_name='AppStream Data Sandbox Stack',
name=f'{appstream_environment_name}-stack',
storage_connectors=[appstream.CfnStack.StorageConnectorProperty(
connector_type='HOMEFOLDERS')],
user_settings=[{"action": "CLIPBOARD_COPY_FROM_LOCAL_DEVICE",
"permission": "ENABLED"},
{"action": "CLIPBOARD_COPY_TO_LOCAL_DEVICE",
"permission": "DISABLED"},
{"action": "FILE_DOWNLOAD", "permission": "DISABLED"},
{"action": "PRINTING_TO_LOCAL_DEVICE",
"permission": "DISABLED"}]
)
fleet_association = appstream.CfnStackFleetAssociation(self, 'AppStreamFleetAssociation',
fleet_name=f'{appstream_environment_name}-fleet',
stack_name=f'{appstream_environment_name}-stack'
)
fleet_association.add_depends_on(appstream_stack)
fleet_association.add_depends_on(appstream_fleet)
# Build Lambda Function Resources
# Define Lambda Function Policy
lambda_inline_policy = {
'AllowS3ListBkt': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=[
's3:ListBucket',
's3:ListBucketByTags',
's3:GetObject',
's3:PutObject'
],
resources=[f'arn:aws:s3:::appstream2-36fb080bb8-{Aws.REGION}-{Aws.ACCOUNT_ID}',
f'arn:aws:s3:::appstream2-36fb080bb8-{Aws.REGION}-{Aws.ACCOUNT_ID}/*']
)
]
),
'AllowLogGroup': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=[
'logs:PutRetentionPolicy'
],
resources=["*"]
)
]
),
'AllowNotebookAccess': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=['sagemaker:ListTags', 'sagemaker:ListNotebookInstances',
'sagemaker:CreatePresignedDomainUrl', 'sagemaker:CreatePresignedNotebookInstanceUrl'],
resources=[
f'arn:aws:sagemaker:{Aws.REGION}:{Aws.ACCOUNT_ID}:notebook-instance/data-sandbox-notebook']
)
]
)
}
# Build Lambda Role
lambda_role = iam.Role(
self,
id='lambda-role',
description='Role Data Sandbox lambda',
max_session_duration=core.Duration.seconds(3600),
role_name=f'data-sandbox-{Aws.REGION}-lambda-role',
assumed_by=iam.ServicePrincipal('lambda.amazonaws.com'),
managed_policies=[iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AWSLambdaBasicExecutionRole"),
iam.ManagedPolicy.from_aws_managed_policy_name("AmazonAppStreamReadOnlyAccess"),
iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMReadOnlyAccess")],
inline_policies=lambda_inline_policy
)
# Build Lambda Function
data_sandbox_lambda = _lambda.Function(self, 'DataSandboxLambda',
handler='data_sandbox_lambda.lambda_handler',
runtime=_lambda.Runtime.PYTHON_3_8,
code=_lambda.Code.asset(os.path.join(current_dir, '../lambda')),
role=lambda_role,
memory_size=256,
timeout=core.Duration.seconds(60),
log_retention=logs.RetentionDays.THREE_MONTHS,
log_retention_role=lambda_role
)
# Grant S3 access to invoke the lambda function
data_sandbox_lambda_permissions = _lambda.CfnPermission(self, 'LambdaPermissions',
principal='s3.amazonaws.com',
action="lambda:InvokeFunction",
source_arn=f"arn:aws:s3:::appstream2-36fb080bb8-{Aws.REGION}-{Aws.ACCOUNT_ID}",
function_name=data_sandbox_lambda.function_name,
source_account=f'{Aws.ACCOUNT_ID}'
)
#put bucket notification on AppStream homefolder
appstream_homefolder_bucket_array = [f'arn:aws:s3:::appstream2-36fb080bb8-{Aws.REGION}-{Aws.ACCOUNT_ID}']
appstream_homefolder_bucket_string = f'appstream2-36fb080bb8-{Aws.REGION}-{Aws.ACCOUNT_ID}'
s3_event_config_custom_sdk_policy = cr.AwsCustomResourcePolicy.from_statements(statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=['s3:PutBucketNotification'],
resources=appstream_homefolder_bucket_array
)
])
s3_event_config_custom_sdk_param = cr.AwsSdkCall(
action='putBucketNotificationConfiguration',
service='S3',
physical_resource_id=cr.PhysicalResourceId.of(id='s3EventNotification'),
parameters={
"Bucket": appstream_homefolder_bucket_string,
"NotificationConfiguration": {
"LambdaFunctionConfigurations": [
{
"Id": "string",
"LambdaFunctionArn": f"{data_sandbox_lambda.function_arn}",
"Events": ["s3:ObjectCreated:*"],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "suffix",
"Value": ".json"
}
]
}
}
}
]
}
}
)
s3_event_config_custom_sdk_delete_param = cr.AwsSdkCall(
action='putBucketNotificationConfiguration',
service='S3',
physical_resource_id=cr.PhysicalResourceId.of(id='s3EventNotification'),
parameters={
"Bucket": appstream_homefolder_bucket_string,
"NotificationConfiguration": {}
}
)
s3_event_custom_sdk_trigger = cr.AwsCustomResource(
self, 'custom-event-sdk',
on_create=s3_event_config_custom_sdk_param,
on_update=s3_event_config_custom_sdk_delete_param,
on_delete=s3_event_config_custom_sdk_delete_param,
policy=s3_event_config_custom_sdk_policy,
log_retention=logs.RetentionDays.THREE_MONTHS
)
#build custom resource to assign IAM role to AppStream fleet
appstream_fleet_iam_role_assignment_policy = cr.AwsCustomResourcePolicy.from_statements(statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=['appstream:UpdateFleet','iam:PassRole'],
resources=[f'arn:aws:appstream:{Aws.REGION}:{Aws.ACCOUNT_ID}:fleet/{appstream_environment_name}-fleet',f'{self.appstream_role.role_arn}']
)
])
appstream_fleet_iam_role_assignment_create = cr.AwsSdkCall(
action='updateFleet',
service='AppStream',
physical_resource_id=cr.PhysicalResourceId.of(id='AppStreamFeeltIAMRoleAssignementCreat'),
parameters={
"Name": appstream_fleet.name,
"IamRoleArn": self.appstream_role.role_arn
}
)
appstream_fleet_iam_role_assignment_trigger = cr.AwsCustomResource(
self, 'appstream-iam-role-assignment',
on_create=appstream_fleet_iam_role_assignment_create,
policy=appstream_fleet_iam_role_assignment_policy,
log_retention=logs.RetentionDays.THREE_MONTHS
)
#enable AppStream usage reports
appstream_usage_reports_policy = cr.AwsCustomResourcePolicy.from_statements(statements=[
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=['appstream:CreateUsageReportSubscription','appstream:DeleteUsageReportSubscription'],
resources=['*']
)
])
appstream_usage_reports_create = cr.AwsSdkCall(
action='createUsageReportSubscription',
service='AppStream',
physical_resource_id=cr.PhysicalResourceId.of(id='AppStreamUsageReports')
)
appstream_usage_reports_trigger = cr.AwsCustomResource(
self, 'appstream-usage-reports',
on_create=appstream_usage_reports_create,
policy=appstream_usage_reports_policy,
log_retention=logs.RetentionDays.THREE_MONTHS
)