Beispiel #1
0
 def _create_user_pool(self) -> cognito.UserPool:
     pool = cognito.UserPool(
         scope=self,
         id="orbit-user-pool",
         account_recovery=cognito.AccountRecovery.EMAIL_ONLY,
         auto_verify=cognito.AutoVerifiedAttrs(email=True, phone=False),
         custom_attributes=None,
         email_settings=None,
         lambda_triggers=None,
         mfa=cognito.Mfa.OFF,
         mfa_second_factor=None,
         password_policy=cognito.PasswordPolicy(
             min_length=8,
             require_digits=True,
             require_lowercase=True,
             require_symbols=True,
             require_uppercase=True,
             temp_password_validity=Duration.days(5),
         ),
         self_sign_up_enabled=False,
         sign_in_aliases=cognito.SignInAliases(email=True,
                                               phone=False,
                                               preferred_username=False,
                                               username=True),
         sign_in_case_sensitive=True,
         sms_role=None,
         sms_role_external_id=None,
         standard_attributes=cognito.StandardAttributes(
             email=cognito.StandardAttribute(required=True, mutable=True)),
         user_invitation=cognito.UserInvitationConfig(
             email_subject="Invite to join Orbit Workbench!",
             email_body=
             "Hello, you have been invited to join Orbit Workbench!<br/><br/>"
             "Username: {username}<br/>"
             "Temporary password: {####}<br/><br/>"
             "Regards",
         ),
         user_pool_name=f"orbit-{self.env_name}-user-pool",
     )
     pool.apply_removal_policy(policy=core.RemovalPolicy.DESTROY)
     pool.add_domain(
         id="orbit-user-pool-domain",
         cognito_domain=cognito.CognitoDomainOptions(
             domain_prefix=f"orbit-{self.context.account_id}-{self.env_name}"
         ),
     )
     return pool
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        servu_userpool = aws_cognito.UserPool(
            self,
            'servu-userpool',
            user_pool_name='ServU Users',
            sign_in_aliases=aws_cognito.SignInAliases(email=True),
            standard_attributes=aws_cognito.StandardAttributes(
                email=aws_cognito.StandardAttribute(required=True,
                                                    mutable=True),
                fullname=aws_cognito.StandardAttribute(required=True,
                                                       mutable=True),
                address=aws_cognito.StandardAttribute(required=True,
                                                      mutable=True),
                phone_number=aws_cognito.StandardAttribute(required=True,
                                                           mutable=True)),
            password_policy=aws_cognito.PasswordPolicy(
                min_length=8,
                require_digits=True,
                require_lowercase=True,
                require_symbols=True,
                require_uppercase=True,
                temp_password_validity=core.Duration.days(1)),
            sign_in_case_sensitive=False)

        servu_userpool_web_client = aws_cognito.UserPoolClient(
            self,
            'servu-userpool-web-client',
            user_pool=servu_userpool,
            auth_flows=aws_cognito.AuthFlow(custom=True,
                                            refresh_token=True,
                                            user_srp=True),
            user_pool_client_name='ServU Web Client')

        # TODO: Manually configure the domain and callback URLs. Look at CFN for the Pool ID and Client ID
        core.CfnOutput(self,
                       'servu-userpool-id',
                       value=servu_userpool.user_pool_id,
                       export_name='servu-userpool-id')

        core.CfnOutput(self,
                       'servu-userpool-client-id',
                       value=servu_userpool_web_client.user_pool_client_id,
                       export_name='servu-userpool-client-id')
    def __init__(self, scope: core.Construct, construct_id: str,
                 **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # -----------------------------------
        #           Cognito User Pool
        # -----------------------------------
        userpool = cognito.UserPool(
            self,
            "ServerlessTodoUserPool",
            user_pool_name="ServerlessTodoUserPool",
            sign_in_aliases=cognito.SignInAliases(username=True, email=True),
            password_policy=cognito.PasswordPolicy(
                min_length=6,
                require_digits=True,
                require_lowercase=True,
                require_symbols=True,
                require_uppercase=True,
                temp_password_validity=core.Duration.days(7)),
            auto_verify=cognito.AutoVerifiedAttrs(email=True),
            standard_attributes=cognito.StandardAttributes(
                email=cognito.StandardAttribute(mutable=True, required=True),
                family_name=cognito.StandardAttribute(mutable=True,
                                                      required=True),
                given_name=cognito.StandardAttribute(mutable=True,
                                                     required=True)))
        user_pool_client = userpool.add_client(
            "UserPoolClient",
            auth_flows=cognito.AuthFlow(admin_user_password=True))

        # -----------------------------------
        #           dynamodb
        # -----------------------------------
        dynamodbTable = dynamodb.Table(
            self,
            "TaskTable",
            partition_key=dynamodb.Attribute(
                name="id", type=dynamodb.AttributeType.STRING),
            sort_key=dynamodb.Attribute(name="meta",
                                        type=dynamodb.AttributeType.STRING),
            billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST,
            point_in_time_recovery=True,
            server_side_encryption=True)
        dynamodbTable.add_global_secondary_index(
            partition_key=dynamodb.Attribute(
                name="meta", type=dynamodb.AttributeType.STRING),
            sort_key=dynamodb.Attribute(name="id",
                                        type=dynamodb.AttributeType.STRING),
            index_name="meta-id-index")
        dynamodbTable.add_global_secondary_index(
            partition_key=dynamodb.Attribute(
                name="owner", type=dynamodb.AttributeType.STRING),
            sort_key=dynamodb.Attribute(name="meta",
                                        type=dynamodb.AttributeType.STRING),
            index_name="owner-meta-index")

        # -----------------------------------
        #             apigateway
        # -----------------------------------
        acm_arn = self.node.try_get_context('acm_arn')
        domain_name = self.node.try_get_context("domain_name")
        hosted_zone = self.node.try_get_context("hosted_zone")

        api_policy = iam.PolicyDocument(
            statements=iam.PolicyStatement(actions=["lambda:InvokeFunction"], )
            .add_resources("arn:aws:lambda:{}:{}:function:*".format(
                self.region, self.account)))

        if acm_arn and domain_name and hosted_zone:

            api = apigw.RestApi(
                self,
                'API',
                domain_name=apigw.DomainNameOptions(
                    certificate=acm.Certificate.from_certificate_arn(
                        self, 'ApiCertificate', acm_arn),
                    domain_name=domain_name,
                    endpoint_type=apigw.EndpointType.REGIONAL),
                deploy_options=apigw.StageOptions(metrics_enabled=True),
                policy=api_policy,
                rest_api_name="Serverless TODO API",
                endpoint_types=[apigw.EndpointType.REGIONAL],
                default_cors_preflight_options=apigw.CorsOptions(
                    allow_origins=apigw.Cors.
                    ALL_ORIGINS,  # TODO: Temporary for development
                    allow_headers=[
                        "Content-Type", "X-Amz-Date", "Authorization",
                        "X-Api-Key", "X-Amz-Security-Token", "X-Tracing-Id",
                        "x-jeffy-correlation-id", "x-amzn-trace-id"
                    ],
                    allow_methods=apigw.Cors.ALL_METHODS,
                    allow_credentials=True))
            route53.CfnRecordSet(
                self,
                "apiDomainRecord",
                name=domain_name,
                type="A",
                alias_target={
                    "dnsName":
                    api.domain_name.domain_name_alias_domain_name,
                    "hostedZoneId":
                    api.domain_name.domain_name_alias_hosted_zone_id
                },
                hosted_zone_id=hosted_zone,
            )
        else:
            api = apigw.RestApi(
                self,
                'API',
                deploy_options=apigw.StageOptions(metrics_enabled=True),
                policy=api_policy,
                rest_api_name="Serverless TODO API",
                endpoint_types=[apigw.EndpointType.REGIONAL],
                default_cors_preflight_options=apigw.CorsOptions(
                    allow_origins=apigw.Cors.
                    ALL_ORIGINS,  # TODO: Temporary for development
                    allow_headers=[
                        "Content-Type", "X-Amz-Date", "Authorization",
                        "X-Api-Key", "X-Amz-Security-Token", "X-Tracing-Id",
                        "x-jeffy-correlation-id", "x-amzn-trace-id"
                    ],
                    allow_methods=apigw.Cors.ALL_METHODS,
                    allow_credentials=True))

        cognito_authorizer = apigw.CognitoUserPoolsAuthorizer(
            self,
            "CognitoAuthorizer",
            cognito_user_pools=[userpool],
            authorizer_name='todo_cognito_authorizer',
            identity_source='method.request.header.Authorization',
            results_cache_ttl=core.Duration.minutes(60))

        api_role = iam.Role(self,
                            "ApiRole",
                            assumed_by=iam.ServicePrincipal(
                                service="apigateway.amazonaws.com"))
        api_statement = iam.PolicyStatement(
            actions=["lambda:InvokeFunction"],
            resources=[
                "arn:aws:lambda:{}:{}:function:*".format(
                    self.region, self.account)
            ])
        api_role.add_to_policy(api_statement)

        # -----------------------------------
        #      lambda common configure
        # -----------------------------------
        env = {
            "TABLE_NAME": dynamodbTable.table_name,
            "USER_POOL_ID": userpool.user_pool_id,
            "USER_POOL_NAME": userpool.user_pool_provider_name,
            "CLIENT_ID": user_pool_client.user_pool_client_id
        }

        # -----------------------------------
        #           get handler
        # -----------------------------------
        get_resource_base_name = "getTaskFunction"
        get_task_func = lambda_.Function(
            self,
            get_resource_base_name,
            code=lambda_.Code.from_asset(
                'function/src/task',
                bundling=core.BundlingOptions(
                    image=lambda_.Runtime.PYTHON_3_8.bundling_docker_image,
                    command=[
                        'bash', '-c',
                        'pip install -r requirements.txt -t /asset-output && cp -a . /asset-output'
                    ],
                )),
            handler="get.lambda_handler",
            runtime=lambda_.Runtime.PYTHON_3_8,
            environment=env,
            tracing=lambda_.Tracing.ACTIVE,
            timeout=core.Duration.seconds(29),
            memory_size=512)

        get_task_func.add_to_role_policy(statement=iam.PolicyStatement(
            actions=['dynamodb:*'],
            resources=[
                dynamodbTable.table_arn, dynamodbTable.table_arn + '/*'
            ]))
        logs.LogGroup(self,
                      get_resource_base_name + 'LogGroup',
                      log_group_name='/aws/lambda/' +
                      get_task_func.function_name,
                      retention=logs.RetentionDays.TWO_WEEKS)

        task_path = api.root.add_resource("task")
        task_id_path = task_path.add_resource("{task_id}")
        get_task_integration = apigw.LambdaIntegration(
            get_task_func, credentials_role=api_role)
        task_id_path.add_method(
            "GET",
            integration=get_task_integration,
            authorization_type=apigw.AuthorizationType.COGNITO,
            authorizer=cognito_authorizer,
        )

        # -----------------------------------
        #           create handler
        # -----------------------------------
        create_resource_base_name = "createTaskFunction"
        create_task_func = lambda_.Function(
            self,
            create_resource_base_name,
            code=lambda_.Code.from_asset(
                'function/src/task',
                bundling=core.BundlingOptions(
                    image=lambda_.Runtime.PYTHON_3_8.bundling_docker_image,
                    command=[
                        'bash', '-c',
                        'pip install -r requirements.txt -t /asset-output && cp -a . /asset-output'
                    ],
                )),
            handler="create.lambda_handler",
            runtime=lambda_.Runtime.PYTHON_3_8,
            environment=env,
            tracing=lambda_.Tracing.ACTIVE,
            timeout=core.Duration.seconds(29),
            memory_size=512)

        create_task_func.add_to_role_policy(statement=iam.PolicyStatement(
            actions=['dynamodb:*'],
            resources=[
                dynamodbTable.table_arn, dynamodbTable.table_arn + '/*'
            ]))
        logs.LogGroup(self,
                      create_resource_base_name + 'LogGroup',
                      log_group_name='/aws/lambda/' +
                      create_task_func.function_name,
                      retention=logs.RetentionDays.TWO_WEEKS)

        create_task_integration = apigw.LambdaIntegration(
            create_task_func, credentials_role=api_role)
        task_path.add_method(
            "POST",
            integration=create_task_integration,
            authorization_type=apigw.AuthorizationType.COGNITO,
            authorizer=cognito_authorizer,
        )

        # -----------------------------------
        #           update handler
        # -----------------------------------
        update_resource_base_name = "updateTaskFunction"
        update_task_func = lambda_.Function(
            self,
            update_resource_base_name,
            code=lambda_.Code.from_asset(
                'function/src/task',
                bundling=core.BundlingOptions(
                    image=lambda_.Runtime.PYTHON_3_8.bundling_docker_image,
                    command=[
                        'bash', '-c',
                        'pip install -r requirements.txt -t /asset-output && cp -a . /asset-output'
                    ],
                )),
            handler="update.lambda_handler",
            runtime=lambda_.Runtime.PYTHON_3_8,
            environment=env,
            tracing=lambda_.Tracing.ACTIVE,
            timeout=core.Duration.seconds(29),
            memory_size=512)

        update_task_func.add_to_role_policy(statement=iam.PolicyStatement(
            actions=['dynamodb:*'],
            resources=[
                dynamodbTable.table_arn, dynamodbTable.table_arn + '/*'
            ]))
        logs.LogGroup(self,
                      update_resource_base_name + 'LogGroup',
                      log_group_name='/aws/lambda/' +
                      update_task_func.function_name,
                      retention=logs.RetentionDays.TWO_WEEKS)

        update_task_integration = apigw.LambdaIntegration(
            update_task_func, credentials_role=api_role)
        task_id_path.add_method(
            "POST",
            integration=update_task_integration,
            authorization_type=apigw.AuthorizationType.COGNITO,
            authorizer=cognito_authorizer,
        )

        # -----------------------------------
        #           delete handler
        # -----------------------------------
        delete_resource_base_name = "deleteTaskFunction"
        delete_task_func = lambda_.Function(
            self,
            delete_resource_base_name,
            code=lambda_.Code.from_asset(
                'function/src/task',
                bundling=core.BundlingOptions(
                    image=lambda_.Runtime.PYTHON_3_8.bundling_docker_image,
                    command=[
                        'bash', '-c',
                        'pip install -r requirements.txt -t /asset-output && cp -a . /asset-output'
                    ],
                )),
            handler="delete.lambda_handler",
            runtime=lambda_.Runtime.PYTHON_3_8,
            environment=env,
            tracing=lambda_.Tracing.ACTIVE,
            timeout=core.Duration.seconds(29),
            memory_size=512)

        delete_task_func.add_to_role_policy(statement=iam.PolicyStatement(
            actions=['dynamodb:*'],
            resources=[
                dynamodbTable.table_arn, dynamodbTable.table_arn + '/*'
            ]))
        logs.LogGroup(self,
                      delete_resource_base_name + 'LogGroup',
                      log_group_name='/aws/lambda/' +
                      delete_task_func.function_name,
                      retention=logs.RetentionDays.TWO_WEEKS)

        delete_task_integration = apigw.LambdaIntegration(
            delete_task_func, credentials_role=api_role)
        task_id_path.add_method(
            "DELETE",
            integration=delete_task_integration,
            authorization_type=apigw.AuthorizationType.COGNITO,
            authorizer=cognito_authorizer,
        )

        # -----------------------------------
        #           search handler
        # -----------------------------------
        search_resource_base_name = "searchTaskFunction"
        search_task_func = lambda_.Function(
            self,
            search_resource_base_name,
            code=lambda_.Code.from_asset(
                'function/src/task',
                bundling=core.BundlingOptions(
                    image=lambda_.Runtime.PYTHON_3_8.bundling_docker_image,
                    command=[
                        'bash', '-c',
                        'pip install -r requirements.txt -t /asset-output && cp -a . /asset-output'
                    ],
                )),
            handler="search.lambda_handler",
            runtime=lambda_.Runtime.PYTHON_3_8,
            environment=env,
            tracing=lambda_.Tracing.ACTIVE,
            timeout=core.Duration.seconds(29),
            memory_size=512)

        search_task_func.add_to_role_policy(statement=iam.PolicyStatement(
            actions=['dynamodb:*'],
            resources=[
                dynamodbTable.table_arn, dynamodbTable.table_arn + '/*'
            ]))
        logs.LogGroup(self,
                      search_resource_base_name + 'LogGroup',
                      log_group_name='/aws/lambda/' +
                      search_task_func.function_name,
                      retention=logs.RetentionDays.TWO_WEEKS)

        search_task_integration = apigw.LambdaIntegration(
            search_task_func, credentials_role=api_role)
        tasks_path = api.root.add_resource("tasks")
        tasks_path.add_method(
            "GET",
            integration=search_task_integration,
            authorization_type=apigw.AuthorizationType.COGNITO,
            authorizer=cognito_authorizer,
        )

        # -----------------------------------
        #           login handler
        # -----------------------------------
        login_resource_base_name = "loginFunction"
        login_task_func = lambda_.Function(
            self,
            login_resource_base_name,
            code=lambda_.Code.from_asset(
                'function/src/user',
                bundling=core.BundlingOptions(
                    image=lambda_.Runtime.PYTHON_3_8.bundling_docker_image,
                    command=[
                        'bash', '-c',
                        'pip install -r requirements.txt -t /asset-output && cp -a . /asset-output'
                    ],
                )),
            handler="login.lambda_handler",
            runtime=lambda_.Runtime.PYTHON_3_8,
            environment=env,
            tracing=lambda_.Tracing.ACTIVE,
            timeout=core.Duration.seconds(29),
            memory_size=512)

        login_task_func.add_to_role_policy(statement=iam.PolicyStatement(
            actions=['cognito-idp:AdminInitiateAuth'],
            resources=[userpool.user_pool_arn]))
        logs.LogGroup(self,
                      login_resource_base_name + 'LogGroup',
                      log_group_name='/aws/lambda/' +
                      login_task_func.function_name,
                      retention=logs.RetentionDays.TWO_WEEKS)

        login_task_integration = apigw.LambdaIntegration(login_task_func)
        auth_path = api.root.add_resource("auth")
        auth_login_path = auth_path.add_resource("login")
        auth_login_path.add_method("POST", integration=login_task_integration)
Beispiel #4
0
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # S3: Create a Bucket for Unicorn Pursuit web page, and grant public read:
        bucket = s3.Bucket(
            self,
            "www.unicornpursuit.com",
            bucket_name="www.unicornpursuit.com",
            access_control=s3.BucketAccessControl.PUBLIC_READ,
        )

        # Grant public read access to the bucket
        bucket.grant_public_access()

        # DynamoDB: Create Table for Project Info (ID, Owner, Content, Photo and Votes)
        voting = ddb.CfnTable(
            self,
            "UnicornDynamoDBVoting",
            table_name="UnicornDynamoDBVoting",
            key_schema=[
                ddb.CfnTable.KeySchemaProperty(attribute_name="id",
                                               key_type="HASH"),
                ddb.CfnTable.KeySchemaProperty(attribute_name="owner",
                                               key_type="RANGE"),
            ],

            # In the new DynamoDB, you can't create AttDefProperty for non-key attributes.
            attribute_definitions=[
                ddb.CfnTable.AttributeDefinitionProperty(attribute_name="id",
                                                         attribute_type="N"),
                ddb.CfnTable.AttributeDefinitionProperty(
                    attribute_name="owner", attribute_type="S"),
            ],
            provisioned_throughput=ddb.CfnTable.ProvisionedThroughputProperty(
                read_capacity_units=5, write_capacity_units=5))

        # Grant RW writes for Unicorn App in Fargate and relevant Lambdas invoked from API Gateway
        # voting.grant_read_write_data(user)

        # Second DynamoDB table called "users" for storing who voted for whom
        # Example: [email protected] gave 5 points to project 323, 4 points to 111 etc.
        users = ddb.Table(self,
                          "UnicornDynamoDBUsers",
                          table_name="UnicornDynamoDBUsers",
                          partition_key=ddb.Attribute(
                              name="owner", type=ddb.AttributeType.STRING))

        # Cognito: Create User Pool
        userpool = cognito.UserPool(
            self,
            "CognitoUnicornUserPool",
            user_pool_name="CognitoUnicornUserPool",
            self_sign_up_enabled=True,

            ## Require username or email for users to sign in
            sign_in_aliases=cognito.SignInAliases(
                username=False,
                email=True,
            ),
            # Require users to give their full name when signing up
            required_attributes=cognito.RequiredAttributes(fullname=True,
                                                           email=True,
                                                           phone_number=True),
            # Verify new sign ups using email
            auto_verify=cognito.AutoVerifiedAttrs(
                email=False,
                phone=True,
            ),
            # Configure OTP Settings ()
            user_verification=cognito.UserVerificationConfig(
                sms_message=
                "Hey Unicorn Hunter, welcome to Unicorn Pursuit! Your OTP is {####}",
            ),
            # Set up required password policy
            password_policy=cognito.PasswordPolicy(
                min_length=12,
                require_symbols=True,
                require_lowercase=True,
                require_uppercase=True,
                require_digits=True,
            ))

        ## Cognito: Create App Client & create Authentication Flow with User and Password
        client = userpool.add_client(
            "UnicornAppClient",
            user_pool_client_name="UnicornAppClient",
            generate_secret=False,

            ## We'll allow both Flows, Implicit and Authorization Code, and decide in the app which to use.
            auth_flows=cognito.AuthFlow(admin_user_password=False,
                                        custom=False,
                                        refresh_token=True,
                                        user_password=True,
                                        user_srp=False),
        )
def add_cognito(self):
    password_policy = _cognito.PasswordPolicy(
        require_lowercase=False,
        require_digits=False,
        require_symbols=False,
        require_uppercase=False,
    )

    user_pool = _cognito.UserPool(
        self,
        'UserPool',
        password_policy=password_policy,
        user_pool_name='UserPool',
        self_sign_up_enabled=True,
        user_verification={
            "email_subject": "Verify your email for our awesome app!",
            "email_body":
            "Hello {username}, Thanks for signing up to our awesome app! Your verification code is {####}",
            "email_style": _cognito.VerificationEmailStyle.CODE,
        },
        user_invitation={
            "email_subject":
            "Invite to join our awesome app!",
            "email_body":
            "Hello {username}, you have been invited to join our awesome app! Your temporary password is {####}",
        },
        sign_in_aliases={"email": True},
        auto_verify={"email": True},
    )

    user_pool_client = user_pool.add_client("AppClient",
                                            auth_flows={
                                                "user_password": True,
                                                "user_srp": True,
                                                "refresh_token": True,
                                                "admin_user_password": True
                                            })

    idp = _cognito.CfnIdentityPool.CognitoIdentityProviderProperty(
        client_id=user_pool_client.user_pool_client_id,
        provider_name=user_pool.user_pool_provider_name)
    identity_pool = _cognito.CfnIdentityPool(
        self,
        "IdPool",
        allow_unauthenticated_identities=False,
        cognito_identity_providers=[idp])

    authenticated_principal = _iam.FederatedPrincipal(
        'cognito-identity.amazonaws.com', {
            "StringEquals": {
                "cognito-identity.amazonaws.com:aud": identity_pool.ref
            },
            "ForAnyValue:StringLike": {
                "cognito-identity.amazonaws.com:amr": "authenticated"
            },
        }, "sts:AssumeRoleWithWebIdentity")

    unauthenticated_principal = _iam.FederatedPrincipal(
        'cognito-identity.amazonaws.com', {
            "StringEquals": {
                "cognito-identity.amazonaws.com:aud": identity_pool.ref
            },
            "ForAnyValue:StringLike": {
                "cognito-identity.amazonaws.com:amr": "authenticated"
            },
        }, "sts:AssumeRoleWithWebIdentity")

    authenticated_role = _iam.Role(self,
                                   "CognitoDefaultAuthenticatedRole",
                                   assumed_by=authenticated_principal)

    unauthenticated_role = _iam.Role(self,
                                     "CognitoDefaultUnAuthenticatedRole",
                                     assumed_by=unauthenticated_principal)

    authenticated_policy = _iam.PolicyStatement(
        effect=_iam.Effect.ALLOW,
        actions=[
            "mobileanalytics:PutEvents", "cognito-sync:*", "cognito-identity:*"
        ],
        resources=["*"])

    unauthenticated_policy = _iam.PolicyStatement(
        effect=_iam.Effect.ALLOW,
        actions=[
            "mobileanalytics:PutEvents",
            "cognito-sync:*",
        ],
        resources=["*"])

    authenticated_role.add_to_policy(authenticated_policy)

    unauthenticated_role.add_to_policy(unauthenticated_policy)

    _cognito.CfnIdentityPoolRoleAttachment(self,
                                           "DefaultValidRoleAttachment",
                                           identity_pool_id=identity_pool.ref,
                                           roles={
                                               "authenticated":
                                               authenticated_role.role_arn,
                                               "unauthenticated":
                                               unauthenticated_role.role_arn
                                           })

    return user_pool, identity_pool, user_pool_client
Beispiel #6
0
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # Let's start with creating an IAM Service Role, later to be assumed by our ECS Fargate Container
        # After creating any resource, we'll be attaching IAM policies to this role using the `fargate_role`.
        fargate_role = iam.Role(
            self,
            "ecsTaskExecutionRole",
            role_name="ecsTaskExecutionRole",
            assumed_by=iam.ServicePrincipal("ecs-tasks.amazonaws.com"),
            description="Custom Role assumed by ECS Fargate (container)"
        )

        # S3: Create a Bucket for Unicorn Pursuit web page, and grant public read:
        bucket = s3.Bucket(self, "www.unicornpursuit.com",
                        bucket_name="www.unicornpursuit.com",
                        access_control=s3.BucketAccessControl.PUBLIC_READ,
                        )

        # Grant public read access to the bucket
        bucket.grant_public_access()


        # Grant S3 Read/Write access to our Fargate Container
        fargate_role.add_to_policy(statement=iam.PolicyStatement(
            resources=[bucket.bucket_arn],
            actions=["s3:*"]
        ))

        # DynamoDB: Create Table for Project Info (ID, Owner, Content, Photo and Votes)
        voting_ddb = ddb.CfnTable(
            self, "UnicornDynamoDBVoting",
            table_name="UnicornDynamoDBVoting",
            key_schema=[
                ddb.CfnTable.KeySchemaProperty(attribute_name="id",key_type="HASH"),
                ddb.CfnTable.KeySchemaProperty(attribute_name="owner",key_type="RANGE"),
            ],
            
        # In the new DynamoDB, you can't create AttDefProperty for non-key attributes.
            attribute_definitions=[
                ddb.CfnTable.AttributeDefinitionProperty(attribute_name="id",attribute_type="N"),
                ddb.CfnTable.AttributeDefinitionProperty(attribute_name="owner",attribute_type="S"),
            ],
            provisioned_throughput=ddb.CfnTable.ProvisionedThroughputProperty(
                read_capacity_units=5,
                write_capacity_units=5
            )
        )
        

        # Second DynamoDB table called "users" for storing who voted for whom
        # Example: [email protected] gave 5 points to project 323, 4 points to 111 etc.
        users_ddb = ddb.Table(
            self, "UnicornDynamoDBUsers",
            table_name="UnicornDynamoDBUsers",
            partition_key=ddb.Attribute(
                name="Owner",
                type=ddb.AttributeType.STRING
            )
        )

        # Grant RW writes for Unicorn App in Fargate
        fargate_role.add_to_policy(statement=iam.PolicyStatement(
            resources=[voting_ddb.attr_arn,
            users_ddb.table_arn],
            actions=["dynamodb:*"]
        ))

        # Cognito: Create User Pool
        userpool = cognito.UserPool(
            self, "CognitoUnicornUserPool",
            user_pool_name="CognitoUnicornUserPool",
            self_sign_up_enabled=True,
            
            ## Require username or email for users to sign in
            sign_in_aliases=cognito.SignInAliases(
                username=False,
                email=True,
            ),
            # Require users to give their full name when signing up
            required_attributes=cognito.RequiredAttributes(
                fullname=True,
                email=True,
                phone_number=True
            ),
            # Verify new sign ups using email
            auto_verify=cognito.AutoVerifiedAttrs(
                email=False,
                phone=True,
            ),
            # Configure OTP Settings ()
            user_verification=cognito.UserVerificationConfig(
                sms_message="Hey Unicorn Hunter, welcome to Unicorn Pursuit! Your OTP is {####}",
            ),
            # Set up required password policy
            password_policy=cognito.PasswordPolicy(
                min_length=12,
                require_symbols=True,
                require_lowercase=True,
                require_uppercase=True,
                require_digits=True,
            )
        )

        ## Cognito: Create App Client & create Authentication Flow with User and Password
        userpool.add_client(
            "UnicornAppClient",
            user_pool_client_name="UnicornAppClient",
            generate_secret=False,
            
            ## We'll allow both Flows, Implicit and Authorization Code, and decide in the app which to use.
            auth_flows=cognito.AuthFlow(
                admin_user_password=False,
                custom=False,
                refresh_token=True,
                user_password=True,
                user_srp=False
                ),
        )

        # Grant Cognito Access to Fargate. Include SSM, so Client App ID can be retrived.
        fargate_role.add_to_policy(statement=iam.PolicyStatement(
            resources=["*"],
            actions=["ssm:*"]
        ))

        fargate_role.add_to_policy(statement=iam.PolicyStatement(
            resources=[userpool.user_pool_arn],
            actions=["cognito-identity:*","cognito-idp:*","cognito-sync:*"]
        ))

        ## Fargate: Create ECS:Fargate with ECR uploaded image
        vpc = ec2.Vpc(self, "UnicornVPC", max_azs=2, nat_gateways=None)

        """   VPC with optimal NAT GW usage
        vpc_lowcost = ec2.Vpc(self, "LowCostVPC",
            max_azs=2,
            cidr="10.7.0.0/16",
            nat_gateways=None,
            subnet_configuration=[ec2.SubnetConfiguration(
                               subnet_type=ec2.SubnetType.PUBLIC,
                               name="Public",
                               cidr_mask=24,
                           ), ec2.SubnetConfiguration(
                               subnet_type=ec2.SubnetType.ISOLATED,
                               name="Private",
                               cidr_mask=24,
                           )
                           ],     
        ) """
        
        linux_ami = ec2.AmazonLinuxImage(generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX,
                                 edition=ec2.AmazonLinuxEdition.STANDARD,
                                 virtualization=ec2.AmazonLinuxVirt.HVM,
                                 storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE
                                 )

        nat_ec2 = ec2.Instance(self, "NAT", 
            instance_name="NAT",
            vpc=vpc,
            vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
            instance_type=ec2.InstanceType(instance_type_identifier="t3.nano"),
            machine_image=linux_ami,
            user_data=ec2.UserData.for_linux(),
            source_dest_check=False,
        )

        # Configure Linux Instance to act as NAT Instance
        nat_ec2.user_data.add_commands("sysctl -w net.ipv4.ip_forward=1")
        nat_ec2.user_data.add_commands("/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE")

        # Add a static route to the ISOLATED subnet, pointing 0.0.0.0/0 to a NAT EC2
        selection = vpc.select_subnets(
            subnet_type=ec2.SubnetType.PRIVATE
        )
    
        for subnet in selection.subnets:
            subnet.add_route("DefaultNAT", router_id=nat_ec2.instance_id, router_type=ec2.RouterType.INSTANCE, destination_cidr_block="0.0.0.0/0") 

        # Create ECS Cluster
        cluster = ecs.Cluster(self, "UnicornCluster", vpc=vpc)
        ecr.Repository(self, "unicorn", repository_name="unicorn")

        fargate_service = ecs_patterns.ApplicationLoadBalancedFargateService(self, "UnicornFargateService",
            cluster=cluster,
            cpu=512,
            desired_count=1,
            task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
                image=ecs.ContainerImage.from_registry("057097267726.dkr.ecr.eu-west-1.amazonaws.com/unicorn"),
                # image=ecs.ContainerImage.from_registry(repo.repository_uri_for_tag()),
                container_port=8080,
                container_name="unicorn",
                execution_role=fargate_role,
                ),
                
            memory_limit_mib=1024,
            public_load_balancer=True   
        )

        fargate_service.service.connections.security_groups[0].add_ingress_rule(
            peer = ec2.Peer.ipv4(vpc.vpc_cidr_block),
            connection = ec2.Port.tcp(8080),
            description="Allow http inbound from VPC"
        )

        # Update NAT EC2 Security Group, to allow only HTTPS from Fargate Service Security Group.
        nat_ec2.connections.security_groups[0].add_ingress_rule(
            peer = fargate_service.service.connections.security_groups[0],
            connection = ec2.Port.tcp(443),
            description="Allow https from Fargate Service"
        )

        # Grant ECR Access to Fargate by attaching an existing ReadOnly policy. so that Unicorn Docker Image can be pulled.
        #fargate_role.add_managed_policy(iam.ManagedPolicy("AmazonEC2ContainerRegistryReadOnly"))
        fargate_role.add_to_policy(statement=iam.PolicyStatement(
            resources=["*"],
            actions=["ecr:*"]
        ))
Beispiel #7
0
    def __init__(self, scope: core.Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        prj_name = self.node.try_get_context('project_name')
        env_name = self.node.try_get_context('env')

        user_pool2 = cognito.UserPool(
            self,
            id=f'{env_name}-precog',
            auto_verify=cognito.AutoVerifiedAttrs(email=True),
            sign_in_aliases=cognito.SignInAliases(email=True, phone=True),
            self_sign_up_enabled=True,
            user_pool_name=f'{env_name}-cdk-2-user-pool',
            custom_attributes={
                "param1": cognito.StringAttribute(mutable=True)
            },
            password_policy=cognito.PasswordPolicy(min_length=10,
                                                   require_lowercase=True,
                                                   require_digits=True,
                                                   require_symbols=False,
                                                   require_uppercase=True))

        user_pool = cognito.CfnUserPool(
            self,
            id=f'{env_name}-cognito-user-pool',
            auto_verified_attributes=['email'],
            username_attributes=['email', 'phone_number'],
            user_pool_name=f'{env_name}-cdk-user-pool',
            schema=[{
                "attributeDataType": "String",
                "name": "param1",
                "mutable": True
            }],
            policies=cognito.CfnUserPool.PoliciesProperty(
                password_policy=cognito.CfnUserPool.PasswordPolicyProperty(
                    minimum_length=10,
                    require_lowercase=True,
                    require_numbers=True,
                    require_symbols=False,
                    require_uppercase=True)))

        user_pool_client2 = cognito.UserPoolClient(
            self,
            id=f'{env_name}-pool-client2',
            user_pool=user_pool2,
            user_pool_client_name=f'{env_name}-cdk-app-client2')
        identity_pool2 = cognito.CfnIdentityPool(
            self,
            id=f'{env_name}-identify-pool-2',
            allow_unauthenticated_identities=False,
            cognito_identity_providers=[
                cognito.CfnIdentityPool.CognitoIdentityProviderProperty(
                    client_id=user_pool_client2.user_pool_client_id,
                    provider_name=user_pool.attr_provider_name)
            ],
            identity_pool_name=f'{env_name}-cdk-identity-pool2')

        user_pool_client = cognito.CfnUserPoolClient(
            self,
            id=f'{env_name}-pool-client',
            user_pool_id=user_pool.ref,
            client_name=f'{env_name}-cdk-app-client')

        identity_pool = cognito.CfnIdentityPool(
            self,
            id=f'{env_name}-identify-pool',
            allow_unauthenticated_identities=False,
            cognito_identity_providers=[
                cognito.CfnIdentityPool.CognitoIdentityProviderProperty(
                    client_id=user_pool_client.ref,
                    provider_name=user_pool.attr_provider_name)
            ],
            identity_pool_name=f'{env_name}-cdk-identity-pool')

        ssm.StringParameter(
            self,
            id='app-id',
            parameter_name=f"/{env_name}/cognito-app-client-id",
            string_value=user_pool_client.ref)

        ssm.StringParameter(self,
                            id='user-pool-id',
                            parameter_name=f"/{env_name}/cognito-user-pool-id",
                            string_value=user_pool_client.user_pool_id)

        ssm.StringParameter(
            self,
            id='identity-pool-id',
            parameter_name=f"/{env_name}/cognito-identity-pool-id",
            string_value=identity_pool.ref  # ref returns the id
        )
def base_cognito_user_pool(construct, **kwargs):
    """
    Function that generates a Cognito User Pool.
    :param construct: Custom construct that will use this function. From the external construct is usually 'self'.
    :param kwargs: Consist of required 'queue_name' and optionals 'queue_delivery_delay' and 'queue_visibility_timeout'.
    :return: DynamoDB Table Construct.
    """
    user_pool_name = construct.prefix + "_" + kwargs[
        "pool_name"] + "_pool_" + construct.environment_

    if kwargs.get("email") is not None:
        email_settings = cognito.EmailSettings(
            from_=kwargs["email"]["from"],
            reply_to=kwargs["email"].get("reply_to"))
    else:
        email_settings = None

    password_policy_settings = kwargs.get("password_policy")
    temporary_password_validation_time = (
        core.Duration.days(
            password_policy_settings.get("temporary_password_duration"))
        if password_policy_settings.get("temporary_password_duration")
        is not None else None)
    password_policy = cognito.PasswordPolicy(
        min_length=password_policy_settings.get("minimum_length"),
        temp_password_validity=temporary_password_validation_time,
        require_lowercase=password_policy_settings.get("require",
                                                       {}).get("lower_case"),
        require_uppercase=password_policy_settings.get("require",
                                                       {}).get("upper_case"),
        require_digits=password_policy_settings.get("require",
                                                    {}).get("digits"),
        require_symbols=password_policy_settings.get("require",
                                                     {}).get("symbols"),
    )

    sign_up_info = kwargs["sign_up"]
    self_sing_up = sign_up_info["enabled"]
    user_verification_info = base_user_verification(
        sign_up_info=sign_up_info["user_verification"])

    user_invitation = kwargs.get("invitation")
    user_invitation_configuration = cognito.UserInvitationConfig(
        email_subject=user_invitation.get("email", {}).get("subject"),
        email_body=user_invitation.get("email", {}).get("body"),
        sms_message=user_invitation.get("sms", {}).get("body"),
    )

    trigger_functions = kwargs.get("triggers", {})
    lambda_triggers = base_lambda_triggers(construct,
                                           trigger_functions=trigger_functions)

    sign_in_list = kwargs.get("sign_in").get("order", list())
    sing_in_kwargs = dict()
    for element in sign_in_list:
        sing_in_kwargs[element] = True
    sign_in_aliases = cognito.SignInAliases(**sing_in_kwargs)

    attributes = kwargs.get("attributes")
    standard_attributes_list = attributes.get("standard", list())
    standard_attributes_dict = dict()
    for element in standard_attributes_list:
        standard_attributes_dict[element["name"]] = cognito.StandardAttribute(
            mutable=element.get("mutable"), required=element.get("required"))
    standard_attributes = cognito.StandardAttributes(
        **standard_attributes_dict)

    custom_attributes_list = attributes.get("custom", list())
    if len(custom_attributes_list) > 0:
        custom_attributes = base_custom_attributes(
            custom_attributes_list=custom_attributes_list)
    else:
        custom_attributes = None

    user_pool = cognito.UserPool(
        construct,
        id=user_pool_name,
        user_pool_name=user_pool_name,
        email_settings=email_settings,
        password_policy=password_policy,
        self_sign_up_enabled=self_sing_up,
        user_verification=user_verification_info,
        user_invitation=user_invitation_configuration,
        sign_in_aliases=sign_in_aliases,
        standard_attributes=standard_attributes,
        custom_attributes=custom_attributes,
        lambda_triggers=lambda_triggers,
    )

    user_pool_client = None
    if kwargs.get("app_client", {}).get("enabled") is True:
        client_name = kwargs["app_client"]["client_name"]
        generate_secret = kwargs["app_client"]["generate_secret"]
        user_pool_client_name = construct.prefix + "_" + client_name + "_client_" + construct.environment_

        auth_flows = None
        auth_flows_configuration = kwargs["app_client"].get("auth_flows")
        if auth_flows_configuration is not None:
            auth_flows = cognito.AuthFlow(**auth_flows_configuration)

        user_pool_client = cognito.UserPoolClient(
            construct,
            id=user_pool_client_name,
            user_pool_client_name=user_pool_client_name,
            generate_secret=generate_secret,
            auth_flows=auth_flows,
            user_pool=user_pool,
        )

    return user_pool, user_pool_client
Beispiel #9
0
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        pool = cognito.UserPool(scope=self,
                                id="user-pool",
                                mfa=cognito.Mfa.OPTIONAL,
                                mfa_second_factor=cognito.MfaSecondFactor(
                                    otp=True, sms=True),
                                password_policy=cognito.PasswordPolicy(
                                    min_length=12,
                                    require_lowercase=True,
                                    require_uppercase=False,
                                    require_digits=False,
                                    require_symbols=False,
                                ))

        client = pool.add_client(
            id="customer-app-client",
            auth_flows=cognito.AuthFlow(
                user_password=True,
                refresh_token=True,
                user_srp=True,
            ),
        )

        graphql_api = appsync.GraphqlApi(
            scope=self,
            id="graphql-api",
            name="todo-api",
            schema=appsync.Schema.from_asset(
                file_path=os.path.join("graphQL", "schema.graphql")),
            authorization_config=appsync.AuthorizationConfig(
                default_authorization=appsync.AuthorizationMode(
                    authorization_type=appsync.AuthorizationType.USER_POOL,
                    user_pool_config=appsync.UserPoolConfig(user_pool=pool,
                                                            ))),
            xray_enabled=True)

        todo_table = dynamodb.Table(
            scope=self,
            id="todo-table",
            removal_policy=core.RemovalPolicy.DESTROY,
            partition_key=dynamodb.Attribute(
                name="id", type=dynamodb.AttributeType.STRING),
        )
        commnet_table = dynamodb.Table(
            scope=self,
            id="comment-table",
            removal_policy=core.RemovalPolicy.DESTROY,
            partition_key=dynamodb.Attribute(
                name="commentid", type=dynamodb.AttributeType.STRING),
            sort_key=dynamodb.Attribute(name="todoid",
                                        type=dynamodb.AttributeType.STRING),
        )
        commnet_table.add_global_secondary_index(
            partition_key=dynamodb.Attribute(
                name="todoid", type=dynamodb.AttributeType.STRING),
            index_name="todoid-index")

        todo_dS = graphql_api.add_dynamo_db_data_source(
            id="todoDS",
            table=todo_table,
        )

        todo_dS.create_resolver(
            type_name="Query",
            field_name="getTodos",
            request_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "getItemsRequest.vtl")),
            response_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "getItemsResponse.vtl")),
        )

        todo_dS.create_resolver(
            type_name="Mutation",
            field_name="addTodo",
            request_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "addTodoRequest.vtl")),
            response_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "addTodoResponse.vtl")),
        )

        comment_dS = graphql_api.add_dynamo_db_data_source(
            id="commentDS",
            table=commnet_table,
        )

        comment_dS.create_resolver(
            type_name="Todo",
            field_name="contents",
            request_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "getCommentsRequest.vtl")),
            response_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "getCommentsResponse.vtl")),
        )

        comment_dS.create_resolver(
            type_name="Mutation",
            field_name="addComment",
            request_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "addCommentRequest.vtl")),
            response_mapping_template=appsync.MappingTemplate.from_file(
                os.path.join("graphQL", "addCommentResponse.vtl")),
        )
Beispiel #10
0
    def __init__(self, scope: core.Construct, id: str,
                 artifact_bucket: s3.Bucket, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        pool = cognito.UserPool(scope=self,
                                id="user-pool",
                                mfa=cognito.Mfa.OPTIONAL,
                                mfa_second_factor=cognito.MfaSecondFactor(
                                    otp=True, sms=True),
                                password_policy=cognito.PasswordPolicy(
                                    min_length=12,
                                    require_lowercase=True,
                                    require_uppercase=False,
                                    require_digits=False,
                                    require_symbols=False,
                                ))

        client = pool.add_client(
            id="customer-app-client",
            auth_flows=cognito.AuthFlow(user_password=True,
                                        refresh_token=True),
        )

        backend = _lambda.Function(
            scope=self,
            id="api-function",
            runtime=_lambda.Runtime.GO_1_X,
            handler="main",
            memory_size=500,
            timeout=core.Duration.seconds(10),
            environment={
                "USER_POOL_ID": pool.user_pool_id,
                "CLIENT_ID": client.user_pool_client_id,
            },
            code=_lambda.Code.from_bucket(
                bucket=artifact_bucket,
                key="Server/main.zip",
            ),
        )
        backend.add_to_role_policy(
            statement=iam.PolicyStatement(actions=[
                "cognito-idp:RespondToAuthChallenge",
                "cognito-idp:InitiateAuth", "cognito-idp:SetUserMFAPreference",
                "cognito-idp:AssociateSoftwareToken",
                "cognito-idp:VerifySoftwareToken"
            ],
                                          resources=[pool.user_pool_arn]))

        api = apigateway.LambdaRestApi(
            scope=self,
            id="mfa-api",
            handler=backend,
            endpoint_types=[apigateway.EndpointType.REGIONAL],
            default_cors_preflight_options=apigateway.CorsOptions(
                allow_origins=["*"]))
        self.api = api

        self.backend_fn = backend

        static_website_bucket = s3.Bucket(
            scope=self,
            id="static-website-bucket",
        )
        self.static_website_bucket = static_website_bucket

        distribution = cloudfront.CloudFrontWebDistribution(
            scope=self,
            id="static-website-distribution",
            default_root_object="index.html",
            origin_configs=[
                cloudfront.SourceConfiguration(
                    s3_origin_source=cloudfront.S3OriginConfig(
                        s3_bucket_source=static_website_bucket,
                        origin_access_identity=cloudfront.OriginAccessIdentity(
                            scope=self,
                            id="origin-access-identity",
                        )),
                    behaviors=[cloudfront.Behavior(is_default_behavior=True)])
            ],
        )
    def __init__(self, scope: core.Construct, construct_id: str,
                 cognito_prefix: str, stack_log_level: str, **kwargs) -> None:

        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your stack goes here
        # Cognito User Pool for Kibana Access
        self.es_user_pool = _cognito.UserPool(
            self,
            "esCognitoUserPool",
            user_pool_name=f"{cognito_prefix}-log-parser-es-users",
            self_sign_up_enabled=False,
            sign_in_aliases=_cognito.SignInAliases(username=True, email=True),
            sign_in_case_sensitive=False,
            standard_attributes={
                "email": {
                    "required": True,
                    "mutable": False
                },
                "fullname": {
                    "required": False,
                    "mutable": True
                }
            },
            password_policy=_cognito.PasswordPolicy(min_length=8),
            auto_verify=_cognito.AutoVerifiedAttrs(email=True))

        # Create User Pool Domain to enable SignUp, SignIn, Auth & Callback Urls
        es_auth_domain = _cognito.UserPoolDomain(
            self,
            "esCognitoUserPoolDomain",
            user_pool=self.es_user_pool,
            cognito_domain=_cognito.CognitoDomainOptions(
                domain_prefix=f"{cognito_prefix}-{core.Aws.ACCOUNT_ID}"))

        # Role Authenticated Cognito Users will assume in ES Service
        self.es_role = _iam.Role(
            self,
            "esKibanaIamRole",
            assumed_by=_iam.ServicePrincipal("es.amazonaws.com"),
            managed_policies=[
                _iam.ManagedPolicy.from_aws_managed_policy_name(
                    managed_policy_name="AmazonESCognitoAccess")
            ],
        )

        # Create Cognito Federated Identity Pool to exchange Cognito auth token for AWS Token
        self.es_id_pool = _cognito.CfnIdentityPool(
            self,
            "esIdentityPool",
            allow_unauthenticated_identities=False,
            cognito_identity_providers=[],
        )

        # Role For Cognito Federated Idenity Pool Authenticated Users
        self.es_auth_role = _iam.Role(
            self,
            "esAuthIamRole",
            assumed_by=_iam.FederatedPrincipal(
                federated="cognito-identity.amazonaws.com",
                conditions={
                    "StringEquals": {
                        "cognito-identity.amazonaws.com:aud":
                        self.es_id_pool.ref
                    },
                    "ForAnyValue:StringLike": {
                        "cognito-identity.amazonaws.com:amr": "authenticated"
                    },
                },
                assume_role_action="sts:AssumeRoleWithWebIdentity"),
        )

        # Attach a Role to Cognito Federated Idenity Pool Authenticated Users
        _cognito.CfnIdentityPoolRoleAttachment(
            self,
            "cognitoFederatedIdentityPoolRoleAttachment",
            identity_pool_id=self.es_id_pool.ref,
            roles={"authenticated": self.es_auth_role.role_arn})

        ###########################################
        ################# OUTPUTS #################
        ###########################################
        output_0 = core.CfnOutput(
            self,
            "AutomationFrom",
            value=f"{GlobalArgs.SOURCE_INFO}",
            description=
            "To know more about this automation stack, check out our github page."
        )

        output_1 = core.CfnOutput(
            self,
            "CreateCognitoUserConsole",
            value=
            f"https://{core.Aws.REGION}.console.aws.amazon.com/cognito/users?region={core.Aws.REGION}#/pool/{self.es_user_pool.user_pool_id}/users",
            description="Create a new user in the user pool here.")