def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=S3_LAMBDA_CONFIG_SCHEMA, configuration_received=self._configuration) # Defining S3 Bucket bucket_data = deepcopy(self._configuration["bucket"]) self._s3_bucket = base_bucket(self, **bucket_data) # Validating Lambda Function Runtime functions_data = self._configuration["lambda_handler"] self._lambda_function = base_lambda_function(self, **functions_data) # Defining the Lambda subscription to the specified S3 Bucket in cdk.json file. s3_events = self._configuration["events"] event_list = enum_parsing(source_list=s3_events, target_enum=s3.EventType) s3_subscription = events.S3EventSource(bucket=self._s3_bucket, events=event_list) self._lambda_function.add_event_source(source=s3_subscription)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case APIGATEWAY_FAN_OUT_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=LAMBDA_FUNCTIONS_CLUSTER_SCHEMA, configuration_received=self._configuration) # Define FAN-Out Lambda functions self._lambda_functions = list() for lambda_function in self._configuration["functions"]: _lambda = base_lambda_function(self, **lambda_function) self._lambda_functions.append(_lambda)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=USER_POOL_GROUPS_SCHEMA, configuration_received=self._configuration) self._groups_roles_list = list() for group_definition in self._configuration["user_pool_groups"]: role = base_service_role( self, resource_name=group_definition["role"]["name"], actions=group_definition["role"]["actions"], resources=group_definition["role"]["resources"], principal_resource=group_definition["role"]["principal"], ) kwargs["role_arn"] = role.role_arn user_group = base_cognito_user_groups(self, **kwargs) self._groups_roles_list.append({"user_group": user_group, "role": role})
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SQS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=SQS_CONFIG_SCHEMA, configuration_received=self._configuration) # Defining SQS Queue queue_data = deepcopy(self._configuration["queue"]) self._sqs_queue = base_queue(construct=self, **queue_data) # Validating Lambda Function Runtime functions_data = self._configuration["lambda_handlers"] self._lambda_functions = list() for lambda_function in functions_data: _lambda_function = base_lambda_function(self, **lambda_function) self._lambda_functions.append(_lambda_function) _lambda_function.add_event_source( lambda_sources.SqsEventSource(queue=self._sqs_queue, batch_size=10))
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SSM_PARAMETER_STRING. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=SSM_PARAMETER_STRING_SCHEMA, configuration_received=self._configuration) self._parameter_string = ssm.StringParameter( self, id="/" + self.prefix + "/" + self.environment_ + "/" + self._configuration["name"] + "/appConfig", parameter_name="/" + self.prefix + "/" + self.environment_ + "/" + self._configuration["name"] + "/appConfig", description=self._configuration.get("description"), string_value=json.dumps(self._configuration["string_value"]), type=ssm.ParameterType.STRING, )
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=SNS_CONFIG_SCHEMA, configuration_received=self._configuration) # Defining SNS Topic topic_data = deepcopy(self._configuration["topic"]) self._sns_topic = base_topic(self, **topic_data) # Validating Lambda Function Runtime functions_data = self._configuration["lambda_handlers"] self._lambda_functions = list() for lambda_function in functions_data: _lambda_function = base_lambda_function(self, **lambda_function) self._lambda_functions.append(_lambda_function) # Defining the Lambda subscription to the specified SNS Topic in cdk.json file. sns_subscription = sns_subs.LambdaSubscription(fn=_lambda_function) self._sns_topic.add_subscription(sns_subscription)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=IOT_LAMBDA_CONFIG_SCHEMA, configuration_received=self._configuration) # Validating Lambda Function Runtime functions_data = self._configuration["lambda_handler"] self._lambda_function = base_lambda_function(self, **functions_data) # Defining Topic Rule properties action = iot.CfnTopicRule.LambdaActionProperty( function_arn=self._lambda_function.function_arn) action_property = iot.CfnTopicRule.ActionProperty(lambda_=action) rule_data = self._configuration["iot_rule"] self._iot_rule = base_iot_rule(self, action_property=action_property, **rule_data)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=IOT_KINESIS_FIREHOSE_CONFIG_SCHEMA, configuration_received=self._configuration) # Defining Kinesis Stream stream_data = deepcopy(self._configuration["stream"]) self._kinesis_stream = base_kinesis_firehose_delivery_stream( self, **stream_data) # Defining IAM Role role = base_kinesis_role(self, resource_name=stream_data["stream_name"], principal_resource="iot") # Validating Lambda Function Runtime functions_data = self._configuration["lambda_handlers"] self._lambda_functions = list() for setting in functions_data: _lambda_function = base_lambda_function( self, **setting["lambda_handler"]) self._lambda_functions.append(_lambda_function) # Defining Function Subscription event_source = event_src.KinesisEventSource( stream=self._kinesis_stream, **setting["event_settings"]) _lambda_function.add_event_source(event_source) # Defining Topic Rule properties action = iot.CfnTopicRule.KinesisActionProperty( stream_name=self._kinesis_stream.stream_name, role_arn=role.role_arn) action_property = iot.CfnTopicRule.ActionProperty(kinesis=action) rule_data = self._configuration["iot_rule"] self._iot_rule = base_iot_rule(self, action_property=action_property, **rule_data)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=IOT_SNS_CONFIG_SCHEMA, configuration_received=self._configuration) # Defining SNS Topic topic_data = deepcopy(self._configuration["topic"]) self._sns_topic = base_topic(self, **topic_data) # Defining IAM Role role = base_sns_role(self, resource_name=topic_data["topic_name"], principal_resource="iot") # Validating Lambda Function Runtime functions_data = self._configuration["lambda_handlers"] self._lambda_functions = list() for lambda_function in functions_data: _lambda_function = base_lambda_function(self, **lambda_function) self._lambda_functions.append(_lambda_function) # Defining the Lambda subscription to the specified SNS Topic in cdk.json file. sns_subscription = sns_subs.LambdaSubscription(fn=_lambda_function) self._sns_topic.add_subscription(sns_subscription) # Defining Topic Rule properties action = iot.CfnTopicRule.SnsActionProperty( target_arn=self._sns_topic.topic_arn, role_arn=role.role_arn) action_property = iot.CfnTopicRule.ActionProperty(sns=action) rule_data = self._configuration["iot_rule"] self._iot_rule = base_iot_rule(self, action_property=action_property, **rule_data)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=SNS_CONFIG_SCHEMA, configuration_received=self._configuration)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=CLOUDWATCH_CONFIG_SCHEMA, configuration_received=self._configuration) rule_configuration = self._configuration["cloudwatch_rule"] rule_name = self.prefix + "_" + rule_configuration[ "rule_name"] + "_" + self.environment_ schedule = events.Schedule.expression( f"cron({rule_configuration['schedule']})") self._cloudwatch_event = events.Rule( self, id=rule_name, rule_name=rule_name, description=rule_configuration.get("description"), enabled=rule_configuration["enabled"], schedule=schedule, ) self._lambda_functions = list() for function_definition in self._configuration["lambda_handlers"]: function_ = base_lambda_function(self, **function_definition) self._cloudwatch_event.add_target( targets.LambdaFunction(handler=function_)) self._lambda_functions.append(function_)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=IOT_SQS_CONFIG_SCHEMA, configuration_received=self._configuration) # Defining SQS Queue queue_data = deepcopy(self._configuration["queue"]) self._sqs_queue = base_queue(construct=self, **queue_data) # Defining IAM Role role = base_sqs_role(self, resource_name=queue_data["queue_name"], principal_resource="iot") # Validating Lambda Function Runtime functions_data = self._configuration["lambda_handlers"] self._lambda_functions = list() for lambda_function in functions_data: _lambda_function = base_lambda_function(self, **lambda_function) self._lambda_functions.append(_lambda_function) _lambda_function.add_event_source(lambda_sources.SqsEventSource(queue=self._sqs_queue, batch_size=10)) # Defining Topic Rule properties action = iot.CfnTopicRule.SqsActionProperty(queue_url=self._sqs_queue.queue_url, role_arn=role.role_arn) action_property = iot.CfnTopicRule.ActionProperty(sqs=action) rule_data = self._configuration["iot_rule"] self._iot_rule = base_iot_rule(self, action_property=action_property, **rule_data)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case IOT_ANALYTICS_DATA_WORKFLOW. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=IOT_POLICY_SCHEMA, configuration_received=self._configuration) self._iot_policy = iot_.CfnPolicy( self, id=self.prefix + "_" + self._configuration["name"] + "_" + self.environment_, policy_name=self.prefix + "_" + self._configuration["name"] + "_" + self.environment_, policy_document=self._configuration["policy_document"], )
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case APIGATEWAY_FAN_OUT_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=S3_BUCKETS_CLUSTER_SCHEMA, configuration_received=self._configuration) # Define S3 Buckets Cluster self._s3_buckets = list() for bucket in self._configuration["buckets"]: _bucket = base_bucket(self, **bucket) self._s3_buckets.append(_bucket)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SAGEMAKER_NOTEBOOK. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=SAGEMAKER_NOTEBOOK_SCHEMA, configuration_received=configuration) base_name = self._configuration["name"] on_create_list = list() if validate_file( file_path=self._configuration["scripts"]["on_create"]): on_create_file = self._configuration["scripts"]["on_create"] else: on_create_file = file_path + "/scripts/iot_analytics_notebook/on_create.sh" with open(on_create_file) as on_create: on_create_contents = {"content": core.Fn.base64(on_create.read())} on_create_list.append(on_create_contents) on_start_list = list() if validate_file( file_path=self._configuration["scripts"]["on_create"]): on_start_file = self._configuration["scripts"]["on_start"] else: on_start_file = file_path + "/scripts/iot_analytics_notebook/on_start.sh" with open(on_start_file) as on_start: on_start_contents = {"content": core.Fn.base64(on_start.read())} on_start_list.append(on_start_contents) lifecycle_configuration_name = self.prefix + "-" + base_name + "lifecycle-" + self.environment_ self._lifecycle_configuration = sagemaker.CfnNotebookInstanceLifecycleConfig( self, id=lifecycle_configuration_name, notebook_instance_lifecycle_config_name= lifecycle_configuration_name, on_create=on_create_list, on_start=on_start_list, ) role_name = self.prefix + "_" + base_name + "sagemaker_role_" + self.environment_ self._role = iam.Role( self, id=role_name, role_name=role_name, assumed_by=iam.ServicePrincipal(service="sagemaker.amazonaws.com")) managed_policy = iam.ManagedPolicy.from_aws_managed_policy_name( managed_policy_name="AmazonSageMakerFullAccess") self._role.add_managed_policy(policy=managed_policy) policy_name = self.prefix + "_" + base_name + "sagemaker_policy" + self.environment_ ecr_statement = iam.PolicyStatement( actions=SAGEMAKER_POLICY["ecr_actions"], resources=SAGEMAKER_POLICY["ecr_resources"]) s3_statement = iam.PolicyStatement( actions=SAGEMAKER_POLICY["s3_actions"], resources=SAGEMAKER_POLICY["s3_resources"]) policy = iam.Policy(self, id=policy_name, policy_name=policy_name, statements=[ecr_statement, s3_statement]) self._role.attach_inline_policy(policy=policy) sagemaker_notebook_name = self.prefix + "_" + base_name + "sagemaker_notebook_" + self.environment_ self._sagemaker_notebook = sagemaker.CfnNotebookInstance( self, id=sagemaker_notebook_name, notebook_instance_name=sagemaker_notebook_name, lifecycle_config_name=self._lifecycle_configuration. notebook_instance_lifecycle_config_name, role_arn=self._role.role_arn, instance_type=self._configuration["instance_type"], )
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case APIGATEWAY_LAMBDA_SIMPLE_WEB_SERVICE_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=APIGATEWAY_SIMPLE_WEB_SERVICE_SCHEMA, configuration_received=self._configuration) # Define S3 Buckets Cluster if isinstance(self._configuration.get("buckets"), list): self._s3_buckets = [ base_bucket(self, **bucket) for bucket in self._configuration["buckets"] ] api_configuration = self._configuration["api"] # Define Lambda Authorizer Function authorizer_functions = api_configuration.get("authorizer_function") self._authorizer_function = None if authorizer_functions is not None: if authorizer_functions.get("imported") is not None: self._authorizer_function = lambda_.Function.from_function_arn( self, id=authorizer_functions.get("imported").get("identifier"), function_arn=authorizer_functions.get("imported").get( "arn"), ) elif authorizer_functions.get("origin") is not None: self._authorizer_function = base_lambda_function( self, **authorizer_functions.get("origin")) # Define API Gateway Authorizer gateway_authorizer = None if self._authorizer_function is not None: # Define Gateway Token Authorizer authorizer_name = api_configuration[ "apigateway_name"] + "_" + "authorizer" if authorizer_functions.get("results_cache_ttl") is not None: results_cache_ttl = core.Duration.minutes( authorizer_functions.get("results_cache_ttl")) else: results_cache_ttl = None gateway_authorizer = api_gateway.TokenAuthorizer( self, id=authorizer_name, authorizer_name=authorizer_name, handler=self._authorizer_function, results_cache_ttl=results_cache_ttl) # Defining Custom Domain domain_options = None custom_domain = api_configuration["root_resource"].get("custom_domain") if custom_domain is not None: domain_name = custom_domain["domain_name"] certificate_arn = custom_domain["certificate_arn"] domain_options = api_gateway.DomainNameOptions( certificate=cert_manager.Certificate.from_certificate_arn( self, id=domain_name, certificate_arn=certificate_arn), domain_name=domain_name, ) # Define API Gateway Lambda Handler self._handler_function = base_lambda_function( self, **api_configuration["root_resource"]["handler"]) if api_configuration["proxy"] is False and api_configuration.get( "root_resource").get("methods") is None: print( "Unable to check which method to use for the API! Use proxy: True or define methods..." ) raise RuntimeError self._lambda_rest_api = api_gateway.LambdaRestApi( self, id=api_configuration["apigateway_name"], rest_api_name=api_configuration["apigateway_name"], description=api_configuration["apigateway_description"], domain_name=domain_options, handler=self._handler_function, proxy=api_configuration["proxy"], cloud_watch_role=True, ) # Add Custom responses self._lambda_rest_api.add_gateway_response( f"{self.prefix}_4XXresponse_{self.environment_}", type=api_gateway.ResponseType.DEFAULT_4_XX, response_headers={"Access-Control-Allow-Origin": "'*'"}, ) self._lambda_rest_api.add_gateway_response( f"{self.prefix}_5XXresponse_{self.environment_}", type=api_gateway.ResponseType.DEFAULT_5_XX, response_headers={"Access-Control-Allow-Origin": "'*'"}, ) # Define Gateway Resource and Methods resource = self._lambda_rest_api.root.add_resource( api_configuration["root_resource"]["name"]) allowed_origins = api_configuration["root_resource"].get( "allowed_origins") if api_configuration["proxy"] is False: gateway_methods = api_configuration["root_resource"]["methods"] for method in gateway_methods: resource.add_method(http_method=method, authorizer=gateway_authorizer) if allowed_origins is not None: resource.add_cors_preflight(allow_origins=allowed_origins, allow_methods=gateway_methods) else: if allowed_origins is not None: resource.add_cors_preflight(allow_origins=allowed_origins)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case APIGATEWAY_LAMBDA_SIMPLE_WEB_SERVICE_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=APIGATEWAY_ASYNC_WEB_SERVICE_SCHEMA, configuration_received=self._configuration) # Define S3 Buckets Cluster if isinstance(self._configuration.get("buckets"), list): self._s3_buckets = [ base_bucket(self, **bucket) for bucket in self._configuration["buckets"] ] api_configuration = self._configuration["api"] # Define Lambda Authorizer Function authorizer_functions = api_configuration.get("authorizer_function") self._authorizer_function = None if authorizer_functions is not None: if authorizer_functions.get("imported") is not None: self._authorizer_function = lambda_.Function.from_function_arn( self, id=authorizer_functions.get("imported").get("identifier"), function_arn=authorizer_functions.get("imported").get( "arn"), ) elif authorizer_functions.get("origin") is not None: self._authorizer_function = base_lambda_function( self, **authorizer_functions.get("origin")) # Define NEW-FUNCTION Lambda Authorizers for lambda_function in authorizer_functions["origin"]: try: function_runtime = getattr(lambda_.Runtime, lambda_function["runtime"]) except Exception: raise WrongRuntimePassed( detail= f"Wrong function runtime {lambda_function['runtime']} specified", tb=traceback.format_exc()) obtainer_code_path = lambda_function.get("code_path") if obtainer_code_path is not None: code_path = obtainer_code_path elif obtainer_code_path is None and DEFAULT_LAMBDA_CODE_PATH_EXISTS is True: code_path = DEFAULT_LAMBDA_CODE_PATH else: raise RuntimeError( f"Code path for Lambda Function {lambda_function['lambda_name']} is not valid!" ) # Defining Lambda function _lambda_function = lambda_.Function( self, id=self.prefix + "_" + lambda_function["lambda_name"] + "_lambda_" + self.environment_, function_name=self.prefix + "_" + lambda_function["lambda_name"] + "_lambda_" + self.environment_, code=lambda_.Code.from_asset(path=code_path), handler=lambda_function["handler"], runtime=function_runtime, layers=None, description=lambda_function.get("description"), tracing=lambda_.Tracing.ACTIVE, environment=lambda_function.get("environment_vars"), timeout=core.Duration.seconds(lambda_function.get("timeout")), reserved_concurrent_executions=lambda_function.get( "reserved_concurrent_executions"), ) # Defining Lambda Function IAM policies to access other services self.iam_policies = list() for iam_actions in configuration["iam_actions"]: self.iam_policies.append(iam_actions) policy_statement = iam.PolicyStatement(actions=self.iam_policies, resources=["*"]) _lambda_function.add_to_role_policy(statement=policy_statement) self._authorizer_lambda_functions.append(_lambda_function)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case APIGATEWAY_FAN_OUT_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=S3_SPA_SIMPLE_PIPELINE_HOSTING_SCHEMA, configuration_received=self._configuration ) self._deployment_bucket = base_bucket(self, **self._configuration["hosting"]["bucket"]) artifact_bucket_name = ( f"{self.prefix}-{self._configuration['hosting']['bucket']['bucket_name']}-artifacts-{self.environment_}" ) artifact_bucket_config = {"bucket_name": artifact_bucket_name, "versioned": True, "public_read_access": False} self._deployment_artifact_bucket = base_bucket(self, **artifact_bucket_config) behaviour = cf.Behavior( is_default_behavior=self._configuration["hosting"]["cloudfront_distribution"]["origin_config"]["behaviours"][ "is_default_behavior" ] ) cloudfront_origins = cf.SourceConfiguration( behaviors=[behaviour], s3_origin_source=cf.S3OriginConfig(s3_bucket_source=self._deployment_bucket) ) self._cloudfront_distribution = cf.CloudFrontWebDistribution( self, id=self._configuration["hosting"]["cloudfront_distribution"]["name"], origin_configs=[cloudfront_origins], ) code_build_project_name = ( f"{self.prefix}-{self._configuration['pipeline']['stages']['build']['name']}-cbproject-{self.environment_}" ) self._codebuild_project = cb.Project( self, id=code_build_project_name, project_name=code_build_project_name, build_spec=cb.BuildSpec.from_object( { "version": self._configuration["pipeline"]["stages"]["build"].get("version", "0.2"), "phases": {"build": {"commands": self._configuration["pipeline"]["stages"]["build"]["commands"]}}, "artifacts": { "base-directory": self._configuration["pipeline"]["stages"]["build"]["build_directory"], "files": self._configuration["pipeline"]["stages"]["build"].get("files", "**/*"), }, } ), ) source_artifact = cp.Artifact(artifact_name="source_artifact") single_page_app_artifact = cp.Artifact(artifact_name="single_page_app_artifact") pipeline_name = f"{self.prefix}-{self._configuration['pipeline']['name']}-pipeline-{self.environment_}" self._s3_single_page_app_pipeline = cp.Pipeline( self, id=pipeline_name, pipeline_name=pipeline_name, artifact_bucket=self._deployment_artifact_bucket, ) self._s3_single_page_app_pipeline.add_stage( stage_name=self._configuration["pipeline"]["stages"]["github_source"]["name"], actions=[ cp_actions.GitHubSourceAction( action_name=self._configuration["pipeline"]["stages"]["github_source"]["name"], repo=self._configuration["pipeline"]["stages"]["github_source"]["repo"], owner=self._configuration["pipeline"]["stages"]["github_source"]["owner"], branch=self._configuration["pipeline"]["stages"]["github_source"]["branch"], oauth_token=core.SecretValue.secrets_manager( secret_id=self._configuration["pipeline"]["stages"]["github_source"]["oauth_token_secret_arn"], ), output=source_artifact, ) ], ) self._s3_single_page_app_pipeline.add_stage( stage_name=self._configuration["pipeline"]["stages"]["build"]["name"], actions=[ cp_actions.CodeBuildAction( action_name=self._configuration["pipeline"]["stages"]["build"]["name"], input=source_artifact, project=self._codebuild_project, outputs=[single_page_app_artifact], ) ], ) self._s3_single_page_app_pipeline.add_stage( stage_name=self._configuration["pipeline"]["stages"]["deploy"]["name"], actions=[ cp_actions.S3DeployAction( action_name=self._configuration["pipeline"]["stages"]["deploy"]["name"], bucket=self._deployment_bucket, input=single_page_app_artifact, ) ], )
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=USER_SERVERLESS_BACKEND_SCHEMA, configuration_received=self._configuration) # Define Lambda Authorizer Function authorizer_functions = self._configuration.get("authorizer_function") self._authorizer_function = None if authorizer_functions is not None: if authorizer_functions.get("imported") is not None: self._authorizer_function = lambda_.Function.from_function_arn( self, id=authorizer_functions.get("imported").get("identifier"), function_arn=authorizer_functions.get("imported").get("arn"), ) elif authorizer_functions.get("origin") is not None: self._authorizer_function = base_lambda_function(self, **authorizer_functions.get("origin")) # Define DynamoDB Tables self._dynamodb_tables_lambda_functions = list() for table in self._configuration.get("dynamo_tables", []): table, stream = base_dynamodb_table(self, **table) stream_lambda = None if stream is True and table["stream"].get("function") is not None: stream_lambda = base_lambda_function(self, **table["stream"]["function"]) # Add DynamoDB Stream Trigger to Lambda Function stream_lambda.add_event_source( source=event_sources.DynamoEventSource( table=table, starting_position=lambda_.StartingPosition.TRIM_HORIZON, batch_size=1 ) ) self._dynamodb_tables_lambda_functions.append({"table": table, "stream_lambda": stream_lambda}) # Define S3 Buckets Cluster if isinstance(self._configuration.get("buckets"), list): self._s3_buckets = [base_bucket(self, **bucket) for bucket in self._configuration["buckets"]] # Define Cognito User Pool user_pool_config = self._configuration["user_pool"] self._user_pool, self._user_pool_client = base_cognito_user_pool(self, **user_pool_config) if user_pool_config.get("identity_pool") is not None and self._user_pool_client is not None: self._identity_pool = base_cognito_user_identity_pool( self, user_pool_client_id=self._user_pool_client.user_pool_client_id, user_pool_provider_name=self._user_pool.user_pool_provider_name, **user_pool_config["identity_pool"], )
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case IOT_ANALYTICS_FAN_OUT. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=IOT_ANALYTICS_FAN_OUT_SCHEMA, configuration_received=self._configuration) # Defining Channel channel_data = self._configuration["channel"] channel_name = self.prefix + "_" + channel_data[ "name"] + "_channel_" + self.environment_ channel_retention_period = channel_data.get("channel_retention_period") self._channel = base_iot_analytics_channel( self, channel_name=channel_name, retention_period=channel_retention_period) self._datastore_pipes = list() resources_dependencies = list() for datastore_pipe in self._configuration["datastore_pipe_definition"]: extra_activities = datastore_pipe.get("extra_activities") base_name = datastore_pipe["name"] # Defining Datastore datastore_name = self.prefix + "_" + base_name + "_datastore_" + self.environment_ datastore_retention_period = datastore_pipe.get( "datastore_retention_period") datastore = base_iot_analytics_datastore( self, datastore_name=datastore_name, retention_period=datastore_retention_period) # Defining Pipeline Properties pipeline_name = self.prefix + "_" + base_name + "_pipeline_" + self.environment_ activities_dict = dict(channel=self._channel, datastore=datastore) individual_resources_dependencies = [self._channel, datastore] resources_dependencies.extend(individual_resources_dependencies) # Defining Pipeline pipeline = base_iot_analytics_pipeline( self, activities=activities_dict, resource_dependencies=individual_resources_dependencies, pipeline_name=pipeline_name, ) self._datastore_pipes.append( dict(datastore=datastore, pipeline=pipeline)) # Defining Datasets self._datasets = list() for dataset_configuration in self._configuration.get("datasets", []): dataset = base_iot_analytics_dataset( construct=self, resource_dependencies=resources_dependencies, **dataset_configuration) self._datasets.append(dataset)
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case APIGATEWAY_LAMBDA_SIMPLE_WEB_SERVICE_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=APIGATEWAY_ROBUST_WEB_SERVICE_SCHEMA, configuration_received=self._configuration) # Define S3 Buckets Cluster if isinstance(self._configuration.get("buckets"), list): self._s3_buckets = [ base_bucket(self, **bucket) for bucket in self._configuration["buckets"] ] api_configuration = self._configuration["api"] api_gateway_name = self.prefix + "_" + api_configuration[ "apigateway_name"] + "_" + self.environment_ api_gateway_name_description = api_configuration.get( "apigateway_description") # # Define Lambda Authorizer Function # authorizer_functions = api_configuration.get("authorizer_function") # self._authorizer_function = None # if authorizer_functions is not None: # if authorizer_functions.get("imported") is not None: # self._authorizer_function = lambda_.Function.from_function_arn( # self, # id=authorizer_functions.get("imported").get("identifier"), # function_arn=authorizer_functions.get("imported").get("arn"), # ) # elif authorizer_functions.get("origin") is not None: # self._authorizer_function = base_lambda_function(self, **authorizer_functions.get("origin")) # # # Define API Gateway Authorizer # gateway_authorizer = None # if self._authorizer_function is not None: # # Define Gateway Token Authorizer # authorizer_name = api_configuration["apigateway_name"] + "_" + "authorizer" # if authorizer_functions.get("results_cache_ttl") is not None: # results_cache_ttl = core.Duration.minutes(authorizer_functions.get("results_cache_ttl")) # else: # results_cache_ttl = None # gateway_authorizer = api_gateway.TokenAuthorizer( # self, # id=authorizer_name, # authorizer_name=authorizer_name, # handler=self._authorizer_function, # results_cache_ttl=results_cache_ttl # ) # # api_gateway.TokenAuthorizer # api_gateway.RequestAuthorizer # api_gateway.CognitoUserPoolsAuthorizer # Define API Gateway Authorizer self._authorizer_function = None self._gateway_authorizer = self.set_authorizer() # Defining Custom Domain domain_options = None custom_domain = api_configuration["settings"].get("custom_domain") if custom_domain is not None: domain_name = custom_domain["domain_name"] certificate_arn = custom_domain["certificate_arn"] domain_options = api_gateway.DomainNameOptions( certificate=cert_manager.Certificate.from_certificate_arn( self, id=domain_name, certificate_arn=certificate_arn), domain_name=domain_name, ) # Define API Gateway Lambda Handler self._handler_function = base_lambda_function( self, **api_configuration["settings"]["default_handler"]) # Validating Proxy configuration for API Gateway proxy_configuration = api_configuration["settings"]["proxy"] if proxy_configuration is False and api_configuration["settings"].get( "default_http_methods") is None: print( "Unable to check which method to use for the API! Use proxy: True or define methods..." ) raise RuntimeError # Defining allowed binary media types by API Gateway binary_media_types = api_configuration["settings"].get( "default_media_types") # Defining CORS preflight options default_cors_options = None default_cors_configuration = api_configuration["settings"].get( "default_cors_options") if default_cors_configuration is not None: default_cors_options = api_gateway.CorsOptions( allow_origins=default_cors_configuration["allow_origins"], allow_methods=["ANY"], status_code=default_cors_configuration["options_status_code"], ) # Defining STAGE Options default_stage_options = None default_stage_configuration = api_configuration["settings"].get( "default_stage_options") if default_stage_configuration is not None: logging_level = api_gateway.MethodLoggingLevel.ERROR logging_level_configuration = default_stage_configuration[ "logging_level"] for element in api_gateway.MethodLoggingLevel: if logging_level_configuration in str(element): logging_level = element default_stage_options = api_gateway.StageOptions( logging_level=logging_level, metrics_enabled=default_stage_configuration["metrics_enabled"], ) # Defining Rest API Gateway with Lambda Integration self._lambda_rest_api = api_gateway.LambdaRestApi( self, id=api_gateway_name, rest_api_name=api_gateway_name, description=api_gateway_name_description, domain_name=domain_options, handler=self._handler_function, proxy=proxy_configuration, binary_media_types=binary_media_types, default_cors_preflight_options=default_cors_options, cloud_watch_role=True, deploy_options=default_stage_options, ) # Add Custom responses self._lambda_rest_api.add_gateway_response( f"{self.prefix}_4XXresponse_{self.environment_}", type=api_gateway.ResponseType.DEFAULT_4_XX, response_headers={"Access-Control-Allow-Origin": "'*'"}, ) self._lambda_rest_api.add_gateway_response( f"{self.prefix}_5XXresponse_{self.environment_}", type=api_gateway.ResponseType.DEFAULT_5_XX, response_headers={"Access-Control-Allow-Origin": "'*'"}, ) # Define API Gateway Root Methods root_methods = api_configuration["settings"].get( "default_http_methods", list()) for method in root_methods: self._lambda_rest_api.root.add_method( http_method=method, authorizer=self._gateway_authorizer) # Defining Resource Trees for API Gateway with Custom Integrations resource_trees = api_configuration["resource_trees"] for resource_tree in resource_trees: resource_base = self._lambda_rest_api.root.add_resource( path_part=resource_tree["resource_name"]) resource_base_handler = base_lambda_function( self, **resource_tree["handler"]) for method in resource_tree["methods"]: resource_base.add_method( http_method=method, integration=api_gateway.LambdaIntegration( handler=resource_base_handler), authorizer=self._gateway_authorizer, ) # resource_base.add_cors_preflight(allow_methods=resource_tree["methods"], allow_origins=["*"]) resource_base_child_definition = resource_tree.get("child") if resource_base_child_definition is not None: resource_base_child = resource_base.add_resource( path_part=resource_base_child_definition["resource_name"]) resource_base_child_handler = base_lambda_function( self, **resource_base_child_definition["handler"]) for method in resource_base_child_definition["methods"]: resource_base_child.add_method( http_method=method, integration=api_gateway.LambdaIntegration( handler=resource_base_child_handler), authorizer=self._gateway_authorizer, ) # resource_base_child.add_cors_preflight( # allow_methods=resource_base_child_definition["methods"], allow_origins=["*"] # ) resource_base_child_trees = resource_base_child_definition.get( "childs", list()) for resource_base_grandchild_tree in resource_base_child_trees: resource_base_grandchild = resource_base_child.add_resource( path_part=resource_base_grandchild_tree[ "resource_name"]) resource_base_grandchild_handler = base_lambda_function( self, **resource_base_grandchild_tree["handler"]) for method in resource_base_grandchild_tree["methods"]: resource_base_grandchild.add_method( http_method=method, integration=api_gateway.LambdaIntegration( handler=resource_base_grandchild_handler), authorizer=self._gateway_authorizer, )
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration(configuration_schema=LAMBDA_LAYER_SCHEMA, configuration_received=self._configuration) layer_paths = self._configuration.get("paths") if layer_paths is not None: layer_code_path = layer_paths["layer_code_path"] layer_directory_path = layer_paths["layer_directory_path"] requirements_path = layer_paths["python_requirements_file_path"] else: if DEFAULT_LAMBDA_LAYER_CODE_PATH_EXISTS is True: layer_code_path = DEFAULT_LAMBDA_LAYER_CODE_PATH layer_directory_path = DEFAULT_LAMBDA_LAYER_CODE_INSTALL_PATH else: print( f"Code path for Lambda Layer {self._configuration['layer_name']} is not valid!" ) raise RuntimeError if DEFAULT_LAMBDA_LAYER_REQUIREMENTS_PATH_EXISTS is True: requirements_path = DEFAULT_LAMBDA_LAYER_REQUIREMENTS_PATH else: print( f"Lambda Python requirements path for Lambda Layer {self._configuration['layer_name']} is not valid!" ) raise RuntimeError subprocess_command = [ "docker", "run", "--rm", "-v", f"{os.environ.get('PWD')}:/foo", "-w", "/foo", "lambci/lambda:build-python3.7", "pip", "install", "-r", requirements_path, "-t", layer_directory_path, ] if self._configuration.get("dependencies", False) is False: subprocess_command.append("--no-dependencies") subprocess.call(subprocess_command) self._configuration["layer_code_path"] = layer_code_path self._lambda_layer = base_lambda_layer(self, **self._configuration)