def register_resources_template(self, template): targets, target_lambdas = [], [] for name, target in six.iteritems(self.settings.get('targets', {})): target_lambdas.append(target['lambda']) targets.append( events.Target( Arn=self.get_destination_arn(target['lambda']), Id=self.get_function_name(target['lambda']), Input=target.get('input', ''), InputPath=target.get('input_path', ''), )) rule = events.Rule(utils.valid_cloudformation_name(self.name, "Rule"), Description=self.settings.get('description', ''), EventPattern=self.settings.get( 'event_pattern', troposphere.Ref(troposphere.AWS_NO_VALUE)), ScheduleExpression=self.settings.get( 'schedule_expression', troposphere.Ref(troposphere.AWS_NO_VALUE)), State=self.get_enabled(), Targets=targets) template.add_resource(rule) for lambda_ in target_lambdas: template.add_resource( troposphere.awslambda.Permission( utils.valid_cloudformation_name(self.name, 'rule', 'permission'), Action="lambda:InvokeFunction", FunctionName=self.get_destination_arn(lambda_), Principal="events.amazonaws.com", SourceArn=troposphere.GetAtt(rule, 'Arn'), ))
def _add_cloudwatch_event_rule( builder: Template, replication_bucket: Parameter, listener_workflow: stepfunctions.StateMachine) -> events.Rule: base_name = "ReplicationListenerEvent" trigger_role = events_trigger_stepfuntions_role( f"{base_name}Role", statemachine=listener_workflow) builder.add_resource(trigger_role) rule = events.Rule( f"{base_name}Rule", State="ENABLED", EventPattern={ "source": ["aws.s3"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventSource": ["s3.amazonaws.com"], "eventName": ["PutObject"], "requestParameters": { "bucketName": [replication_bucket.ref()] }, }, }, Targets=[ events.Target(Arn=listener_workflow.ref(), Id=f"{base_name}TriggerWorkflow", RoleArn=trigger_role.get_att("Arn")) ], ) return builder.add_resource(rule)
def build(self, t): evt = t.add_resource( events.Rule('{}Event'.format(self.name), Targets=[])) if self.schedule is not None: evt.ScheduleExpression = self.schedule if self.enabled: evt.State = 'ENABLED' else: evt.State = 'DISABLED' for val in self.targets: tg = val[0] r = val[1] role_ref = ensure_param(t, r.output_role_arn()) # noqa target = events.Target() if isinstance(tg, (awslambda.LambdaStack)): func_name_ref = ensure_param(t, tg.output_func_name()) func_arn_ref = ensure_param(t, tg.output_func_arn()) target.Id = tg.get_stack_name() target.Arn = Ref(func_arn_ref) t.add_resource( tlambda.Permission('{}EventPerm'.format( tg.get_stack_name()), Action='lambda:invokeFunction', Principal='events.amazonaws.com', FunctionName=Ref(func_name_ref), SourceArn=GetAtt(evt, 'Arn'))) evt.Targets.append(target)
def show_event_rule(events_invoke_lambda_role, show_function): return events.Rule('ShowEventRule', Description='Show words', RoleArn=GetAtt(events_invoke_lambda_role, 'Arn'), ScheduleExpression='cron(0/5 * * * ? *)', State='ENABLED', Targets=[ events.Target(Arn=GetAtt(show_function, 'Arn'), Id='ShowFunction'), ])
def rule(self) -> events.Rule: """Return the rule scheduling the fargate task.""" return events.Rule( name_to_id(self.name), Description=self.description, Name=self.name, ScheduleExpression=self.schedule_expression, State=self.state, Targets=self.targets, )
def archive_event_rule(events_invoke_lambda_role, archive_function): return events.Rule('ArchiveEventRule', Description='Archive words', RoleArn=GetAtt(events_invoke_lambda_role, 'Arn'), ScheduleExpression='cron(0/5 * * * ? *)', State='ENABLED', Targets=[ events.Target(Arn=GetAtt(archive_function, 'Arn'), Id='ArchiveFunction'), ])
def _add_pipeline_notifications(self, pipeline): subscriptions = self._create_sns_subscriptions() topic = sns.Topic( 'AppPipelineDeployments', DisplayName='AppPipelineDeployments', Subscription=subscriptions, ) self._t.add_resource(topic) topic_policy = sns.TopicPolicy( 'AllowCloudWatchEventsPublish', PolicyDocument=Policy(Version='2012-10-17', Statement=[ Statement( Sid='AllowCloudWatchEventsToPublish', Effect=Allow, Action=[_sns.Publish], Principal=Principal( 'Service', 'events.amazonaws.com'), Resource=[topic.Ref()], ) ]), Topics=[topic.Ref()], ) self._t.add_resource(topic_policy) sns_target = [events.Target(Id='1', Arn=topic.Ref())] cw_event = events.Rule( 'PipelineEvents', Description='CloudWatch Events Rule for app pipeline.', EventPattern={ "source": ["aws.codepipeline"], "detail-type": [ 'CodePipeline Action Execution State Change', ], 'detail': { 'type': { # Notify when a deploy fails/succeeds # or when an approval is needed. # We could also add something when any # part of the pipeline fails. 'category': ['Deploy', 'Approval'], }, 'pipeline': [pipeline.Ref()], } }, Targets=sns_target, ) self._t.add_resource(cw_event) return topic
def EVE_EventRules(key): for n, v in getattr(cfg, key).items(): resname = f"{key}{n}" ibox_lo_cfg = v.get("IBOX_LINKED_OBJ", {}) if isinstance(ibox_lo_cfg, str): ibox_lo_cfg = {"Base": ibox_lo_cfg} # resources Targets = [] for m, w in v["Targets"].items(): targetname = f"{resname}Targets{m}" Target = eve.Target(targetname) if m.startswith("Lambda"): permname = "%s%s" % (m.replace("Lambda", "LambdaPermission"), resname) # create ad hoc IBOX_LINKED_OBJ lo_cfg = { "Key": "LambdaPermission", "Type": "EventsRule", "Name": f"LambdaPermission{m}{resname}", "Conf": { "IBOX_RESNAME": permname, "IBOX_LINKED_OBJ_NAME": w["Arn"], "IBOX_LINKED_OBJ_INDEX": f"GetAtt('{resname}', 'Arn')", }, } ibox_lo_cfg[m] = lo_cfg if m.startswith("ECSCluster"): # add common "fixed" props auto_get_props(Target, mapname="EventsRuleTargetECSCluster", indexname=m) # add props found in yaml cfg auto_get_props(Target) Targets.append(Target) getattr(cfg, resname).update({"IBOX_LINKED_OBJ": ibox_lo_cfg}) r_Rule = eve.Rule(resname) auto_get_props(r_Rule, indexname=n) r_Rule.Targets = Targets add_obj(r_Rule)
def add_lambda_events_rule(self, title, function, **kwargs): t = self.template schedule_rule = t.add_resource( events.Rule(title + 'ScheduleRule', Targets=[ events.Target(Arn=GetAtt(function, 'Arn'), Id=title + 'LambdaFunction') ], **kwargs)) perm = t.add_resource( awslambda.Permission(title + 'LambdaInvokePermission', FunctionName=Ref(function), Action='lambda:InvokeFunction', Principal='events.amazonaws.com', SourceArn=GetAtt(schedule_rule, 'Arn'))) return schedule_rule, perm
def build_rule(name: str, schedule: str, template_name: str) -> events.Rule: experiment_template = Fis().get_template(template_name) if experiment_template is None: raise Exception("AWS FIS template not found.") else: rule = events.Rule(rule_name(name)) target = events.Target() target.Arn = GetAtt(lambda_function_name(name), "Arn") target.Id = "1" target.Input = json.dumps({ "experiment_name": fis_automated_experiment_name(template_name), "template_id": experiment_template["id"] }) rule.ScheduleExpression = schedule rule.Targets = [target] return rule
def create_template(self): """Create template (main function called by Stacker).""" template = self.template variables = self.get_variables() template.set_version("2010-09-09") template.set_description("App - Build Pipeline") # Resources boundary_arn = Join( "", [ "arn:", Partition, ":iam::", AccountId, ":policy/", variables["RolePermissionsBoundaryName"].ref, ], ) # Repo image limit is 1000 by default; this lambda function will prune # old images image_param_path = Join("", ["/", variables["AppPrefix"].ref, "/current-hash"]) image_param_arn = Join( "", [ "arn:", Partition, ":ssm:", Region, ":", AccountId, ":parameter", image_param_path, ], ) ecr_repo_arn = Join( "", [ "arn:", Partition, ":ecr:", Region, ":", AccountId, ":repository/", variables["EcrRepoName"].ref, ], ) cleanuplambdarole = template.add_resource( iam.Role( "CleanupLambdaRole", AssumeRolePolicyDocument=make_simple_assume_policy( "lambda.amazonaws.com" ), ManagedPolicyArns=[IAM_ARN_PREFIX + "AWSLambdaBasicExecutionRole"], PermissionsBoundary=boundary_arn, Policies=[ iam.Policy( PolicyName=Join( "", [variables["AppPrefix"].ref, "-ecrcleanup"] ), PolicyDocument=PolicyDocument( Version="2012-10-17", Statement=[ Statement( Action=[awacs.ssm.GetParameter], Effect=Allow, Resource=[image_param_arn], ), Statement( Action=[ awacs.ecr.DescribeImages, awacs.ecr.BatchDeleteImage, ], Effect=Allow, Resource=[ecr_repo_arn], ), ], ), ) ], ) ) cleanupfunction = template.add_resource( awslambda.Function( "CleanupFunction", Description="Cleanup stale ECR images", Code=awslambda.Code(ZipFile=variables["ECRCleanupLambdaFunction"]), Environment=awslambda.Environment( Variables={ "ECR_REPO_NAME": variables["EcrRepoName"].ref, "SSM_PARAM": image_param_path, } ), Handler="index.handler", Role=cleanuplambdarole.get_att("Arn"), Runtime="python3.6", Timeout=120, ) ) cleanuprule = template.add_resource( events.Rule( "CleanupRule", Description="Regularly invoke CleanupFunction", ScheduleExpression="rate(7 days)", State="ENABLED", Targets=[ events.Target( Arn=cleanupfunction.get_att("Arn"), Id="CleanupFunction" ) ], ) ) template.add_resource( awslambda.Permission( "AllowCWLambdaInvocation", FunctionName=cleanupfunction.ref(), Action=awacs.awslambda.InvokeFunction.JSONrepr(), Principal="events.amazonaws.com", SourceArn=cleanuprule.get_att("Arn"), ) ) appsource = template.add_resource( codecommit.Repository( "AppSource", RepositoryName=Join("-", [variables["AppPrefix"].ref, "source"]), ) ) for i in ["Name", "Arn"]: template.add_output( Output( "AppRepo%s" % i, Description="%s of app source repo" % i, Value=appsource.get_att(i), ) ) bucket = template.add_resource( s3.Bucket( "Bucket", AccessControl=s3.Private, LifecycleConfiguration=s3.LifecycleConfiguration( Rules=[ s3.LifecycleRule( NoncurrentVersionExpirationInDays=90, Status="Enabled" ) ] ), VersioningConfiguration=s3.VersioningConfiguration(Status="Enabled"), ) ) template.add_output( Output( "PipelineBucketName", Description="Name of pipeline bucket", Value=bucket.ref(), ) ) # This list must be kept in sync between the CodeBuild project and its # role build_name = Join("", [variables["AppPrefix"].ref, "-build"]) build_role = template.add_resource( iam.Role( "BuildRole", AssumeRolePolicyDocument=make_simple_assume_policy( "codebuild.amazonaws.com" ), PermissionsBoundary=boundary_arn, Policies=[ iam.Policy( PolicyName=Join("", [build_name, "-policy"]), PolicyDocument=PolicyDocument( Version="2012-10-17", Statement=[ Statement( Action=[awacs.s3.GetObject], Effect=Allow, Resource=[Join("", [bucket.get_att("Arn"), "/*"])], ), Statement( Action=[awacs.ecr.GetAuthorizationToken], Effect=Allow, Resource=["*"], ), Statement( Action=[ awacs.ecr.BatchCheckLayerAvailability, awacs.ecr.BatchGetImage, awacs.ecr.CompleteLayerUpload, awacs.ecr.DescribeImages, awacs.ecr.GetDownloadUrlForLayer, awacs.ecr.InitiateLayerUpload, awacs.ecr.PutImage, awacs.ecr.UploadLayerPart, ], Effect=Allow, Resource=[ecr_repo_arn], ), Statement( Action=[ awacs.ssm.GetParameter, awacs.ssm.PutParameter, ], Effect=Allow, Resource=[image_param_arn], ), Statement( Action=[ awacs.logs.CreateLogGroup, awacs.logs.CreateLogStream, awacs.logs.PutLogEvents, ], Effect=Allow, Resource=[ Join( "", [ "arn:", Partition, ":logs:", Region, ":", AccountId, ":log-group:/aws/codebuild/", build_name, ] + x, ) for x in [[":*"], [":*/*"]] ], ), ], ), ) ], ) ) buildproject = template.add_resource( codebuild.Project( "BuildProject", Artifacts=codebuild.Artifacts(Type="CODEPIPELINE"), Environment=codebuild.Environment( ComputeType="BUILD_GENERAL1_SMALL", EnvironmentVariables=[ codebuild.EnvironmentVariable( Name="AWS_DEFAULT_REGION", Type="PLAINTEXT", Value=Region ), codebuild.EnvironmentVariable( Name="AWS_ACCOUNT_ID", Type="PLAINTEXT", Value=AccountId ), codebuild.EnvironmentVariable( Name="IMAGE_REPO_NAME", Type="PLAINTEXT", Value=variables["EcrRepoName"].ref, ), ], Image="aws/codebuild/docker:18.09.0", Type="LINUX_CONTAINER", ), Name=build_name, ServiceRole=build_role.get_att("Arn"), Source=codebuild.Source( Type="CODEPIPELINE", BuildSpec=variables["BuildProjectBuildSpec"] ), ) ) pipelinerole = template.add_resource( iam.Role( "PipelineRole", AssumeRolePolicyDocument=make_simple_assume_policy( "codepipeline.amazonaws.com" ), PermissionsBoundary=boundary_arn, Policies=[ iam.Policy( PolicyName=Join("", [build_name, "-pipeline-policy"]), PolicyDocument=PolicyDocument( Version="2012-10-17", Statement=[ Statement( Action=[ awacs.codecommit.GetBranch, awacs.codecommit.GetCommit, awacs.codecommit.UploadArchive, awacs.codecommit.GetUploadArchiveStatus, # noqa awacs.codecommit.CancelUploadArchive, ], # noqa Effect=Allow, Resource=[appsource.get_att("Arn")], ), Statement( Action=[awacs.s3.GetBucketVersioning], Effect=Allow, Resource=[bucket.get_att("Arn")], ), Statement( Action=[awacs.s3.GetObject, awacs.s3.PutObject], Effect=Allow, Resource=[Join("", [bucket.get_att("Arn"), "/*"])], ), Statement( Action=[ awacs.codebuild.BatchGetBuilds, awacs.codebuild.StartBuild, ], Effect=Allow, Resource=[buildproject.get_att("Arn")], ), ], ), ) ], ) ) template.add_resource( codepipeline.Pipeline( "Pipeline", ArtifactStore=codepipeline.ArtifactStore( Location=bucket.ref(), Type="S3" ), Name=build_name, RoleArn=pipelinerole.get_att("Arn"), Stages=[ codepipeline.Stages( Name="Source", Actions=[ codepipeline.Actions( Name="CodeCommit", ActionTypeId=codepipeline.ActionTypeId( Category="Source", Owner="AWS", Provider="CodeCommit", Version="1", ), Configuration={ "RepositoryName": appsource.get_att("Name"), # noqa "BranchName": "master", }, OutputArtifacts=[ codepipeline.OutputArtifacts(Name="CodeCommitRepo") ], ), ], ), codepipeline.Stages( Name="Build", Actions=[ codepipeline.Actions( Name="Build", ActionTypeId=codepipeline.ActionTypeId( Category="Build", Owner="AWS", Provider="CodeBuild", Version="1", ), Configuration={"ProjectName": buildproject.ref()}, InputArtifacts=[ codepipeline.InputArtifacts(Name="CodeCommitRepo") ], ) ], ), ], ) )
Email=MEMBER_ACCOUNT_EMAIL, DetectorId=Ref(detector))) snstopic = t.add_resource( sns.Topic( "SNSTopic", Condition="IsMaster", Subscription=[ # put any subscriptions here ])) event = t.add_resource( events.Rule("EventsRule", Condition="IsMaster", EventPattern={"source": ["aws.guardduty"]}, State="ENABLED", Targets=[events.Target( Arn=Ref(snstopic), Id="sns", )])) # Allow events to send notifications to SNS t.add_resource( sns.TopicPolicy( "SNSTopicPolicy", Condition="IsMaster", PolicyDocument=aws.Policy(Statement=[ aws.Statement( Effect=aws.Allow, Action=[ aws.Action("sns", "Publish"), ],
Ref(databases_to_use_parameter)))) # Permission for SNS to trigger the Lambda template.add_resource( awslambda.Permission("SNSPermissionForLambda", Action="lambda:invokeFunction", FunctionName=Ref(backup_rds_function), Principal="sns.amazonaws.com", SourceArn=Ref(rds_topic))) schedule_event = template.add_resource( events.Rule("AuroraBackupEvent", Condition="IncludeAurora", Description="Copy Aurora clusters to another region", ScheduleExpression="rate(1 day)", State="ENABLED", Targets=[ events.Target(Arn=GetAtt(backup_rds_function, "Arn"), Id="backup_rds_function") ])) # Permission for CloudWatch Events to trigger the Lambda template.add_resource( awslambda.Permission("EventsPermissionForLambda", Condition="IncludeAurora", Action="lambda:invokeFunction", FunctionName=Ref(backup_rds_function), Principal="events.amazonaws.com", SourceArn=GetAtt(schedule_event, "Arn"))) print(template.to_json())
role=lambda_exe_role, lambda_params={ "Environment": awslambda.Environment( Variables={ 'PREVIOUS_TIME_SSM_PARAM_NAME': Ref(ssm_previous_time), 'SCHEDULER_LAMBDA_NAME': Ref(hyp3_scheduler.scheduler) }), "MemorySize": 128, "Timeout": 300 })) find_new_target = events.Target("FindNewTarget", Arn=GetAtt(find_new_granules, 'Arn'), Id="FindNewFunction1") find_new_event_rule = t.add_resource( events.Rule("FindNewGranulesSchedule", ScheduleExpression="rate(1 minute)", State="ENABLED", Targets=[find_new_target])) PermissionForEventsToInvokeLambda = t.add_resource( awslambda.Permission("EventSchedulePermissions", FunctionName=Ref(find_new_granules), Action="lambda:InvokeFunction", Principal="events.amazonaws.com", SourceArn=GetAtt("FindNewGranulesSchedule", "Arn")))
def ssm_ansible(): template = Template() stackname = Ref("AWS::StackName") template.add_parameter(Parameter( "LambdaZipBucket", Type="String", Description="Bucket which has Lambda Zip file", Default="lambda-zip-bucket", ConstraintDescription="Must be an existing bucket.'" )) ansible_bucket = s3.Bucket( 'AnsibleBucket', BucketName=Join("", [stackname, "-code-bucket"]), BucketEncryption=s3.BucketEncryption( 'AnsibleCodeBucketEncryption', ServerSideEncryptionConfiguration=[ s3.ServerSideEncryptionRule( ServerSideEncryptionByDefault=s3.ServerSideEncryptionByDefault( 'Default', SSEAlgorithm='AES256' ) ) ] ) ) ansible_lambda_role = iam.Role( 'AnsibleLambdaRole', RoleName=Join("", [stackname, "-AnsibleLambdaSSM"]), Policies=[ Policy( PolicyName="AnsibleLambdaSSM", PolicyDocument=PolicyDocument( Statement=[ Statement( Effect=Allow, Action=[ Action("ssm", "*"), Action("ec2", "DescribeInstances") ], Resource=[ "*" ] ), Statement( Effect=Allow, Action=[ Action("logs", "CreateLogGroup"), Action("logs", "CreateLogStream"), Action("logs", "PutLogEvents") ], Resource=[ "arn:aws:logs:*:*:*" ] ) ] ) ) ], AssumeRolePolicyDocument=PolicyDocument( Statement=[ Statement( Effect=Allow, Action=[ Action("sts", "AssumeRole") ], Principal=Principal("Service", "lambda.amazonaws.com") ) ] ) ) ansible_lambda = awslambda.Function( 'AnsibleLambda', FunctionName=Join("", [stackname, "-ansible-ssm"]), Handler="lambda_function.lambda_handler", Runtime="python3.7", Role=GetAtt(ansible_lambda_role, "Arn"), Code=Code( S3Key="ansible_ssm_lambda.zip", S3Bucket=Ref("LambdaZipBucket") ), Environment=Environment( Variables={ 'code_bucket': Ref(ansible_bucket), 'provision_playbook': "provision-playbook.yml", 'update_playbook': "update-playbook.yml" } ) ) cloudwatch_event_rule_trigger_lambda = events.Rule( 'CloudWatchEventRuleLambda', Description="Capture when instance stat changes to 'running' or 'terminated'.", EventPattern={ "source": [ "aws.ec2" ], "detail-type": [ "EC2 Instance State-change Notification" ], "detail": { "state": [ "running", "terminated" ] } }, Name=Join("", [stackname, "-instance-state"]), Targets=[ events.Target( 'TriggerTarget', Arn=GetAtt(ansible_lambda, "Arn"), Id="TriggerTarget" ) ] ) cloudwatch_lambda_permission = awslambda.Permission( 'CloudWatchLambdaPermission', Action="lambda:InvokeFunction", FunctionName=Ref(ansible_lambda), Principal="events.amazonaws.com", SourceArn=GetAtt(cloudwatch_event_rule_trigger_lambda, "Arn") ) template.add_resource(ansible_bucket) template.add_resource(ansible_lambda_role) template.add_resource(ansible_lambda) template.add_resource(cloudwatch_event_rule_trigger_lambda) template.add_resource(cloudwatch_lambda_permission) with open(os.path.dirname(os.path.realpath(__file__)) + '/ssm_ansible.yml', 'w') as cf_file: cf_file.write(template.to_yaml()) return template.to_yaml()
Description="Maintains EBS snapshots of tagged instances", Code=awslambda.Code( S3Bucket=Ref(s3_bucket_parameter), S3Key=Ref(source_zip_parameter), ), Handler="ebs-snapshots.lambda_handler", MemorySize=128, Role=GetAtt(lambda_role, "Arn"), Runtime="python3.6", Timeout=30)) schedule_event = template.add_resource( events.Rule("LambdaTriggerRule", Description="Trigger EBS snapshot Lambda", ScheduleExpression="rate(1 day)", State="ENABLED", Targets=[ events.Target(Arn=GetAtt(lambda_function, "Arn"), Id="ebs-snapshot-lambda") ])) # Permission for CloudWatch Events to trigger the Lambda template.add_resource( awslambda.Permission("EventsPermissionForLambda", Action="lambda:invokeFunction", FunctionName=Ref(lambda_function), Principal="events.amazonaws.com", SourceArn=GetAtt(schedule_event, "Arn"))) print(template.to_json())
#!/usr/bin/env python from troposphere import Template, Output, GetAtt, Parameter, Ref, events, awslambda t = Template() lambda_arn = t.add_parameter( Parameter('LambdaArn', Type='String', Description='Lambda Arn')) rule = t.add_resource( events.Rule("ReDSRule", Targets=[events.Target(Arn=Ref(lambda_arn), Id="ReDS")], ScheduleExpression="rate(5 minutes)")) permission = t.add_resource( awslambda.Permission("ReDSPerm", FunctionName=Ref(lambda_arn), Action="lambda:InvokeFunction", Principal="events.amazonaws.com", SourceArn=GetAtt(rule, "Arn"))) t.add_output([ Output( 'EventRule', Description='ReDS Event Rule', Value=Ref(rule), ), Output( 'EventPermission', Description='ReDS Lambda Permission', Value=Ref(permission),
) # Create the Event Rule cw_event_rule = t.add_resource(events.Rule( "CodeCommitRule", EventPattern={ "source": [ "aws.codecommit" ], "detail": { "referenceType": [ "branch" ], "referenceName": [ "master" ] }, "detail-type": [ "CodeCommit Repository State Change" ], "resources": [ Join("", ["arn:aws:codecommit:", Ref('AWS::Region'), ":", Ref('AWS::AccountId'), ":", Ref(CodeCommitRepo)]), ] }, Description="CodeCommit State Change CloudWatch Event", State="ENABLED", Targets=[codecommit_event_target] )) print(t.to_json())
"data_url": data_url, "portal_url": portal_url, "portal_user": portal_user, "portal_password": portal_password, "portal_item": id, "file": file, "format": frmt }))) # create an EventBridge rule to kick off the lambda arcgis_rule = template.add_resource( events.Rule(rule_name, ScheduleExpression=cron, Description="My Lambda CloudWatch Event", State="ENABLED", Targets=[ events.Target("MyLambdaTarget", Arn=GetAtt(arcgis_lambda.title, "Arn"), Id="MyLambdaId") ])) # add permissions to the lambda to allow EventBridge to kick it off arcgis_permission = template.add_resource( awslambda.Permission( perm_name, FunctionName=GetAtt(arcgis_lambda.title, 'Arn'), Action='lambda:InvokeFunction', Principal='events.amazonaws.com', SourceArn=GetAtt(arcgis_rule.title, 'Arn'), ))
def create_template(self): """Create template (main function called by Stacker).""" template = self.template variables = self.get_variables() template.set_version('2010-09-09') template.set_description('App - Build Pipeline') # Resources boundary_arn = Join('', [ 'arn:', Partition, ':iam::', AccountId, ':policy/', variables['RolePermissionsBoundaryName'].ref ]) # Repo image limit is 1000 by default; this lambda function will prune # old images image_param_path = Join( '', ['/', variables['AppPrefix'].ref, '/current-hash']) image_param_arn = Join('', [ 'arn:', Partition, ':ssm:', Region, ':', AccountId, ':parameter', image_param_path ]) ecr_repo_arn = Join('', [ 'arn:', Partition, ':ecr:', Region, ':', AccountId, ':repository/', variables['EcrRepoName'].ref ]) cleanuplambdarole = template.add_resource( iam.Role('CleanupLambdaRole', AssumeRolePolicyDocument=make_simple_assume_policy( 'lambda.amazonaws.com'), ManagedPolicyArns=[ IAM_ARN_PREFIX + 'AWSLambdaBasicExecutionRole' ], PermissionsBoundary=boundary_arn, Policies=[ iam.Policy( PolicyName=Join( '', [variables['AppPrefix'].ref, '-ecrcleanup']), PolicyDocument=PolicyDocument( Version='2012-10-17', Statement=[ Statement(Action=[awacs.ssm.GetParameter], Effect=Allow, Resource=[image_param_arn]), Statement(Action=[ awacs.ecr.DescribeImages, awacs.ecr.BatchDeleteImage ], Effect=Allow, Resource=[ecr_repo_arn]) ])) ])) cleanupfunction = template.add_resource( awslambda.Function( 'CleanupFunction', Description='Cleanup stale ECR images', Code=awslambda.Code( ZipFile=variables['ECRCleanupLambdaFunction']), Environment=awslambda.Environment( Variables={ 'ECR_REPO_NAME': variables['EcrRepoName'].ref, 'SSM_PARAM': image_param_path }), Handler='index.handler', Role=cleanuplambdarole.get_att('Arn'), Runtime='python3.6', Timeout=120)) cleanuprule = template.add_resource( events.Rule('CleanupRule', Description='Regularly invoke CleanupFunction', ScheduleExpression='rate(7 days)', State='ENABLED', Targets=[ events.Target(Arn=cleanupfunction.get_att('Arn'), Id='CleanupFunction') ])) template.add_resource( awslambda.Permission( 'AllowCWLambdaInvocation', FunctionName=cleanupfunction.ref(), Action=awacs.awslambda.InvokeFunction.JSONrepr(), Principal='events.amazonaws.com', SourceArn=cleanuprule.get_att('Arn'))) appsource = template.add_resource( codecommit.Repository( 'AppSource', RepositoryName=Join('-', [variables['AppPrefix'].ref, 'source']))) for i in ['Name', 'Arn']: template.add_output( Output("AppRepo%s" % i, Description="%s of app source repo" % i, Value=appsource.get_att(i))) bucket = template.add_resource( s3.Bucket( 'Bucket', AccessControl=s3.Private, LifecycleConfiguration=s3.LifecycleConfiguration(Rules=[ s3.LifecycleRule(NoncurrentVersionExpirationInDays=90, Status='Enabled') ]), VersioningConfiguration=s3.VersioningConfiguration( Status='Enabled'))) template.add_output( Output('PipelineBucketName', Description='Name of pipeline bucket', Value=bucket.ref())) # This list must be kept in sync between the CodeBuild project and its # role build_name = Join('', [variables['AppPrefix'].ref, '-build']) build_role = template.add_resource( iam.Role( 'BuildRole', AssumeRolePolicyDocument=make_simple_assume_policy( 'codebuild.amazonaws.com'), PermissionsBoundary=boundary_arn, Policies=[ iam.Policy( PolicyName=Join('', [build_name, '-policy']), PolicyDocument=PolicyDocument( Version='2012-10-17', Statement=[ Statement( Action=[awacs.s3.GetObject], Effect=Allow, Resource=[ Join('', [bucket.get_att('Arn'), '/*']) ]), Statement( Action=[awacs.ecr.GetAuthorizationToken], Effect=Allow, Resource=['*']), Statement(Action=[ awacs.ecr.BatchCheckLayerAvailability, awacs.ecr.BatchGetImage, awacs.ecr.CompleteLayerUpload, awacs.ecr.DescribeImages, awacs.ecr.GetDownloadUrlForLayer, awacs.ecr.InitiateLayerUpload, awacs.ecr.PutImage, awacs.ecr.UploadLayerPart ], Effect=Allow, Resource=[ecr_repo_arn]), Statement(Action=[ awacs.ssm.GetParameter, awacs.ssm.PutParameter ], Effect=Allow, Resource=[image_param_arn]), Statement(Action=[ awacs.logs.CreateLogGroup, awacs.logs.CreateLogStream, awacs.logs.PutLogEvents ], Effect=Allow, Resource=[ Join('', [ 'arn:', Partition, ':logs:', Region, ':', AccountId, ':log-group:/aws/codebuild/', build_name ] + x) for x in [[':*'], [':*/*']] ]) ])) ])) buildproject = template.add_resource( codebuild.Project( 'BuildProject', Artifacts=codebuild.Artifacts(Type='CODEPIPELINE'), Environment=codebuild.Environment( ComputeType='BUILD_GENERAL1_SMALL', EnvironmentVariables=[ codebuild.EnvironmentVariable( Name='AWS_DEFAULT_REGION', Type='PLAINTEXT', Value=Region), codebuild.EnvironmentVariable(Name='AWS_ACCOUNT_ID', Type='PLAINTEXT', Value=AccountId), codebuild.EnvironmentVariable( Name='IMAGE_REPO_NAME', Type='PLAINTEXT', Value=variables['EcrRepoName'].ref), ], Image='aws/codebuild/docker:18.09.0', Type='LINUX_CONTAINER'), Name=build_name, ServiceRole=build_role.get_att('Arn'), Source=codebuild.Source( Type='CODEPIPELINE', BuildSpec=variables['BuildProjectBuildSpec']))) pipelinerole = template.add_resource( iam.Role( 'PipelineRole', AssumeRolePolicyDocument=make_simple_assume_policy( 'codepipeline.amazonaws.com'), PermissionsBoundary=boundary_arn, Policies=[ iam.Policy( PolicyName=Join('', [build_name, '-pipeline-policy']), PolicyDocument=PolicyDocument( Version='2012-10-17', Statement=[ Statement( Action=[ awacs.codecommit.GetBranch, awacs.codecommit.GetCommit, awacs.codecommit.UploadArchive, awacs.codecommit. GetUploadArchiveStatus, # noqa awacs.codecommit.CancelUploadArchive ], # noqa Effect=Allow, Resource=[appsource.get_att('Arn')]), Statement( Action=[awacs.s3.GetBucketVersioning], Effect=Allow, Resource=[bucket.get_att('Arn')]), Statement( Action=[ awacs.s3.GetObject, awacs.s3.PutObject ], Effect=Allow, Resource=[ Join('', [bucket.get_att('Arn'), '/*']) ]), Statement( Action=[ awacs.codebuild.BatchGetBuilds, awacs.codebuild.StartBuild ], Effect=Allow, Resource=[buildproject.get_att('Arn')]) ])) ])) template.add_resource( codepipeline.Pipeline( 'Pipeline', ArtifactStore=codepipeline.ArtifactStore(Location=bucket.ref(), Type='S3'), Name=build_name, RoleArn=pipelinerole.get_att('Arn'), Stages=[ codepipeline.Stages( Name='Source', Actions=[ codepipeline.Actions( Name='CodeCommit', ActionTypeId=codepipeline.ActionTypeId( Category='Source', Owner='AWS', Provider='CodeCommit', Version='1'), Configuration={ 'RepositoryName': appsource.get_att('Name'), # noqa 'BranchName': 'master' }, OutputArtifacts=[ codepipeline.OutputArtifacts( Name='CodeCommitRepo') ]), ]), codepipeline.Stages( Name='Build', Actions=[ codepipeline.Actions( Name='Build', ActionTypeId=codepipeline.ActionTypeId( Category='Build', Owner='AWS', Provider='CodeBuild', Version='1'), Configuration={ 'ProjectName': buildproject.ref() }, InputArtifacts=[ codepipeline.InputArtifacts( Name='CodeCommitRepo') ]) ]) ]))