def add_resources(self):
        self.runner_terminate_rule = self.template.add_resource(
            Rule(
                "RunnerTeminateRule",
                EventPattern={
                    "source": ["aws.autoscaling"],
                    "detail-type": ["EC2 Instance-terminate Lifecycle Action"],
                },
                State="ENABLED",
                Targets=[
                    Target(
                        Arn=Ref(self.runner_unregister_function_arn),
                        Id=Ref(self.runner_terminate_target_id),
                    )
                ],
            ))

        self.runner_unregister_permission = self.template.add_resource(
            Permission(
                "RunnerUnregisterPermission",
                Action="lambda:InvokeFunction",
                FunctionName=Ref(self.runner_unregister_function),
                Principal="events.amazonaws.com",
                SourceArn=GetAtt(self.runner_terminate_rule, "Arn"),
            ))

        self.runner_terminate_lifecyclehook = self.template.add_resource(
            LifecycleHook(
                "RunnerTerminateLifecycleHook",
                AutoScalingGroupName=Ref(self.runner_autoscaling_group),
                LifecycleTransition="autoscaling:EC2_INSTANCE_TERMINATING",
            ))
def create_lambda_fn_cron(name_prefix, lambda_fn, schedule_expression):
    rule = Rule(
        '{}EventRule'.format(name_prefix),
        ScheduleExpression=schedule_expression,
        Targets=[Target(Arn=GetAtt(lambda_fn, 'Arn'), Id=lambda_fn.name)])

    permission = Permission('{}LambdaFunctionPermission'.format(name_prefix),
                            Action="lambda:InvokeFunction",
                            FunctionName=GetAtt(lambda_fn, 'Arn'),
                            Principal='events.amazonaws.com',
                            SourceArn=GetAtt(rule, 'Arn'))

    return (rule, permission)
Пример #3
0
def build_cw_event(template=Template,
                   project_name=None,
                   role=None,
                   target_job=None,
                   hour=12,
                   minute=0,
                   input_json=None):
    """ Create a CloudWatch Event to run a CodeBuild Project. """
    # CloudFormation doesn't allow underscores
    project_name = project_name.replace('_', '')

    # target_job is only expected in the case where multiple events are pointed at the same target.
    # Use the project name as the dependency otherwise.
    if not target_job:
        target_job = project_name

    # input_json is used to pass additional ENV variables to the codebuild job.
    if input_json:
        project_target = Target(f"{project_name}Target",
                                Arn=GetAtt(target_job, "Arn"),
                                RoleArn=GetAtt(role, "Arn"),
                                Input=json.dumps(input_json),
                                Id=f"{project_name}CWid")
    else:
        project_target = Target(f"{project_name}Target",
                                Arn=GetAtt(target_job, "Arn"),
                                RoleArn=GetAtt(role, "Arn"),
                                Id=f"{project_name}CWid")

    Rule(
        f"{project_name}Rule",
        template=template,
        Name=f"{project_name}Event",
        Description="scheduled run Build with CloudFormation",
        Targets=[project_target],
        State='ENABLED',
        # Run at the top of hour.
        ScheduleExpression=f"cron({minute} {hour} * * ? *)",
        DependsOn=target_job)
Пример #4
0
def build_cw_event(template=Template, project_name=None, role=None):
    # Run either at 12 or 13:00 UTC, 04/05:00 PST
    hour = randrange(12, 14)
    project_target = Target(f"{project_name}Target",
                            Arn=GetAtt(project_name, "Arn"),
                            RoleArn=GetAtt(role, "Arn"),
                            Id=f"{project_name}CWid")
    rule = template.add_resource(
        Rule(
            f"{project_name}Rule",
            Name=f"{project_name}Evernt",
            Description="scheduled run Build with CloudFormation",
            Targets=[project_target],
            State='ENABLED',
            # Run at the top of a random hour.
            ScheduleExpression=f"cron(0 {hour} * * ? *)",
            DependsOn=project_name))
    return rule
Пример #5
0
def add_lambda_scheduler(*, template_res, cron, lambda_function_name,
                         lambda_function_arn):
    lambda_function = ''.join(
        [a.title() for a in lambda_function_name.split('_')])
    event_target = Target(f'{lambda_function}EventTarget',
                          Arn=lambda_function_arn,
                          Id=f'{lambda_function}FunctionEventTarget')
    scheduler = template_res.add_resource(
        Rule(
            f'ScheduledRule{lambda_function}',
            ScheduleExpression=cron,
            # http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html
            Description=f'Scheduled Event for Lambda {lambda_function_name}',
            State="ENABLED",
            Targets=[event_target]))
    add_permission = template_res.add_resource(
        awslambda.Permission(f'AccessLambda{lambda_function}',
                             Action='lambda:InvokeFunction',
                             FunctionName=f'{lambda_function_name}',
                             Principal='events.amazonaws.com',
                             SourceArn=GetAtt(scheduler, 'Arn')))
def create_lambda_schedule(template, awslambda, schedule):
    """
    Create Lambda function schedule
    :param template: Cloudformation template to add to
    :param awslambda: Lambda function to be scheduled
    :param schedule: Rate at which schedule should run
    """
    trop_cw_rule = template.add_resource(
        Rule('CloudsploitRule',
             Name='CloudsploitReporter',
             ScheduleExpression=schedule,
             State='ENABLED',
             Targets=[
                 Target(Arn=GetAtt(awslambda, 'Arn'), Id='CloudsploitRule')
             ]))

    trop_cw_permission = template.add_resource(
        Permission('CloudsploitRulePermission',
                   Action='lambda:InvokeFunction',
                   FunctionName=GetAtt(awslambda, 'Arn'),
                   Principal='events.amazonaws.com',
                   SourceArn=GetAtt(trop_cw_rule, 'Arn')))
Пример #7
0
def create_template():
    t = Template(Description="Infrastructure for routezero")
    api_key = t.add_parameter(Parameter("ZerotierApiKey", Type="String", NoEcho=True))
    network_id = t.add_parameter(Parameter("ZerotierNetworkId", Type="String"))
    role = t.add_resource(
        Role(
            "Role",
            AssumeRolePolicyDocument=get_lambda_assumerole_policy(),
            Policies=[
                Policy(
                    PolicyName="cloudformation-route53-update",
                    PolicyDocument=PolicyDocument(
                        Statement=[
                            Statement(
                                Effect=Allow,
                                Action=[
                                    cloudformation.Action("*"),
                                    route53.Action("*"),
                                ],
                                Resource=["*"],
                            )
                        ]
                    ),
                )
            ],
            ManagedPolicyArns=[
                "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
            ],
        )
    )
    function = t.add_resource(
        CLIFunction(
            "Function",
            MemorySize=256,
            Timeout=60 * 15,
            Handler=".".join([routezero.__name__, routezero.handler.__name__]),
            Runtime="python3.6",
            Code=create_bundle(),
            Role=GetAtt(role, "Arn"),
            Environment=Environment(
                Variables={
                    "ZEROTIER_API_KEY": Ref(api_key),
                    "ZEROTIER_NETWORK_ID": Ref(network_id),
                    "ROUTE53_RECORD_STACK_NAME": Sub("${AWS::StackName}Records"),
                }
            ),
        )
    )
    log_group = t.add_resource(
        LogGroup(
            "LogGroup", LogGroupName=Sub("/aws/lambda/${Function}"), RetentionInDays=30
        )
    )
    permission = t.add_resource(
        Permission(
            "Permission",
            FunctionName=GetAtt(function, "Arn"),
            Principal="events.amazonaws.com",
            Action="lambda:InvokeFunction",
            SourceArn=Sub(
                "arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/*"
            ),
            DependsOn=[log_group],
        )
    )
    rule = t.add_resource(
        Rule(
            "Rule",
            ScheduleExpression="rate(15 minutes)",
            Targets=[Target(Id=Ref(function), Arn=GetAtt(function, "Arn"))],
            DependsOn=[permission],
        )
    )
    return t
Пример #8
0
            "Version":
            "2012-10-17",
            "Statement": [{
                "Action": ["sts:AssumeRole"],
                "Effect": "Allow",
                "Principal": {
                    "Service": ["events.amazonaws.com"]
                }
            }]
        },
    ))

cw_rule_target = Target(Arn=Join('', [
    "arn:aws:codepipeline:",
    Ref('regionparameter'), ':',
    Ref('accountparameter'), ':',
    Ref('pipeline')
]),
                        Id='mlTargert1',
                        RoleArn=GetAtt("CloudWatchEventExecutionRole", "Arn"))

pipeline_cw_rule = t.add_resource(
    Rule('mlpipelinerule',
         Description='Triggers codepipeline',
         EventPattern=cw_event_pattern,
         State='ENABLED',
         Targets=[cw_rule_target]))

# This role allows sagemaker to do things like use the kms key that was used to encrypt the contents of the input and
# output buckets as well as pull docker container images from the ecr repo.
SagemakerExecutionRole = t.add_resource(
    Role(
Пример #9
0
def create_template():
    template = Template(Description=(
        "Static website hosted with S3 and CloudFront. "
        "https://github.com/schlarpc/overengineered-cloudfront-s3-static-website"
    ))

    partition_config = add_mapping(
        template,
        "PartitionConfig",
        {
            "aws": {
                # the region with the control plane for CloudFront, IAM, Route 53, etc
                "PrimaryRegion":
                "us-east-1",
                # assume that Lambda@Edge replicates to all default enabled regions, and that
                # future regions will be opt-in. generated with AWS CLI:
                # aws ec2 describe-regions --all-regions --query "Regions[?OptInStatus=='opt-in-not-required'].RegionName|sort(@)"
                "DefaultRegions": [
                    "ap-northeast-1",
                    "ap-northeast-2",
                    "ap-northeast-3",
                    "ap-south-1",
                    "ap-southeast-1",
                    "ap-southeast-2",
                    "ca-central-1",
                    "eu-central-1",
                    "eu-north-1",
                    "eu-west-1",
                    "eu-west-2",
                    "eu-west-3",
                    "sa-east-1",
                    "us-east-1",
                    "us-east-2",
                    "us-west-1",
                    "us-west-2",
                ],
            },
            # this doesn't actually work, because Lambda@Edge isn't supported in aws-cn
            "aws-cn": {
                "PrimaryRegion": "cn-north-1",
                "DefaultRegions": ["cn-north-1", "cn-northwest-1"],
            },
        },
    )

    acm_certificate_arn = template.add_parameter(
        Parameter(
            "AcmCertificateArn",
            Description=
            "Existing ACM certificate to use for serving TLS. Overrides HostedZoneId.",
            Type="String",
            AllowedPattern="(arn:[^:]+:acm:[^:]+:[^:]+:certificate/.+|)",
            Default="",
        ))

    hosted_zone_id = template.add_parameter(
        Parameter(
            "HostedZoneId",
            Description=
            "Existing Route 53 zone to use for validating a new TLS certificate.",
            Type="String",
            AllowedPattern="(Z[A-Z0-9]+|)",
            Default="",
        ))

    dns_names = template.add_parameter(
        Parameter(
            "DomainNames",
            Description=
            "Comma-separated list of additional domain names to serve.",
            Type="CommaDelimitedList",
            Default="",
        ))

    tls_protocol_version = template.add_parameter(
        Parameter(
            "TlsProtocolVersion",
            Description=
            "CloudFront TLS security policy; see https://amzn.to/2DR91Xq for details.",
            Type="String",
            Default="TLSv1.2_2019",
        ))

    log_retention_days = template.add_parameter(
        Parameter(
            "LogRetentionDays",
            Description=
            "Days to keep CloudFront, S3, and Lambda logs. 0 means indefinite retention.",
            Type="Number",
            AllowedValues=[0] + CLOUDWATCH_LOGS_RETENTION_OPTIONS,
            Default=365,
        ))

    default_ttl_seconds = template.add_parameter(
        Parameter(
            "DefaultTtlSeconds",
            Description="Cache time-to-live when not set by S3 object headers.",
            Type="Number",
            Default=int(datetime.timedelta(minutes=5).total_seconds()),
        ))

    enable_price_class_hack = template.add_parameter(
        Parameter(
            "EnablePriceClassHack",
            Description="Cut your bill in half with this one weird trick.",
            Type="String",
            Default="false",
            AllowedValues=["true", "false"],
        ))

    retention_defined = add_condition(template, "RetentionDefined",
                                      Not(Equals(Ref(log_retention_days), 0)))

    using_price_class_hack = add_condition(
        template, "UsingPriceClassHack",
        Equals(Ref(enable_price_class_hack), "true"))

    using_acm_certificate = add_condition(
        template, "UsingAcmCertificate",
        Not(Equals(Ref(acm_certificate_arn), "")))

    using_hosted_zone = add_condition(template, "UsingHostedZone",
                                      Not(Equals(Ref(hosted_zone_id), "")))

    using_certificate = add_condition(
        template,
        "UsingCertificate",
        Or(Condition(using_acm_certificate), Condition(using_hosted_zone)),
    )

    should_create_certificate = add_condition(
        template,
        "ShouldCreateCertificate",
        And(Condition(using_hosted_zone),
            Not(Condition(using_acm_certificate))),
    )

    using_dns_names = add_condition(template, "UsingDnsNames",
                                    Not(Equals(Select(0, Ref(dns_names)), "")))

    is_primary_region = "IsPrimaryRegion"
    template.add_condition(
        is_primary_region,
        Equals(Region, FindInMap(partition_config, Partition,
                                 "PrimaryRegion")),
    )

    precondition_region_is_primary = template.add_resource(
        WaitConditionHandle(
            "PreconditionIsPrimaryRegionForPartition",
            Condition=is_primary_region,
        ))

    log_ingester_dlq = template.add_resource(
        Queue(
            "LogIngesterDLQ",
            MessageRetentionPeriod=int(
                datetime.timedelta(days=14).total_seconds()),
            KmsMasterKeyId="alias/aws/sqs",
        ))

    log_ingester_role = template.add_resource(
        Role(
            "LogIngesterRole",
            AssumeRolePolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect="Allow",
                        Principal=Principal("Service", "lambda.amazonaws.com"),
                        Action=[sts.AssumeRole],
                    )
                ],
            ),
            Policies=[
                PolicyProperty(
                    PolicyName="DLQPolicy",
                    PolicyDocument=PolicyDocument(
                        Version="2012-10-17",
                        Statement=[
                            Statement(
                                Effect=Allow,
                                Action=[sqs.SendMessage],
                                Resource=[GetAtt(log_ingester_dlq, "Arn")],
                            )
                        ],
                    ),
                )
            ],
        ))

    log_ingester = template.add_resource(
        Function(
            "LogIngester",
            Runtime=PYTHON_RUNTIME,
            Handler="index.{}".format(log_ingest.handler.__name__),
            Code=Code(ZipFile=inspect.getsource(log_ingest)),
            MemorySize=256,
            Timeout=300,
            Role=GetAtt(log_ingester_role, "Arn"),
            DeadLetterConfig=DeadLetterConfig(
                TargetArn=GetAtt(log_ingester_dlq, "Arn")),
        ))

    log_ingester_permission = template.add_resource(
        Permission(
            "LogIngesterPermission",
            FunctionName=GetAtt(log_ingester, "Arn"),
            Action="lambda:InvokeFunction",
            Principal="s3.amazonaws.com",
            SourceAccount=AccountId,
        ))

    log_bucket = template.add_resource(
        Bucket(
            "LogBucket",
            # S3 requires this ACL (regardless of bucket policy) or s3:PutBucketLogging fails.
            # When the CloudFront distribution is created, it adds an additional bucket ACL.
            # That ACL is not possible to model in CloudFormation.
            AccessControl="LogDeliveryWrite",
            LifecycleConfiguration=LifecycleConfiguration(Rules=[
                LifecycleRule(ExpirationInDays=1, Status="Enabled"),
                LifecycleRule(
                    AbortIncompleteMultipartUpload=
                    AbortIncompleteMultipartUpload(DaysAfterInitiation=1),
                    Status="Enabled",
                ),
            ]),
            NotificationConfiguration=NotificationConfiguration(
                LambdaConfigurations=[
                    LambdaConfigurations(Event="s3:ObjectCreated:*",
                                         Function=GetAtt(log_ingester, "Arn"))
                ]),
            BucketEncryption=BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=
                        ServerSideEncryptionByDefault(
                            # if we use KMS, we can't read the logs
                            SSEAlgorithm="AES256"))
                ]),
            OwnershipControls=OwnershipControls(Rules=[
                OwnershipControlsRule(ObjectOwnership="BucketOwnerPreferred")
            ], ),
            PublicAccessBlockConfiguration=PublicAccessBlockConfiguration(
                BlockPublicAcls=True,
                BlockPublicPolicy=True,
                IgnorePublicAcls=True,
                RestrictPublicBuckets=True,
            ),
            DependsOn=[log_ingester_permission],
        ))

    log_ingester_log_group = template.add_resource(
        LogGroup(
            "LogIngesterLogGroup",
            LogGroupName=Join(
                "", ["/aws/lambda/", Ref(log_ingester)]),
            RetentionInDays=If(retention_defined, Ref(log_retention_days),
                               NoValue),
        ))

    log_ingester_policy = template.add_resource(
        PolicyType(
            "LogIngesterPolicy",
            Roles=[Ref(log_ingester_role)],
            PolicyName="IngestLogPolicy",
            PolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Action=[logs.CreateLogStream, logs.PutLogEvents],
                        Resource=[
                            Join(
                                ":",
                                [
                                    "arn",
                                    Partition,
                                    "logs",
                                    Region,
                                    AccountId,
                                    "log-group",
                                    "/aws/cloudfront/*",
                                ],
                            ),
                            Join(
                                ":",
                                [
                                    "arn",
                                    Partition,
                                    "logs",
                                    Region,
                                    AccountId,
                                    "log-group",
                                    "/aws/s3/*",
                                ],
                            ),
                            GetAtt(log_ingester_log_group, "Arn"),
                        ],
                    ),
                    Statement(
                        Effect=Allow,
                        Action=[s3.GetObject],
                        Resource=[Join("", [GetAtt(log_bucket, "Arn"), "/*"])],
                    ),
                ],
            ),
        ))

    bucket = template.add_resource(
        Bucket(
            "ContentBucket",
            LifecycleConfiguration=LifecycleConfiguration(Rules=[
                # not supported by CFN yet:
                # LifecycleRule(
                # Transitions=[
                # LifecycleRuleTransition(
                # StorageClass='INTELLIGENT_TIERING',
                # TransitionInDays=1,
                # ),
                # ],
                # Status="Enabled",
                # ),
                LifecycleRule(
                    AbortIncompleteMultipartUpload=
                    AbortIncompleteMultipartUpload(DaysAfterInitiation=7),
                    Status="Enabled",
                )
            ]),
            LoggingConfiguration=LoggingConfiguration(
                DestinationBucketName=Ref(log_bucket), LogFilePrefix="s3/"),
            BucketEncryption=BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=
                        ServerSideEncryptionByDefault(
                            # Origin Access Identities can't use KMS
                            SSEAlgorithm="AES256"))
                ]),
            OwnershipControls=OwnershipControls(Rules=[
                OwnershipControlsRule(ObjectOwnership="BucketOwnerPreferred")
            ], ),
            PublicAccessBlockConfiguration=PublicAccessBlockConfiguration(
                BlockPublicAcls=True,
                BlockPublicPolicy=True,
                IgnorePublicAcls=True,
                RestrictPublicBuckets=True,
            ),
        ))

    origin_access_identity = template.add_resource(
        CloudFrontOriginAccessIdentity(
            "CloudFrontIdentity",
            CloudFrontOriginAccessIdentityConfig=
            CloudFrontOriginAccessIdentityConfig(
                Comment=GetAtt(bucket, "Arn")),
        ))

    bucket_policy = template.add_resource(
        BucketPolicy(
            "ContentBucketPolicy",
            Bucket=Ref(bucket),
            PolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Principal=Principal(
                            "CanonicalUser",
                            GetAtt(origin_access_identity,
                                   "S3CanonicalUserId"),
                        ),
                        Action=[s3.GetObject],
                        Resource=[Join("", [GetAtt(bucket, "Arn"), "/*"])],
                    ),
                ],
            ),
        ))

    # Not strictly necessary, as ACLs should take care of this access. However, CloudFront docs
    # state "In some circumstances [...] S3 resets permissions on the bucket to the default value",
    # and this allows logging to work without any ACLs in place.
    log_bucket_policy = template.add_resource(
        BucketPolicy(
            "LogBucketPolicy",
            Bucket=Ref(log_bucket),
            PolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Principal=Principal("Service",
                                            "delivery.logs.amazonaws.com"),
                        Action=[s3.PutObject],
                        Resource=[
                            Join(
                                "/",
                                [GetAtt(log_bucket, "Arn"), "cloudfront", "*"])
                        ],
                    ),
                    Statement(
                        Effect=Allow,
                        Principal=Principal("Service",
                                            "delivery.logs.amazonaws.com"),
                        Action=[s3.ListBucket],
                        Resource=[Join("/", [GetAtt(log_bucket, "Arn")])],
                    ),
                    Statement(
                        Effect=Allow,
                        Principal=Principal("Service", "s3.amazonaws.com"),
                        Action=[s3.PutObject],
                        Resource=[
                            Join("/", [GetAtt(log_bucket, "Arn"), "s3", "*"])
                        ],
                    ),
                ],
            ),
        ))

    certificate_validator_dlq = template.add_resource(
        Queue(
            "CertificateValidatorDLQ",
            MessageRetentionPeriod=int(
                datetime.timedelta(days=14).total_seconds()),
            KmsMasterKeyId="alias/aws/sqs",
            Condition=should_create_certificate,
        ))

    certificate_validator_role = template.add_resource(
        Role(
            "CertificateValidatorRole",
            AssumeRolePolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect="Allow",
                        Principal=Principal("Service", "lambda.amazonaws.com"),
                        Action=[sts.AssumeRole],
                    )
                ],
            ),
            Policies=[
                PolicyProperty(
                    PolicyName="DLQPolicy",
                    PolicyDocument=PolicyDocument(
                        Version="2012-10-17",
                        Statement=[
                            Statement(
                                Effect=Allow,
                                Action=[sqs.SendMessage],
                                Resource=[
                                    GetAtt(certificate_validator_dlq, "Arn")
                                ],
                            )
                        ],
                    ),
                )
            ],
            # TODO scope down
            ManagedPolicyArns=[
                "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
                "arn:aws:iam::aws:policy/AmazonRoute53FullAccess",
                "arn:aws:iam::aws:policy/AWSCertificateManagerReadOnly",
            ],
            Condition=should_create_certificate,
        ))

    certificate_validator_function = template.add_resource(
        Function(
            "CertificateValidatorFunction",
            Runtime=PYTHON_RUNTIME,
            Handler="index.{}".format(certificate_validator.handler.__name__),
            Code=Code(ZipFile=inspect.getsource(certificate_validator)),
            MemorySize=256,
            Timeout=300,
            Role=GetAtt(certificate_validator_role, "Arn"),
            DeadLetterConfig=DeadLetterConfig(
                TargetArn=GetAtt(certificate_validator_dlq, "Arn")),
            Environment=Environment(
                Variables={
                    certificate_validator.EnvVars.HOSTED_ZONE_ID.name:
                    Ref(hosted_zone_id)
                }),
            Condition=should_create_certificate,
        ))

    certificate_validator_log_group = template.add_resource(
        LogGroup(
            "CertificateValidatorLogGroup",
            LogGroupName=Join(
                "", ["/aws/lambda/",
                     Ref(certificate_validator_function)]),
            RetentionInDays=If(retention_defined, Ref(log_retention_days),
                               NoValue),
            Condition=should_create_certificate,
        ))

    certificate_validator_rule = template.add_resource(
        Rule(
            "CertificateValidatorRule",
            EventPattern={
                "detail-type": ["AWS API Call via CloudTrail"],
                "detail": {
                    "eventSource": ["acm.amazonaws.com"],
                    "eventName": ["AddTagsToCertificate"],
                    "requestParameters": {
                        "tags": {
                            "key": [certificate_validator_function.title],
                            "value":
                            [GetAtt(certificate_validator_function, "Arn")],
                        }
                    },
                },
            },
            Targets=[
                Target(
                    Id="certificate-validator-lambda",
                    Arn=GetAtt(certificate_validator_function, "Arn"),
                )
            ],
            DependsOn=[certificate_validator_log_group],
            Condition=should_create_certificate,
        ))

    certificate_validator_permission = template.add_resource(
        Permission(
            "CertificateValidatorPermission",
            FunctionName=GetAtt(certificate_validator_function, "Arn"),
            Action="lambda:InvokeFunction",
            Principal="events.amazonaws.com",
            SourceArn=GetAtt(certificate_validator_rule, "Arn"),
            Condition=should_create_certificate,
        ))

    certificate = template.add_resource(
        Certificate(
            "Certificate",
            DomainName=Select(0, Ref(dns_names)),
            SubjectAlternativeNames=Ref(
                dns_names),  # duplicate first name works fine
            ValidationMethod="DNS",
            Tags=Tags(
                **{
                    certificate_validator_function.title:
                    GetAtt(certificate_validator_function, "Arn")
                }),
            DependsOn=[certificate_validator_permission],
            Condition=should_create_certificate,
        ))

    edge_hook_role = template.add_resource(
        Role(
            "EdgeHookRole",
            AssumeRolePolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect="Allow",
                        Principal=Principal(
                            "Service",
                            [
                                "lambda.amazonaws.com",
                                "edgelambda.amazonaws.com"
                            ],
                        ),
                        Action=[sts.AssumeRole],
                    )
                ],
            ),
        ))

    edge_hook_function = template.add_resource(
        Function(
            "EdgeHookFunction",
            Runtime=PYTHON_RUNTIME,
            Handler="index.handler",
            Code=Code(ZipFile=inspect.getsource(edge_hook)),
            MemorySize=128,
            Timeout=3,
            Role=GetAtt(edge_hook_role, "Arn"),
        ))
    edge_hook_function_hash = (hashlib.sha256(
        json.dumps(edge_hook_function.to_dict(),
                   sort_keys=True).encode("utf-8")).hexdigest()[:10].upper())

    edge_hook_version = template.add_resource(
        Version(
            "EdgeHookVersion" + edge_hook_function_hash,
            FunctionName=GetAtt(edge_hook_function, "Arn"),
        ))

    replica_log_group_name = Join(
        "/",
        [
            "/aws/lambda",
            Join(
                ".",
                [
                    FindInMap(partition_config, Partition, "PrimaryRegion"),
                    Ref(edge_hook_function),
                ],
            ),
        ],
    )

    edge_hook_role_policy = template.add_resource(
        PolicyType(
            "EdgeHookRolePolicy",
            PolicyName="write-logs",
            PolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Action=[logs.CreateLogStream, logs.PutLogEvents],
                        Resource=[
                            Join(
                                ":",
                                [
                                    "arn",
                                    Partition,
                                    "logs",
                                    "*",
                                    AccountId,
                                    "log-group",
                                    replica_log_group_name,
                                    "log-stream",
                                    "*",
                                ],
                            ),
                        ],
                    ),
                ],
            ),
            Roles=[Ref(edge_hook_role)],
        ))

    stack_set_administration_role = template.add_resource(
        Role(
            "StackSetAdministrationRole",
            AssumeRolePolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Principal=Principal("Service",
                                            "cloudformation.amazonaws.com"),
                        Action=[sts.AssumeRole],
                    ),
                ],
            ),
        ))

    stack_set_execution_role = template.add_resource(
        Role(
            "StackSetExecutionRole",
            AssumeRolePolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Principal=Principal(
                            "AWS", GetAtt(stack_set_administration_role,
                                          "Arn")),
                        Action=[sts.AssumeRole],
                    ),
                ],
            ),
            Policies=[
                PolicyProperty(
                    PolicyName="create-stackset-instances",
                    PolicyDocument=PolicyDocument(
                        Version="2012-10-17",
                        Statement=[
                            Statement(
                                Effect=Allow,
                                Action=[
                                    cloudformation.DescribeStacks,
                                    logs.DescribeLogGroups,
                                ],
                                Resource=["*"],
                            ),
                            # stack instances communicate with the CFN service via SNS
                            Statement(
                                Effect=Allow,
                                Action=[sns.Publish],
                                NotResource=[
                                    Join(
                                        ":",
                                        [
                                            "arn", Partition, "sns", "*",
                                            AccountId, "*"
                                        ],
                                    )
                                ],
                            ),
                            Statement(
                                Effect=Allow,
                                Action=[
                                    logs.CreateLogGroup,
                                    logs.DeleteLogGroup,
                                    logs.PutRetentionPolicy,
                                    logs.DeleteRetentionPolicy,
                                ],
                                Resource=[
                                    Join(
                                        ":",
                                        [
                                            "arn",
                                            Partition,
                                            "logs",
                                            "*",
                                            AccountId,
                                            "log-group",
                                            replica_log_group_name,
                                            "log-stream",
                                            "",
                                        ],
                                    ),
                                ],
                            ),
                            Statement(
                                Effect=Allow,
                                Action=[
                                    cloudformation.CreateStack,
                                    cloudformation.DeleteStack,
                                    cloudformation.UpdateStack,
                                ],
                                Resource=[
                                    Join(
                                        ":",
                                        [
                                            "arn",
                                            Partition,
                                            "cloudformation",
                                            "*",
                                            AccountId,
                                            Join(
                                                "/",
                                                [
                                                    "stack",
                                                    Join(
                                                        "-",
                                                        [
                                                            "StackSet",
                                                            StackName, "*"
                                                        ],
                                                    ),
                                                ],
                                            ),
                                        ],
                                    )
                                ],
                            ),
                        ],
                    ),
                ),
            ],
        ))

    stack_set_administration_role_policy = template.add_resource(
        PolicyType(
            "StackSetAdministrationRolePolicy",
            PolicyName="assume-execution-role",
            PolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Action=[sts.AssumeRole],
                        Resource=[GetAtt(stack_set_execution_role, "Arn")],
                    ),
                ],
            ),
            Roles=[Ref(stack_set_administration_role)],
        ))

    edge_log_groups = template.add_resource(
        StackSet(
            "EdgeLambdaLogGroupStackSet",
            AdministrationRoleARN=GetAtt(stack_set_administration_role, "Arn"),
            ExecutionRoleName=Ref(stack_set_execution_role),
            StackSetName=Join("-", [StackName, "EdgeLambdaLogGroup"]),
            PermissionModel="SELF_MANAGED",
            Description="Multi-region log groups for Lambda@Edge replicas",
            Parameters=[
                StackSetParameter(
                    ParameterKey="LogGroupName",
                    ParameterValue=replica_log_group_name,
                ),
                StackSetParameter(
                    ParameterKey="LogRetentionDays",
                    ParameterValue=Ref(log_retention_days),
                ),
            ],
            OperationPreferences=OperationPreferences(
                FailureToleranceCount=0,
                MaxConcurrentPercentage=100,
            ),
            StackInstancesGroup=[
                StackInstances(
                    DeploymentTargets=DeploymentTargets(Accounts=[AccountId]),
                    Regions=FindInMap(partition_config, Partition,
                                      "DefaultRegions"),
                )
            ],
            TemplateBody=create_log_group_template().to_json(indent=None),
            DependsOn=[stack_set_administration_role_policy],
        ))

    price_class_distribution = template.add_resource(
        Distribution(
            "PriceClassDistribution",
            DistributionConfig=DistributionConfig(
                Comment="Dummy distribution used for price class hack",
                DefaultCacheBehavior=DefaultCacheBehavior(
                    TargetOriginId="default",
                    ViewerProtocolPolicy="allow-all",
                    ForwardedValues=ForwardedValues(QueryString=False),
                ),
                Enabled=True,
                Origins=[
                    Origin(Id="default",
                           DomainName=GetAtt(bucket, "DomainName"))
                ],
                IPV6Enabled=True,
                ViewerCertificate=ViewerCertificate(
                    CloudFrontDefaultCertificate=True),
                PriceClass="PriceClass_All",
            ),
            Condition=using_price_class_hack,
        ))

    distribution = template.add_resource(
        Distribution(
            "ContentDistribution",
            DistributionConfig=DistributionConfig(
                Enabled=True,
                Aliases=If(using_dns_names, Ref(dns_names), NoValue),
                Logging=Logging(Bucket=GetAtt(log_bucket, "DomainName"),
                                Prefix="cloudfront/"),
                DefaultRootObject="index.html",
                Origins=[
                    Origin(
                        Id="default",
                        DomainName=GetAtt(bucket, "DomainName"),
                        S3OriginConfig=S3OriginConfig(
                            OriginAccessIdentity=Join(
                                "",
                                [
                                    "origin-access-identity/cloudfront/",
                                    Ref(origin_access_identity),
                                ],
                            )),
                    )
                ],
                DefaultCacheBehavior=DefaultCacheBehavior(
                    TargetOriginId="default",
                    Compress=True,
                    ForwardedValues=ForwardedValues(QueryString=False),
                    ViewerProtocolPolicy="redirect-to-https",
                    DefaultTTL=Ref(default_ttl_seconds),
                    LambdaFunctionAssociations=[
                        LambdaFunctionAssociation(
                            EventType="origin-request",
                            LambdaFunctionARN=Ref(edge_hook_version),
                        )
                    ],
                ),
                HttpVersion="http2",
                IPV6Enabled=True,
                ViewerCertificate=ViewerCertificate(
                    AcmCertificateArn=If(
                        using_acm_certificate,
                        Ref(acm_certificate_arn),
                        If(using_hosted_zone, Ref(certificate), NoValue),
                    ),
                    SslSupportMethod=If(using_certificate, "sni-only",
                                        NoValue),
                    CloudFrontDefaultCertificate=If(using_certificate, NoValue,
                                                    True),
                    MinimumProtocolVersion=Ref(tls_protocol_version),
                ),
                PriceClass=If(using_price_class_hack, "PriceClass_100",
                              "PriceClass_All"),
            ),
            DependsOn=[
                bucket_policy,
                log_ingester_policy,
                edge_log_groups,
                precondition_region_is_primary,
            ],
        ))

    distribution_log_group = template.add_resource(
        LogGroup(
            "DistributionLogGroup",
            LogGroupName=Join(
                "", ["/aws/cloudfront/", Ref(distribution)]),
            RetentionInDays=If(retention_defined, Ref(log_retention_days),
                               NoValue),
        ))

    bucket_log_group = template.add_resource(
        LogGroup(
            "BucketLogGroup",
            LogGroupName=Join("", ["/aws/s3/", Ref(bucket)]),
            RetentionInDays=If(retention_defined, Ref(log_retention_days),
                               NoValue),
        ))

    template.add_output(Output("DistributionId", Value=Ref(distribution)))

    template.add_output(
        Output("DistributionDomain", Value=GetAtt(distribution, "DomainName")))

    template.add_output(
        Output(
            "DistributionDnsTarget",
            Value=If(
                using_price_class_hack,
                GetAtt(price_class_distribution, "DomainName"),
                GetAtt(distribution, "DomainName"),
            ),
        ))

    template.add_output(
        Output(
            "DistributionUrl",
            Value=Join("",
                       ["https://",
                        GetAtt(distribution, "DomainName"), "/"]),
        ))

    template.add_output(Output("ContentBucketArn", Value=GetAtt(bucket,
                                                                "Arn")))

    return template
    "};",
]

# Create the Lambda function
foobar_function = t.add_resource(
    Function(
        "FoobarFunction",
        Code=Code(ZipFile=Join("", code)),
        Handler="index.handler",
        Role=GetAtt("LambdaExecutionRole", "Arn"),
        Runtime="nodejs",
    ))

# Create the Event Target
foobar_target = Target("FoobarTarget",
                       Arn=GetAtt("FoobarFunction", "Arn"),
                       Id="FooBarFunction1")

# Create the Event Rule
rule = t.add_resource(
    Rule(
        "FoobarRule",
        EventPattern={
            "source": ["aws.ec2"],
            "detail-type": ["EC2 Instance State-change Notification"],
            "detail": {
                "state": ["stopping"]
            },
        },
        Description="Foobar CloudWatch Event",
        State="ENABLED",
Пример #11
0
          StageName=stage_name,
          RestApiId=Ref(rest_api),
          DeploymentId=Ref(deployment)))

t.add_output([
    Output("ApiEndpoint",
           Value=Join("", [
               "https://",
               Ref(rest_api), ".execute-api.",
               Ref('AWS::Region'), ".amazonaws.com/", stage_name
           ]),
           Description="Endpoint for this stage of the api")
])

#Event Target (for email scheduling)
event_target_daily_emailer = Target("DailyEmailerTarget",
                                    Arn=GetAtt("EmailSendFunction", "Arn"),
                                    Id="DailyEmailerTargetFunction")

# Schedule the emailer to run daily
event_rule_daily_emailer = t.add_resource(
    Rule("DailyEmailsRule",
         ScheduleExpression="cron(0 23 * * ? *)",
         Name="DailyEmailListRule",
         State="ENABLED",
         Targets=[event_target_daily_emailer]))

# Project wants yaml instead of json
#print(t.to_json())
print(t.to_yaml())
Пример #12
0
 def create_target(self, arn, target_id, name_prefix=''):
     return Target('{0}Target'.format(name_prefix), Arn=arn, Id=target_id)
Пример #13
0
        "KmsKeyArn": GetAtt(kms_key, "Arn"),
        "Environment": Environment(
            Variables={
                "HyP3StackName": Ref("AWS::StackName")
            }
        ),
        "Timeout": 60
    }
))

custom_metric_target = Target(
    "CustomMetricTarget",
    Arn=GetAtt(custom_metric, 'Arn'),
    Id="CustomMetricFunction1",
    Input=Sub(
        '{"QueueUrl":"${QueueUrl}","AutoScalingGroupName":"${AGName}","MetricName":"${MetricName}"}',
        QueueUrl=Ref(start_events),
        AGName=Ref(processing_group),
        MetricName=custom_metric_name
    )
)

custom_metric_rule = t.add_resource(Rule(
    "CustomMetricSchedule",
    ScheduleExpression="rate(1 minute)",
    State="ENABLED",
    Targets=[custom_metric_target]
))

PermissionForEventsToInvokeLambda = t.add_resource(Permission(
    "EventScheduleCustomMetricPermissions",
Пример #14
0
            ],
            "requestParameters": {
                "bucketName": [
                    {"Ref": S3_DELIVERY_BUCKET}
                ],
                "key": [
                    S3_OBJECT_Key
                ]
            }
        }
    },
    Targets=[
        Target(
            Arn=Join(
                "",
                ['arn:aws:codepipeline:', Region, ":", AccountId, ":", BUILD_NAME]
            ),
            Id='CodePipelineTarget',
            RoleArn=GetAtt(EventRole, "Arn"),
        )
    ]
))

BucketPolicy = t.add_resource(BucketPolicy(
    "BucketPolicy",
    PolicyDocument={
        "Statement": [
                {
                "Sid": "AWSCloudTrailAclCheck",
                "Effect": "Allow",
                "Principal": {
                    "Service": [
Пример #15
0
 def add_target_lambda_demo(self):
     self.lambda_target = Target("SpotLambdaTargetDemo",
                                 Arn=GetAtt(self.lambda_function, 'Arn'),
                                 Id="LambdaTarget2")
            iam.Policy(
                PolicyName="LambdaPolicy",
                PolicyDocument=aws.Policy(Statement=[
                    aws.Statement(Effect=aws.Allow,
                                  Action=[
                                      aws.Action("logs", "CreateLogGroup"),
                                      aws.Action("logs", "CreateLogStream"),
                                      aws.Action("logs", "PutLogEvents"),
                                  ],
                                  Resource=["arn:aws:logs:*:*:*"])
                ]))
        ]))

# Create the Event Target
GuardDutyEventTarget = Target("GuardDutyEventTarget",
                              Arn=GetAtt('GuardDutyToSlackFunction', 'Arn'),
                              Id="GuardDutyToSlackFunction")

# Create the Event Rule
GuardDutyEventRule = t.add_resource(
    Rule("GuardDutyEventRule",
         EventPattern={
             "source": ["aws.guardduty"],
             "detail-type": ["GuardDuty Finding"]
         },
         Description="GuardDuty CloudWatch Event Rule",
         State="ENABLED",
         Targets=[GuardDutyEventTarget]))

# Create invoke Permission
APILambdaPermission = t.add_resource(
             MemorySize=Ref(memory_size),
             Timeout=Ref(timeout)))

manage_snapshots_function = template.add_resource(
    Function("ManageSnapshots",
             Description=
             "Function deletes volume snapshots basted on ec2 instance tags",
             Code=Code(S3Bucket=Ref(s3_bucket), S3Key="backup-manager.zip"),
             Handler="ebs-snapshot-manager.lambda_handler",
             Role=GetAtt("LambdaExecutionRole", "Arn"),
             Runtime="python2.7",
             MemorySize=Ref(memory_size),
             Timeout=Ref(timeout)))

create_backup_target = Target("CreateBackupTarget",
                              Arn=GetAtt(create_snapshots_function, 'Arn'),
                              Id="CreateBackupFunction1")

create_backup_rule = template.add_resource(
    Rule("CreateBackupRule",
         ScheduleExpression="cron(0 7 * * ? *)",
         Description="Create backups event rule",
         State="ENABLED",
         Targets=[create_backup_target]))

manage_backup_target = Target("ManageBackupTarget",
                              Arn=GetAtt(manage_snapshots_function, 'Arn'),
                              Id="ManageBackupFunction1")

manage_backup_rule = template.add_resource(
    Rule("ManageBackupRule",
Пример #18
0
    def _deploy_service(self, service: ff.Service):
        context = self._context_map.get_context(service.name)
        if self._aws_config.get('image_uri') is None:
            self._package_and_deploy_code(context)

        template = Template()
        template.set_version('2010-09-09')

        memory_size = template.add_parameter(
            Parameter(f'{self._lambda_resource_name(service.name)}MemorySize',
                      Type=NUMBER,
                      Default=self._aws_config.get('memory_sync', '3008')))

        timeout_gateway = template.add_parameter(
            Parameter(
                f'{self._lambda_resource_name(service.name)}GatewayTimeout',
                Type=NUMBER,
                Default='30'))

        timeout_async = template.add_parameter(
            Parameter(
                f'{self._lambda_resource_name(service.name)}AsyncTimeout',
                Type=NUMBER,
                Default='900'))

        role_title = f'{self._lambda_resource_name(service.name)}ExecutionRole'
        role = self._add_role(role_title, template)

        params = {
            'FunctionName': f'{self._service_name(service.name)}Sync',
            'Role': GetAtt(role_title, 'Arn'),
            'MemorySize': Ref(memory_size),
            'Timeout': Ref(timeout_gateway),
            'Environment': self._lambda_environment(context)
        }

        image_uri = self._aws_config.get('image_uri')
        if image_uri is not None:
            params.update({
                'Code': Code(ImageUri=image_uri),
                'PackageType': 'Image',
            })
        else:
            params.update({
                'Code':
                Code(S3Bucket=self._bucket, S3Key=self._code_key),
                'Runtime':
                'python3.7',
                'Handler':
                'handlers.main',
            })

        if self._security_group_ids and self._subnet_ids:
            params['VpcConfig'] = VPCConfig(
                SecurityGroupIds=self._security_group_ids,
                SubnetIds=self._subnet_ids)
        api_lambda = template.add_resource(
            Function(f'{self._lambda_resource_name(service.name)}Sync',
                     **params))

        route = inflection.dasherize(context.name)
        proxy_route = f'{route}/{{proxy+}}'
        template.add_resource(
            Permission(
                f'{self._lambda_resource_name(service.name)}SyncPermission',
                Action='lambda:InvokeFunction',
                FunctionName=f'{self._service_name(service.name)}Sync',
                Principal='apigateway.amazonaws.com',
                SourceArn=Join('', [
                    'arn:aws:execute-api:', self._region, ':',
                    self._account_id, ':',
                    ImportValue(
                        self._rest_api_reference()), '/*/*/', route, '*'
                ]),
                DependsOn=api_lambda))

        if self._adaptive_memory:
            value = '3008' if not self._adaptive_memory else '256'
            try:
                value = int(self._aws_config.get('memory_async'))
            except ValueError:
                pass
            memory_size = template.add_parameter(
                Parameter(
                    f'{self._lambda_resource_name(service.name)}MemorySizeAsync',
                    Type=NUMBER,
                    Default=value))

        params = {
            'FunctionName': self._lambda_function_name(service.name, 'Async'),
            'Role': GetAtt(role_title, 'Arn'),
            'MemorySize': Ref(memory_size),
            'Timeout': Ref(timeout_async),
            'Environment': self._lambda_environment(context)
        }

        if image_uri is not None:
            params.update({
                'Code': Code(ImageUri=image_uri),
                'PackageType': 'Image',
            })
        else:
            params.update({
                'Code':
                Code(S3Bucket=self._bucket, S3Key=self._code_key),
                'Runtime':
                'python3.7',
                'Handler':
                'handlers.main',
            })

        if self._security_group_ids and self._subnet_ids:
            params['VpcConfig'] = VPCConfig(
                SecurityGroupIds=self._security_group_ids,
                SubnetIds=self._subnet_ids)
        async_lambda = template.add_resource(
            Function(self._lambda_resource_name(service.name, type_='Async'),
                     **params))

        if self._adaptive_memory:
            self._add_adaptive_memory_functions(template, context,
                                                timeout_async, role_title,
                                                async_lambda)
            # self._add_adaptive_memory_streams(template, context, async_lambda, role)

        # Timers
        for cls, _ in context.command_handlers.items():
            if cls.has_timer():
                timer = cls.get_timer()
                if timer.environment is not None and timer.environment != self._env:
                    continue
                if isinstance(timer.command, str):
                    timer_name = timer.command
                else:
                    timer_name = timer.command.__name__

                target = Target(
                    f'{self._service_name(service.name)}AsyncTarget',
                    Arn=GetAtt(
                        self._lambda_resource_name(service.name,
                                                   type_='Async'), 'Arn'),
                    Id=self._lambda_resource_name(service.name, type_='Async'),
                    Input=
                    f'{{"_context": "{context.name}", "_type": "command", "_name": "{cls.__name__}"}}'
                )
                rule = template.add_resource(
                    Rule(f'{timer_name}TimerRule',
                         ScheduleExpression=f'cron({timer.cron})',
                         State='ENABLED',
                         Targets=[target]))
                template.add_resource(
                    Permission(f'{timer_name}TimerPermission',
                               Action='lambda:invokeFunction',
                               Principal='events.amazonaws.com',
                               FunctionName=Ref(async_lambda),
                               SourceArn=GetAtt(rule, 'Arn')))

        integration = template.add_resource(
            Integration(
                self._integration_name(context.name),
                ApiId=ImportValue(self._rest_api_reference()),
                PayloadFormatVersion='2.0',
                IntegrationType='AWS_PROXY',
                IntegrationUri=Join('', [
                    'arn:aws:lambda:',
                    self._region,
                    ':',
                    self._account_id,
                    ':function:',
                    Ref(api_lambda),
                ]),
            ))

        template.add_resource(
            Route(f'{self._route_name(context.name)}Base',
                  ApiId=ImportValue(self._rest_api_reference()),
                  RouteKey=f'ANY /{route}',
                  AuthorizationType='NONE',
                  Target=Join(
                      '/', ['integrations', Ref(integration)]),
                  DependsOn=integration))

        template.add_resource(
            Route(f'{self._route_name(context.name)}Proxy',
                  ApiId=ImportValue(self._rest_api_reference()),
                  RouteKey=f'ANY /{proxy_route}',
                  AuthorizationType='NONE',
                  Target=Join(
                      '/', ['integrations', Ref(integration)]),
                  DependsOn=integration))

        # Error alarms / subscriptions

        if 'errors' in self._aws_config:
            alerts_topic = template.add_resource(
                Topic(self._alert_topic_name(service.name),
                      TopicName=self._alert_topic_name(service.name)))

            if 'email' in self._aws_config.get('errors'):
                for address in self._aws_config.get('errors').get('email').get(
                        'recipients').split(','):
                    template.add_resource(
                        SubscriptionResource(
                            self._alarm_subscription_name(context.name),
                            Protocol='email',
                            Endpoint=address,
                            TopicArn=self._alert_topic_arn(context.name),
                            DependsOn=[alerts_topic]))

        # Queues / Topics

        subscriptions = {}
        for subscription in self._get_subscriptions(context):
            if subscription['context'] not in subscriptions:
                subscriptions[subscription['context']] = []
            subscriptions[subscription['context']].append(subscription)

        dlq = template.add_resource(
            Queue(f'{self._queue_name(context.name)}Dlq',
                  QueueName=f'{self._queue_name(context.name)}Dlq',
                  VisibilityTimeout=905,
                  ReceiveMessageWaitTimeSeconds=20,
                  MessageRetentionPeriod=1209600))
        self._queue_policy(template, dlq,
                           f'{self._queue_name(context.name)}Dlq',
                           subscriptions)

        queue = template.add_resource(
            Queue(self._queue_name(context.name),
                  QueueName=self._queue_name(context.name),
                  VisibilityTimeout=905,
                  ReceiveMessageWaitTimeSeconds=20,
                  MessageRetentionPeriod=1209600,
                  RedrivePolicy=RedrivePolicy(deadLetterTargetArn=GetAtt(
                      dlq, 'Arn'),
                                              maxReceiveCount=1000),
                  DependsOn=dlq))
        self._queue_policy(template, queue, self._queue_name(context.name),
                           subscriptions)

        template.add_resource(
            EventSourceMapping(
                f'{self._lambda_resource_name(context.name)}AsyncMapping',
                BatchSize=1,
                Enabled=True,
                EventSourceArn=GetAtt(queue, 'Arn'),
                FunctionName=self._lambda_function_name(service.name, 'Async'),
                DependsOn=[queue, async_lambda]))
        topic = template.add_resource(
            Topic(self._topic_name(context.name),
                  TopicName=self._topic_name(context.name)))

        for context_name, list_ in subscriptions.items():
            if context_name == context.name and len(list_) > 0:
                template.add_resource(
                    SubscriptionResource(
                        self._subscription_name(context_name),
                        Protocol='sqs',
                        Endpoint=GetAtt(queue, 'Arn'),
                        TopicArn=self._topic_arn(context.name),
                        FilterPolicy={
                            '_name': [x['name'] for x in list_],
                        },
                        RedrivePolicy={
                            'deadLetterTargetArn': GetAtt(dlq, 'Arn'),
                        },
                        DependsOn=[queue, dlq, topic]))
            elif len(list_) > 0:
                if context_name not in self._context_map.contexts:
                    self._find_or_create_topic(context_name)
                template.add_resource(
                    SubscriptionResource(
                        self._subscription_name(context.name, context_name),
                        Protocol='sqs',
                        Endpoint=GetAtt(queue, 'Arn'),
                        TopicArn=self._topic_arn(context_name),
                        FilterPolicy={'_name': [x['name'] for x in list_]},
                        RedrivePolicy={
                            'deadLetterTargetArn': GetAtt(dlq, 'Arn'),
                        },
                        DependsOn=[queue, dlq]))

        # DynamoDB Table

        ddb_table = template.add_resource(
            Table(self._ddb_resource_name(context.name),
                  TableName=self._ddb_table_name(context.name),
                  AttributeDefinitions=[
                      AttributeDefinition(AttributeName='pk',
                                          AttributeType='S'),
                      AttributeDefinition(AttributeName='sk',
                                          AttributeType='S'),
                  ],
                  BillingMode='PAY_PER_REQUEST',
                  KeySchema=[
                      KeySchema(AttributeName='pk', KeyType='HASH'),
                      KeySchema(AttributeName='sk', KeyType='RANGE'),
                  ],
                  TimeToLiveSpecification=TimeToLiveSpecification(
                      AttributeName='TimeToLive', Enabled=True)))

        template.add_output(
            Output("DDBTable",
                   Value=Ref(ddb_table),
                   Description="Document table"))

        for cb in self._pre_deployment_hooks:
            cb(template=template, context=context, env=self._env)

        self.info('Deploying stack')
        self._s3_client.put_object(Body=template.to_json(),
                                   Bucket=self._bucket,
                                   Key=self._template_key)
        url = self._s3_client.generate_presigned_url(ClientMethod='get_object',
                                                     Params={
                                                         'Bucket':
                                                         self._bucket,
                                                         'Key':
                                                         self._template_key
                                                     })

        stack_name = self._stack_name(context.name)
        try:
            self._cloudformation_client.describe_stacks(StackName=stack_name)
            self._update_stack(self._stack_name(context.name), url)
        except ClientError as e:
            if f'Stack with id {stack_name} does not exist' in str(e):
                self._create_stack(self._stack_name(context.name), url)
            else:
                raise e

        for cb in self._post_deployment_hooks:
            cb(template=template, context=context, env=self._env)

        self._migrate_schema(context)

        self.info('Done')
    "};",
]

# Create the Lambda function
foobar_function = t.add_resource(
    Function(
        "FoobarFunction",
        Code=Code(ZipFile=Join("", code)),
        Handler="index.handler",
        Role=GetAtt("LambdaExecutionRole", "Arn"),
        Runtime="nodejs",
    ))

# Create the Event Target
foobar_target = Target("FoobarTarget",
                       Arn=GetAtt('FoobarFunction', 'Arn'),
                       Id="FooBarFunction1")

# Create the Event Rule
rule = t.add_resource(
    Rule("FoobarRule",
         EventPattern={
             "source": ["aws.ec2"],
             "detail-type": ["EC2 Instance State-change Notification"],
             "detail": {
                 "state": ["stopping"]
             }
         },
         Description="Foobar CloudWatch Event",
         State="ENABLED",
         Targets=[foobar_target]))
Пример #20
0
    def add_resources(self):
        """Create Resources to deploy Limit Monitor."""
        template = self.template
        variables = self.get_variables()

        path = os.path.dirname(os.path.abspath(path=__file__))
        stacker_dict = yaml.safe_load(
            open(path + '/' + '../01_limit_monitor_spoke_us-east-1.yaml'))

        service_item = ''
        for item in stacker_dict['stacks']['servicelimitmonitorspoke'][
                'variables']['SERVICES']:
            quoted_item = '"' + item + '"'
            service_item = service_item + quoted_item + ','
        """Adding Mapping for AnonymousData"""
        template.add_mapping('MetricsMap',
                             {'Send-Data': {
                                 'SendAnonymousData': 'Yes'
                             }})
        """Adding Mapping for RefreshRate."""
        template.add_mapping('RefreshRate',
                             {'CronSchedule': {
                                 'Default': 'rate(1 day)'
                             }})
        """Adding Mapping for SourceCode."""
        template.add_mapping(
            'SourceCode', {
                'General': {
                    'S3Bucket': 'solutions',
                    'KeyPrefix': 'limit-monitor/v5.1.1'
                }
            })

        # """Adding Mapping for EventsMap."""
        # template.add_mapping(
        #     'EventsMap', {
        #         'Checks': {
        #             'Services': '"AutoScaling","CloudFormation","EBS","EC2","ELB","IAM","RDS","VPC"'
        #
        #         }
        #     }
        # )

        s3_bucket = FindInMap('SourceCode', 'General', 'S3Bucket')
        s3_key = FindInMap('SourceCode', 'General', 'KeyPrefix')
        """TAOkRule Target Resource Definition."""

        ta_ok_rule_target = Target(
            'TAOkRuleTarget',
            Arn=Join(':', [
                'arn:aws:events', 'us-east-1',
                str(variables['MasterAccount'].value), 'event-bus/default'
            ]),
            Id='SpokeOkTarget',
        )
        """CWR - Rule for TA OK events'."""
        template.add_resource(
            Rule('TAOkRule',
                 Description=
                 'Limit Monitor Solution - Spoke - Rule for TA OK events',
                 EventPattern={
                     'account': [Ref('AWS::AccountId')],
                     'source': ['aws.trustedadvisor'],
                     'detail-type':
                     ['Trusted Advisor Check Item Refresh Notification'],
                     'detail': {
                         'status': ["OK"],
                         'check-item-detail': {
                             'Service': variables['SERVICES'].value
                         }
                     }
                 },
                 State='ENABLED',
                 Targets=[
                     ta_ok_rule_target,
                 ]))
        """TAWarnRule Target Resource Definition."""

        ta_warn_rule_target = Target(
            'TAWarnRuleTarget',
            Arn=Join(':', [
                'arn:aws:events', 'us-east-1',
                str(variables['MasterAccount'].value), 'event-bus/default'
            ]),
            Id='SpokeWarnTarget',
        )
        """CWR - Rule for TA WARN events'"""
        template.add_resource(
            Rule('TAWarnRule',
                 Description=
                 'Limit Monitor Solution - Spoke - Rule for TA WARN events',
                 EventPattern={
                     'account': [Ref('AWS::AccountId')],
                     'source': ['aws.trustedadvisor'],
                     'detail-type':
                     ['Trusted Advisor Check Item Refresh Notification'],
                     'detail': {
                         'status': ["WARN"],
                         'check-item-detail': {
                             'Service': variables['SERVICES'].value
                         }
                     }
                 },
                 State='ENABLED',
                 Targets=[
                     ta_warn_rule_target,
                 ]))
        """TAErrorRule Target Resource Definition."""

        ta_error_rule_target = Target(
            'TAErrorRuleTarget',
            Arn=Join(':', [
                'arn:aws:events', 'us-east-1',
                str(variables['MasterAccount'].value), 'event-bus/default'
            ]),
            Id='SpokeErrorTarget',
        )
        """CWR - Rule for TA Error events'"""
        template.add_resource(
            Rule('TAErrorRule',
                 Description=
                 'Limit Monitor Solution - Spoke - Rule for TA WARN events',
                 EventPattern={
                     'account': [Ref('AWS::AccountId')],
                     'source': ['aws.trustedadvisor'],
                     'detail-type':
                     ['Trusted Advisor Check Item Refresh Notification'],
                     'detail': {
                         'status': ["ERROR"],
                         'check-item-detail': {
                             'Service': variables['SERVICES'].value
                         }
                     }
                 },
                 State='ENABLED',
                 Targets=[
                     ta_error_rule_target,
                 ]))
        """Create the IAM role for the TA Refresher Lambda Function"""

        ta_refresher_role = template.add_resource(
            Role('TARefresherRole',
                 AssumeRolePolicyDocument=PolicyDocument(Statement=[
                     Statement(Effect=Allow,
                               Action=[awacs.sts.AssumeRole],
                               Principal=Principal('Service',
                                                   ['lambda.amazonaws.com']))
                 ]),
                 Path='/',
                 Policies=[
                     Policy(PolicyDocument=PolicyDocument(
                         Version='2012-10-17',
                         Statement=[
                             Statement(Effect=Allow,
                                       Action=[
                                           CreateLogGroup, CreateLogStream,
                                           PutLogEvents
                                       ],
                                       Resource=[
                                           Join(':', [
                                               'arn:aws:logs',
                                               Ref('AWS::Region'),
                                               Ref('AWS::AccountId'),
                                               'log-group', '/aws/lambda/*'
                                           ])
                                       ]),
                             Statement(Effect=Allow,
                                       Action=[awacs.support.Action('*')],
                                       Resource=['*']),
                         ]),
                            PolicyName=Join('-', [
                                'Limit-Monitor-Refresher-Policy',
                                Ref('AWS::StackName')
                            ]))
                 ]))
        """Create TA Refresher Lambda Function."""

        ta_refresher = template.add_resource(
            Function(
                'TARefresher',
                Description=
                'Serverless Limit Monitor - Lambda function to summarize service limits',
                Environment=Environment(
                    Variables={
                        # 'AWS_SERVICES': FindInMap('EventsMap', 'Checks', 'Services'),
                        'AWS_SERVICES': str(service_item[:-1]),
                        'LOG_LEVEL': 'ERROR'
                    }),
                Handler='index.handler',
                Role=GetAtt(ta_refresher_role, 'Arn'),
                Code=Code(S3Bucket=Join(
                    '-', [s3_bucket, Ref('AWS::Region')]),
                          S3Key=Join('/',
                                     [s3_key, 'limtr-refresh-service.zip'])),
                Runtime='nodejs8.10',
                Timeout=300,
                DependsOn=[ta_refresher_role]))
        """Create the target for Refresh Schedule."""

        ta_refresher_target = Target('TARefreshRate',
                                     Arn=GetAtt(ta_refresher, 'Arn'),
                                     Id='SqsPollRate')
        """Create the TARefreshSchedule Rule."""

        ta_refresh_schedule = template.add_resource(
            Rule('TARefreshSchedule',
                 Description=
                 'Limit Monitor Solution - Schedule to refresh TA checks',
                 ScheduleExpression=FindInMap('RefreshRate', 'CronSchedule',
                                              'Default'),
                 State='ENABLED',
                 Targets=[ta_refresher_target],
                 DependsOn=[ta_refresher]))
        """Create the Ta Refresher Lambda Permission."""

        template.add_resource(
            Permission('TARefresherInvokePermission',
                       FunctionName=Ref(ta_refresher),
                       Action='lambda:InvokeFunction',
                       Principal='events.amazonaws.com',
                       SourceArn=GetAtt(ta_refresh_schedule, 'Arn'),
                       DependsOn=[ta_refresher]))
        """Create the Limtr Helper Role."""

        limtr_helper_role = template.add_resource(
            Role('LimtrHelperRole',
                 AssumeRolePolicyDocument=PolicyDocument(
                     Version='2012-10-17',
                     Statement=[
                         Statement(Effect=Allow,
                                   Action=[awacs.sts.AssumeRole],
                                   Principal=Principal(
                                       'Service', ['lambda.amazonaws.com']))
                     ]),
                 Path='/',
                 Policies=[
                     Policy(PolicyDocument=PolicyDocument(
                         Version='2012-10-17',
                         Statement=[
                             Statement(Effect=Allow,
                                       Action=[
                                           CreateLogGroup, CreateLogStream,
                                           PutLogEvents
                                       ],
                                       Resource=[
                                           Join(':', [
                                               'arn:aws:logs',
                                               Ref('AWS::Region'),
                                               Ref('AWS::AccountId'),
                                               'log-group', '/aws/lambda/*'
                                           ])
                                       ]),
                             Statement(
                                 Effect=Allow,
                                 Action=[PutPermission, RemovePermission],
                                 Resource=[
                                     Join(':', [
                                         'arn:aws:events',
                                         Ref('AWS::Region'),
                                         Ref('AWS::AccountId'),
                                         'event-bus/default'
                                     ])
                                 ]),
                             Statement(
                                 Effect=Allow,
                                 Action=[GetParameters, PutParameter],
                                 Resource=[
                                     Join(':', [
                                         'arn:aws:ssm',
                                         Ref('AWS::Region'),
                                         Ref('AWS::AccountId'), 'parameter/*'
                                     ])
                                 ])
                         ]),
                            PolicyName='Custom_Limtr_Helper_Permissions')
                 ]))
        """Create the Lambda Function for the Limtr Helper."""

        limtr_helper = template.add_resource(
            Function(
                'LimtrHelperFunction',
                Description=
                'This function generates UUID, establishes cross account trust '
                'on CloudWatch Event Bus and sends anonymous metric',
                Handler='index.handler',
                Environment=Environment(Variables={'LOG_LEVEL': 'ERROR'}),
                Code=Code(S3Bucket=Join(
                    '-', [s3_bucket, Ref('AWS::Region')]),
                          S3Key=Join('/',
                                     [s3_key, 'limtr-helper-service.zip'])),
                Role=GetAtt(limtr_helper_role, 'Arn'),
                Runtime='nodejs8.10',
                Timeout=300,
                DependsOn=[limtr_helper_role]))
        """Create the Custom Resource UUID."""

        create_uuid = template.add_resource(
            CustomUUID('CreateUUID', ServiceToken=GetAtt(limtr_helper, 'Arn')))
        """Create the Custom Resource DeploymentData."""

        template.add_resource(
            CustomDeploymentData('DeploymentData',
                                 ServiceToken=GetAtt(limtr_helper, 'Arn'),
                                 SOLUTION='SO0005',
                                 UUID=Ref(create_uuid),
                                 VERSION='v5.1.1',
                                 ANONYMOUS_DATA=FindInMap(
                                     'MetricsMap', 'Send-Data',
                                     'SendAnonymousData')))
        """Output for Service Checks."""

        template.add_output(
            Output('ServiceChecks',
                   Description='Service limits monitored in the account',
                   Value=str(service_item[:-1])))
Пример #21
0
                    Protocol='tcp',
                ))
        for depend in depends:
            definition.DependsOn.append(
                ContainerDependency(
                    Condition='START',
                    ContainerName=depend,
                ))
            definition.Links.append(depend)
        task.ContainerDefinitions.append(definition)
    t.add_resource(task)

    if schedule:
        target = Target(
            Id="{}-Schedule".format(name),
            Arn=GetAtt(netkan_ecs, 'Arn'),
            RoleArn=GetAtt(netkan_scheduler_role, 'Arn'),
            EcsParameters=EcsParameters(TaskDefinitionArn=Ref(task)))
        t.add_resource(
            Rule(
                '{}Rule'.format(name),
                Description='{} scheduled task'.format(name),
                ScheduleExpression=schedule,
                Targets=[target],
            ))
        continue

    t.add_resource(
        Service(
            '{}Service'.format(name),
            Cluster='NetKANCluster',
Пример #22
0
t = Template()

code = [
    "var response=require('cfn-response');",
    "exports.handler=function(event, context) {", " return 'test'; ", "}; "
]

test_function = t.add_resource(
    Function("TestFunction",
             Code=Code(ZipFile=Join("", code)),
             Handler="index.handler",
             Role=GetAtt("LambdaExecutionRole", "Arn"),
             Runtime="nodejs"))

test_target = Target("TestTarget",
                     Arn=GetAtt('TestFunction', 'Arn'),
                     Id="TestFunction1")

rule = t.add_resource(
    Rule("TestRule",
         EventPattern={
             "source": ["aws.ec2"],
             "detail-type": ["test notification"],
             "detail": {
                 "state": ["stopping"]
             }
         },
         Description="Test Cloudwatch Event",
         State="DISABLED",
         Targets=[test_target]))
                           ],
                       }],
                   })
        ],
    ))

template.add_resource(
    Rule('StartMetadataRule',
         Description=
         'Routes start metadata events to the corresponding step functions',
         EventBusName=Ref(event_bus),
         EventPattern={"source": ["spunt.video.events"]},
         Targets=[
             Target(
                 Arn=Ref(video_step_function),
                 Id='VideoStepFunction',
                 RoleArn=GetAtt(event_bridge_role, 'Arn'),
             )
         ]))

start_insights_role = template.add_resource(
    Role(
        'StartInsightsLambdaRole',
        Path="/",
        AssumeRolePolicyDocument={
            "Version":
            "2012-10-17",
            "Statement": [{
                "Action": ["sts:AssumeRole"],
                "Effect": "Allow",
                "Principal": {
def create_template():
    template = Template(
        Description="Lambda VPC interface IP allocator utility")

    vpc_id = template.add_parameter(Parameter("VpcId", Type="String"))

    image_uri = template.add_parameter(Parameter(
        "ImageUri",
        Type="String",
    ))

    deployment_id = template.add_parameter(
        Parameter(
            "DeploymentId",
            Type="String",
        ))

    role = template.add_resource(
        Role(
            "Role",
            AssumeRolePolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Action=[sts.AssumeRole],
                        Principal=Principal("Service", "lambda.amazonaws.com"),
                    ),
                ],
            ),
        ))

    function, alias = common.add_versioned_lambda(
        template,
        Ref(deployment_id),
        Function(
            "Function",
            MemorySize=256,
            Timeout=30,
            Role=GetAtt(role, "Arn"),
            PackageType="Image",
            Code=Code(ImageUri=Ref(image_uri), ),
            ImageConfig=ImageConfig(Command=[
                Join(":", (handler.__module__, handler.__name__)),
            ], ),
        ),
    )

    log_group = template.add_resource(
        LogGroup(
            "FunctionLogs",
            LogGroupName=Join("/",
                              ["/aws/lambda", Ref(function)]),
            RetentionInDays=common.LOG_RETENTION_DAYS,
        ))

    policy = template.add_resource(
        PolicyType(
            "Policy",
            PolicyName=Ref(role),
            PolicyDocument=PolicyDocument(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Action=[logs.PutLogEvents, logs.CreateLogStream],
                        Resource=[GetAtt(log_group, "Arn")],
                    ),
                    # TODO scope down
                    Statement(
                        Effect=Allow,
                        Action=[
                            ec2.AllocateAddress,
                            ec2.ReleaseAddress,
                            ec2.AssociateAddress,
                            ec2.CreateTags,
                        ],
                        Resource=[
                            Join(":", [
                                "arn", Partition, "ec2", Region, AccountId, "*"
                            ])
                        ],
                    ),
                    Statement(
                        Effect=Allow,
                        Action=[
                            ec2.DescribeAddresses,
                        ],
                        Resource=["*"],
                    ),
                ],
            ),
            Roles=[Ref(role)],
        ))

    rule_create = template.add_resource(
        Rule(
            "RuleCreate",
            EventPattern={
                "source": ["aws.ec2"],
                "detail-type": ["AWS API Call via CloudTrail"],
                "detail": {
                    "eventSource": ["ec2.amazonaws.com"],
                    "eventName": ["CreateNetworkInterface"],
                    "responseElements": {
                        "networkInterface": {
                            "vpcId": [Ref(vpc_id)],
                            "description": [{
                                "prefix": "AWS Lambda VPC ENI"
                            }],
                        },
                    },
                    "errorCode": [{
                        "exists": False
                    }],
                },
            },
            Targets=[
                Target(
                    Id="default",
                    Arn=Ref(alias),
                ),
            ],
            DependsOn=[policy],
        ))

    template.add_resource(
        Permission(
            "PermissionCreate",
            Principal="events.amazonaws.com",
            Action="lambda:InvokeFunction",
            FunctionName=Ref(alias),
            SourceArn=GetAtt(rule_create, "Arn"),
        ))

    rule_delete = template.add_resource(
        Rule(
            "RuleDelete",
            EventPattern={
                "source": ["aws.ec2"],
                "detail-type": ["AWS API Call via CloudTrail"],
                "detail": {
                    "eventSource": ["ec2.amazonaws.com"],
                    "eventName": ["DeleteNetworkInterface"],
                    "errorCode": [{
                        "exists": False
                    }],
                },
            },
            Targets=[
                Target(
                    Id="default",
                    Arn=Ref(alias),
                ),
            ],
            DependsOn=[policy],
        ))

    template.add_resource(
        Permission(
            "PermissionDelete",
            Principal="events.amazonaws.com",
            Action="lambda:InvokeFunction",
            FunctionName=Ref(alias),
            SourceArn=GetAtt(rule_delete, "Arn"),
        ))

    return template
Пример #25
0
    def scaffold(self):
        """ Create long lived stack resources for the cluster """
        self.t.add_resource(
            Cluster("Cluster", ClusterName=self.cluster_vars['name']))
        OUTPUT_SG = ["ALB", "DB", "Cache", "Aux"]
        for sg in OUTPUT_SG:
            tmpsg = SecurityGroup(
                "{}BadgeSg".format(sg),
                GroupDescription=
                "SG for {} to wear in order to talk to ecs instances".format(
                    sg),
                VpcId=self.cluster_vars.get('vpc'))
            self.t.add_resource(tmpsg)
            self.t.add_output(
                Output("{}BadgeSg".format(sg),
                       Description="{} Security Group Badge".format(sg),
                       Export=Export(Sub("${AWS::StackName}:%sBadgeSg" % sg)),
                       Value=GetAtt(tmpsg, "GroupId")))
        # Refactor like this
        ### removing this because it's in the agent now
        add_asg_cleanup(self.t,
                        sanitize_cfn_resource_name(self.cluster_vars['name']))

        # add metric lambda
        self.t.add_resource(
            Function("ECSMetricLambda",
                     Code=Code(S3Bucket=Sub("${S3Bucket}"),
                               S3Key=Sub("${S3Prefix}/deployment.zip")),
                     Handler="metrics.cluster_metrics.lambda_handler",
                     Role=GetAtt("CronLambdaRole", "Arn"),
                     Runtime="python3.7",
                     MemorySize=128,
                     Timeout=300,
                     Environment=Environment(
                         Variables={
                             "CLUSTER": Sub("${ClusterName}"),
                             "ASGPREFIX": Sub("${ClusterName}-asg-"),
                             "REGION": Ref("AWS::Region")
                         })))

        self.t.add_resource(
            Role("CronLambdaRole",
                 AssumeRolePolicyDocument={
                     "Statement": [{
                         "Effect": "Allow",
                         "Action": "sts:AssumeRole",
                         "Principal": {
                             "Service": "lambda.amazonaws.com"
                         },
                     }]
                 },
                 Policies=[
                     Policy(PolicyName="logs-and-stuff",
                            PolicyDocument={
                                "Statement": [{
                                    "Effect": "Allow",
                                    "Action": ["logs:*"],
                                    "Resource": "arn:aws:logs:*:*:*"
                                }, {
                                    "Effect":
                                    "Allow",
                                    "Action": [
                                        "ec2:DescribeAutoScalingGroups",
                                        "ec2:UpdateAutoScalingGroup", "ecs:*",
                                        "cloudwatch:PutMetricData"
                                    ],
                                    "Resource":
                                    "*"
                                }]
                            })
                 ]))
        # run metrics every minute
        self.t.add_resource(
            Rule(
                "CronStats",
                ScheduleExpression="rate(1 minute)",
                Description="Cron for cluster stats",
                Targets=[Target(Id="1", Arn=GetAtt("ECSMetricLambda",
                                                   "Arn"))]))
        self.t.add_resource(
            Permission("StatPerm",
                       Action="lambda:InvokeFunction",
                       FunctionName=GetAtt("ECSMetricLambda", "Arn"),
                       Principal="events.amazonaws.com",
                       SourceArn=GetAtt("CronStats", "Arn")))
Пример #26
0
        Rule = T.add_resource(Rule(
            'PostCrawlerRuleForETL',
            Name='PostCrawlerRuleForETL'.lower(),
            EventPattern={
                "source": ["aws.glue"],
                "detail-type": ["Glue Crawler State Change"],
                "detail": {
                    "state": [
                        "Succeeded"
                    ]
                }
            },
            Description="Post Crawler Rule for CloudWatch Event",
            State="ENABLED",
            Targets=[
                Target(
                    "PostCrawlerTarget",
                    Arn= GetAtt("PostCrawlerFnForGlueJob", "Arn"),
                    Id= "PostCrawlerTargetFunction1"
                )
            ]
        ))


# Prints the cf template file to console
print(T.to_json())

# Finally, write the template to a yaml file
with open('src_handlers/temp/cf_stack.yaml', 'w') as f:
    f.write(T.to_yaml())
Пример #27
0
    def __init__(self, title, template, dependencies, network_config,
                 lambda_config):
        """
        Amazonia lambda unit definition
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html
        https://github.com/cloudtools/troposphere/blob/master/troposphere/awslambda.py
        :param title: Title of the autoscaling application e.g 'webApp1', 'api2' or 'dataprocessing'
        :param template: Troposphere stack to append resources to
        :param dependencies: list of unit names this unit needs access to
        :param network_config: object containing network related variables
        :param lambda_config: object containing lambda related variables
        """
        super(Lambda, self).__init__(vpc=network_config.vpc,
                                     title=title,
                                     template=template)
        self.title = title
        self.dependencies = dependencies if dependencies else []

        self.function_name = Join(
            '',
            [Ref('AWS::StackName'), '-', lambda_config.lambda_function_name])

        self.trop_lambda_function = template.add_resource(
            Function(self.title,
                     Code=Code(S3Bucket=lambda_config.lambda_s3_bucket,
                               S3Key=lambda_config.lambda_s3_key),
                     Description=lambda_config.lambda_description,
                     FunctionName=self.function_name,
                     Handler=lambda_config.lambda_handler,
                     MemorySize=lambda_config.lambda_memory_size,
                     Role=lambda_config.lambda_role_arn,
                     Runtime=lambda_config.lambda_runtime,
                     Timeout=lambda_config.lambda_timeout,
                     VpcConfig=VPCConfig(
                         SubnetIds=network_config.private_subnets,
                         SecurityGroupIds=[self.security_group])))

        self.add_egress(receiver=network_config.public_cidr,
                        port='-1')  # All Traffic to Nat gateways

        if lambda_config.lambda_schedule:
            self.cwa_name = Join('', [
                Ref('AWS::StackName'), '-',
                lambda_config.lambda_function_name + 'Rule'
            ])

            self.trop_cw_rule = template.add_resource(
                Rule(self.title + 'Rule',
                     Name=self.cwa_name,
                     ScheduleExpression=lambda_config.lambda_schedule,
                     State='ENABLED',
                     Targets=[
                         Target(Arn=GetAtt(self.trop_lambda_function, 'Arn'),
                                Id=title)
                     ]))

            self.trop_cw_permission = template.add_resource(
                Permission(self.title + 'RulePermission',
                           Action='lambda:InvokeFunction',
                           FunctionName=GetAtt(self.trop_lambda_function,
                                               'Arn'),
                           Principal='events.amazonaws.com',
                           SourceArn=GetAtt(self.trop_cw_rule, 'Arn')))
Пример #28
0
            "regions": Ref(regions),
        }),
        Handler=module_name + ".handler",
        MemorySize=128,
        Role=GetAtt(lambda_role, "Arn"),
        Runtime="python2.7",
        Timeout=30,
    ))

chaos_lambda_rule = t.add_resource(
    Rule("ChaosLambdaRule",
         Description="Trigger Chaos Lambda according to a schedule",
         State="ENABLED",
         ScheduleExpression=Ref(chaos_schedule),
         Targets=[
             Target(Arn=GetAtt(lambda_function, "Arn"),
                    Id="ChaosLambdaRuleTarget")
         ]))
t.add_resource(
    Permission("ChaosLambdaRulePermission",
               FunctionName=GetAtt(lambda_function, "Arn"),
               SourceArn=GetAtt(chaos_lambda_rule, "Arn"),
               Principal="events.amazonaws.com",
               Action="lambda:InvokeFunction"))

t.add_output(
    Output("ChaosLambdaFunctionOutput",
           Value=Ref(lambda_function),
           Description="The Chaos Lambda Function"))
t.add_output(
    Output("ChaosLambdaRuleOutput",
           Value=Ref(chaos_lambda_rule),
Пример #29
0
def define_service_targets(stack, rule, cluster_arn):
    """
    Function to define the targets for service.

    :param ecs_composex.events.events_stack.XStack stack:
    :param ecs_composex.events.events_stack.Rule rule:
    :param troposphere.Sub cluster_arn:
    :return:
    """
    for service in rule.families_targets:
        service_sg_param = Parameter(f"{service[0].logical_name}GroupId",
                                     Type=SG_ID_TYPE)
        service_task_def_param = Parameter(
            f"{service[0].logical_name}{TASK_T}", Type="String")
        service_subnets_param = Parameter(
            f"{service[0].logical_name}{APP_SUBNETS.title}", Type=SUBNETS_TYPE)
        events_policy_doc = {
            "Version":
            "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": ["ecs:RunTask"],
                    "Resource": [Ref(service_task_def_param)],
                    "Condition": {
                        "ArnLike": {
                            "ecs:cluster": cluster_arn
                        }
                    },
                },
                {
                    "Effect": "Allow",
                    "Action": "iam:PassRole",
                    "Resource": ["*"],
                    "Condition": {
                        "StringLike": {
                            "iam:PassedToService":
                            Sub(f"ecs-tasks.${{{AWS_URL_SUFFIX}}}")
                        }
                    },
                },
            ],
        }
        task_events_policy_doc = {
            "Version":
            "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": ["ecs:RunTask"],
                    "Resource": [Ref(service[0].template.resources[TASK_T])],
                    "Condition": {
                        "ArnLike": {
                            "ecs:cluster": cluster_arn
                        }
                    },
                },
                {
                    "Effect": "Allow",
                    "Action": "iam:PassRole",
                    "Resource": ["*"],
                    "Condition": {
                        "StringLike": {
                            "iam:PassedToService":
                            Sub(f"ecs-tasks.${{{AWS_URL_SUFFIX}}}")
                        }
                    },
                },
            ],
        }
        events_policy = Policy(PolicyName="EventsAccess",
                               PolicyDocument=events_policy_doc)
        if "EventsAccessPolicy" not in service[0].template.resources:
            service[0].template.add_resource(
                PolicyType(
                    "EventsAccessPolicy",
                    PolicyName="EventsAccess",
                    PolicyDocument=task_events_policy_doc,
                    Roles=[
                        service[0].iam_manager.task_role.name,
                        service[0].iam_manager.exec_role.name,
                    ],
                ))
        role_name = f"{rule.logical_name}IamRoleToTrigger{service[0].logical_name}"
        if role_name not in stack.stack_template.resources:
            role = stack.stack_template.add_resource(
                Role(
                    f"{rule.logical_name}IamRoleToTrigger{service[0].logical_name}",
                    AssumeRolePolicyDocument={
                        "Version":
                        "2012-10-17",
                        "Statement": [{
                            "Sid": "TrustPolicy",
                            "Effect": "Allow",
                            "Principal": {
                                "Service": Sub(f"events.${{{AWS_URL_SUFFIX}}}")
                            },
                            "Action": "sts:AssumeRole",
                        }],
                    },
                    ManagedPolicyArns=[],
                    Policies=[events_policy],
                    PermissionsBoundary=Ref(AWS_NO_VALUE),
                ))
            if service[0].iam_manager.permissions_boundary:
                role.PermissionsBoundary = service[
                    0].iam_manager.permissions_boundary
        else:
            role = stack.stack_template.resources[role_name]
        add_parameters(
            stack.stack_template,
            [service_sg_param, service_task_def_param, service_subnets_param],
        )
        stack.Parameters.update({
            service_sg_param.title:
            GetAtt(
                service[0].logical_name,
                f"Outputs.{service[0].logical_name}GroupId",
            ),
            service_task_def_param.title:
            GetAtt(
                service[0].logical_name,
                f"Outputs.{service[0].task_definition.title}",
            ),
            service_subnets_param.title:
            GetAtt(
                service[0].logical_name,
                f"Outputs.{SERVICE_SUBNETS.title}",
            ),
        })
        target = Target(
            EcsParameters=EcsParameters(
                NetworkConfiguration=NetworkConfiguration(
                    AwsVpcConfiguration=AwsVpcConfiguration(
                        Subnets=Ref(service_subnets_param),
                        SecurityGroups=[Ref(service_sg_param)],
                        AssignPublicIp=service[0].service_networking.
                        eip_assign,
                    )),
                PlatformVersion=Ref(FARGATE_VERSION),
                TaskCount=service[3],
                TaskDefinitionArn=Ref(service_task_def_param),
                LaunchType="FARGATE",
            ),
            Arn=cluster_arn,
            Id=service[0].logical_name,
            RoleArn=GetAtt(role, "Arn"),
        )
        rule.cfn_resource.Targets.append(target)
        if service[0].logical_name not in stack.DependsOn:
            stack.DependsOn.append(service[0].logical_name)
        if (keyisset("DeleteDefaultService", service[4])
                and SERVICE_T in service[0].template.resources):
            LOG.info(
                f"Deleting ECS Service definition from stack for {service[0].name}"
            )
            del service[0].template.resources[SERVICE_T]
        if SERVICE_SCALING_TARGET in service[0].template.resources:
            LOG.warning(
                f"Target for event {rule.logical_name} also had scaling rules. Deleting"
            )
            delete_service_from_template(service)
def lambda_configuration(name):
    resources = []
    
    """
    define variables
    """
    select_function = name
    print("passing function name to configuration: {}".format(name))
    
    bucket_name = lambda_config['GLOBAL']['BUCKETNAME']
    dynamodb_table = lambda_config['DynamoDB']['table_name']
    source_file_name = lambda_config['Lambda']['functions'][select_function]['source_file_name']
    title = lambda_config['Lambda']['functions'][select_function]['title']
    load_packages = lambda_config['Lambda']['functions'][select_function]['load_packages']
    
    assigned_roles = [iam.allow_lambda_execute,        # REQUIRED TO ENABLE LOGGING
                      iam.allow_dynamodb_action]
    
    function_name = lambda_config['Lambda']['functions'][select_function]['function_name']
    function_description = lambda_config['Lambda']['functions'][select_function]['function_description']
    function_to_run = lambda_config['Lambda']['functions'][select_function]['function_to_run']
    memory_size = int(lambda_config['Lambda']['functions'][select_function]['memory_size'])
    timeout = lambda_config['Lambda']['functions'][select_function]['timeout']
    
    environment_var = lmb.Environment(
       Variables={"SITE": "https://aws.amazon.com/console/",
                  "EXPECTED":"AWS"}
       )
    
    if memory_size > 1536:
        sys.exit("Memory Size too large")
    if memory_size < 128:
        sys.exit("Memory Size too small")
    if memory_size % 64 != 0:
        sys.exit("Memory Size not a multiple of 64")
    
    source = 'lambda/{0}'.format(source_file_name)
    file_name_only = os.path.splitext(os.path.basename(source))[0]
    zip_file = file_name_only + '.zip'
    function_handler = file_name_only + '.' + function_to_run
    
    role_title = '{0}Role'.format(title)
    code_title = '{0}Code'.format(title)
    function_title = '{0}Function'.format(title)
    permission_title = '{0}Permission'.format(title)
    target_id = '{0}Target'.format(title)
    
    # Copy the source file into the S3 Bucket
    s3.zip_and_load(source, load_packages=load_packages)
    
    role = Role(
        role_title,
        AssumeRolePolicyDocument=iam.lambda_assume_role,
        Policies=assigned_roles
    )
    resources.append(role)
    
    code = lmb.Code(
        code_title,
        S3Bucket=bucket_name,
        S3Key=zip_file
    )
    
    function = lmb.Function(
       function_title,
       FunctionName=function_name,
       Description=function_description,
       Code=code,
       Handler=function_handler,
       MemorySize=memory_size,
       Role=GetAtt(role_title, "Arn"),
       Environment=environment_var,
       Runtime='python3.6',
       Timeout=timeout
    )

    resources.append(function)
    
    permission = lmb.Permission(
        permission_title,
        FunctionName=function_name,
        Action="lambda:InvokeFunction",
        Principal="events.amazonaws.com",
        DependsOn=function_title
    )
    resources.append(permission)
    print("type resources is: {} ".format(type(resources)))
    
    target = Target(
        Arn=GetAtt(function, "Arn"),
        Id=target_id
    )
    print("type target is: {}".format(target))
    """we need to return both: list of resources and target. The last will be used for CW rule """
    return [resources, target]