def template(**kwargs): """ Args: Returns: template Template() """ template = Template() release = template.add_parameter( Parameter('ReleaseNewAlias', Type="String", AllowedValues=['Yes', 'No'], Default='No')) release_condition = template.add_condition( 'ReleaseAlias', {'ReleaseAlias': Equals(Ref(release), 'Yes')}) function = template.add_resource(lambda_function(**kwargs)) version = template.add_resource( Version('LambdaVersion', FunctionName=GetAtt(function, 'Arn'))) alias = template.add_resource( Alias('LambdaAlias', Name='prod', DependsOn=[release_condition], Description=Sub(f'Alias to version ${{{version.title}.Arn}}'), FunctionName=Ref(function), FunctionVersion=Ref(version))) template.add_output(object_outputs(function, True)) template.add_output(object_outputs(version, True)) return template
def template(make_public=False, **kwargs): required_params = ['Runtimes', 'Bucket', 'Key'] check_params_exist(required_params, kwargs) template = Template() layer_name = template.add_parameter( Parameter('LayerName', Type="String", AllowedPattern="[a-zA-Z0-9-]*")) template.set_description('Default template for Lambda Layer version') template.set_transform('AWS::Serverless-2016-10-31') version = template.add_resource( LayerVersion(f'LayerVersion{DATE}', DeletionPolicy='Retain', CompatibleRuntimes=kwargs['Runtimes'], Description=Sub(f'Layer ${{{layer_name.title}}}'), LayerName=Ref(layer_name), Content=Content(S3Bucket=kwargs['Bucket'], S3Key=kwargs['Key']))) if make_public: PERM = template.add_resource( LayerVersionPermission(f'LambdaVersionPermission{DATE}', DeletionPolicy='Retain', Principal='*', LayerVersionArn=Ref(version), Action='lambda:GetLayerVersion')) template.add_output(object_outputs(version, export=True)) return template
def template(**kwargs): """ """ template_required_params = [ 'BucketName', 'Source', 'LayerBuildProjects', 'LayersMergeProject', 'LayerName', 'GeneratorFunctionName', 'CloudformationRoleArn' ] check_params_exist(template_required_params, kwargs) template = Template() token = template.add_parameter( Parameter('GitHubOAuthToken', Type="String", NoEcho=True)) role = pipelinerole_build(UseCodeCommit=True, UseCodeBuild=True, UseLambda=True, UseCloudformation=True, Bucket=kwargs['BucketName']) if kwargs['Source']['Provider'].lower() == 'github': kwargs['Source']['Config']['OAuthToken'] = Ref(token) source = SourceAction(name='SourceCode', provider=kwargs['Source']['Provider'], config=kwargs['Source']['Config']) build_actions = [] builds_projects = kwargs['LayerBuildProjects'] for project in builds_projects: build_actions.append(BuildAction(project, source.outputs, project)) build_outputs = [] for action in build_actions: build_outputs += action.outputs merge_action = BuildAction('MergeAction', build_outputs, kwargs['LayersMergeProject']) invoke = InvokeAction('GenerateTemplateForCfn', merge_action.outputs, function_name=kwargs['GeneratorFunctionName']) input_name = invoke.outputs[0].Name deploy = DeployAction('DeployToCfn', invoke.outputs, 'CloudFormation', StackName=f'layer-{kwargs["LayerName"]}', RoleArn=kwargs['CloudformationRoleArn'], TemplatePath=f'{input_name}::tmp/template.json') stages = [ ('Source', [source]), ('BuildLayers', build_actions), ('MergeLayers', [merge_action]), ('GenerateCfnTemplate', [invoke]), ('DeployWithCfn', [deploy]), ] pipeline = CodePipeline('Pipeline', GetAtt(role, 'Arn'), kwargs['BucketName'], stages) template.add_resource(role) template.add_resource(pipeline) template.add_output(object_outputs(pipeline, True)) return template
def generate_vpc_template(layers, az_count, cidr_block): TPL = Template() TPL.set_description('VPC - Version 2019-06-05') TPL.set_metadata({'Author': 'https://github.com/johnpreston'}) VPC = VPCType('VPC', CidrBlock=cidr_block, EnableDnsHostnames=True, EnableDnsSupport=True, Tags=Tags(Name=Ref('AWS::StackName'), EnvironmentName=Ref('AWS::StackName'))) IGW = InternetGateway("InternetGateway") IGW_ATTACH = VPCGatewayAttachment("VPCGatewayAttachement", InternetGatewayId=Ref(IGW), VpcId=Ref(VPC)) DHCP_OPTIONS = DHCPOptions('VpcDhcpOptions', DomainName=Sub(f'${{AWS::StackName}}.local'), DomainNameServers=['AmazonProvidedDNS'], Tags=Tags(Name=Sub(f'DHCP-${{{VPC.title}}}'))) DHCP_ATTACH = VPCDHCPOptionsAssociation('VpcDhcpOptionsAssociate', DhcpOptionsId=Ref(DHCP_OPTIONS), VpcId=Ref(VPC)) DNS_HOSTED_ZONE = HostedZone( 'VpcHostedZone', VPCs=[HostedZoneVPCs(VPCId=Ref(VPC), VPCRegion=Ref('AWS::Region'))], Name=Sub(f'${{AWS::StackName}}.local'), HostedZoneTags=Tags(Name=Sub(f'ZoneFor-${{{VPC.title}}}'))) TPL.add_resource(VPC) TPL.add_resource(IGW) TPL.add_resource(IGW_ATTACH) TPL.add_resource(DHCP_OPTIONS) TPL.add_resource(DHCP_ATTACH) TPL.add_resource(DNS_HOSTED_ZONE) STORAGE_RTB = TPL.add_resource( RouteTable('StorageRtb', VpcId=Ref(VPC), Tags=Tags(Name='StorageRtb'))) STORAGE_SUBNETS = [] for count, subnet_cidr in zip(az_count, layers['stor']): subnet = Subnet( f'StorageSubnet{alpha[count].upper()}', CidrBlock=subnet_cidr, VpcId=Ref(VPC), AvailabilityZone=Sub(f'${{AWS::Region}}{alpha[count]}'), Tags=Tags(Name=Sub(f'${{AWS::StackName}}-Storage-{alpha[count]}'), Usage="Storage")) subnet_assoc = TPL.add_resource( SubnetRouteTableAssociation( f'StorageSubnetAssoc{alpha[count].upper()}', SubnetId=Ref(subnet), RouteTableId=Ref(STORAGE_RTB))) STORAGE_SUBNETS.append(subnet) TPL.add_resource(subnet) PUBLIC_RTB = TPL.add_resource( RouteTable('PublicRtb', VpcId=Ref(VPC), Tags=Tags(Name='PublicRtb'))) PUBLIC_ROUTE = TPL.add_resource( Route('PublicDefaultRoute', GatewayId=Ref(IGW), RouteTableId=Ref(PUBLIC_RTB), DestinationCidrBlock='0.0.0.0/0')) PUBLIC_SUBNETS = [] NAT_GATEWAYS = [] for count, subnet_cidr in zip(az_count, layers['pub']): subnet = Subnet( f'PublicSubnet{alpha[count].upper()}', CidrBlock=subnet_cidr, VpcId=Ref(VPC), AvailabilityZone=Sub(f'${{AWS::Region}}{alpha[count]}'), MapPublicIpOnLaunch=True, Tags=Tags(Name=Sub(f'${{AWS::StackName}}-Public-{alpha[count]}'))) eip = TPL.add_resource( EIP(f"NatGatewayEip{alpha[count].upper()}", Domain='vpc')) nat = NatGateway(f"NatGatewayAz{alpha[count].upper()}", AllocationId=GetAtt(eip, 'AllocationId'), SubnetId=Ref(subnet)) subnet_assoc = TPL.add_resource( SubnetRouteTableAssociation( f'PublicSubnetsRtbAssoc{alpha[count].upper()}', RouteTableId=Ref(PUBLIC_RTB), SubnetId=Ref(subnet))) NAT_GATEWAYS.append(nat) PUBLIC_SUBNETS.append(subnet) TPL.add_resource(nat) TPL.add_resource(subnet) APP_SUBNETS = [] APP_RTBS = [] for count, subnet_cidr, nat in zip(az_count, layers['app'], NAT_GATEWAYS): SUFFIX = alpha[count].upper() subnet = Subnet( f'AppSubnet{SUFFIX}', CidrBlock=subnet_cidr, VpcId=Ref(VPC), AvailabilityZone=Sub(f'${{AWS::Region}}{alpha[count]}'), Tags=Tags(Name=Sub(f'${{AWS::StackName}}-App-{alpha[count]}'))) APP_SUBNETS.append(subnet) rtb = RouteTable(f'AppRtb{alpha[count].upper()}', VpcId=Ref(VPC), Tags=Tags(Name=f'AppRtb{alpha[count].upper()}')) APP_RTBS.append(rtb) route = Route(f'AppRoute{alpha[count].upper()}', NatGatewayId=Ref(nat), RouteTableId=Ref(rtb), DestinationCidrBlock='0.0.0.0/0') subnet_assoc = SubnetRouteTableAssociation( f'SubnetRtbAssoc{alpha[count].upper()}', RouteTableId=Ref(rtb), SubnetId=Ref(subnet)) TPL.add_resource(subnet) TPL.add_resource(rtb) TPL.add_resource(route) TPL.add_resource(subnet_assoc) APP_S3_ENDPOINT = VPCEndpoint( 'AppS3Endpoint', VpcId=Ref(VPC), RouteTableIds=[Ref(rtb) for rtb in APP_RTBS], ServiceName=Sub('com.amazonaws.${AWS::Region}.s3'), VpcEndpointType='Gateway', ) PUBLIC_S3_ENDPOINT = VPCEndpoint( 'PublicS3Endpoint', VpcId=Ref(VPC), RouteTableIds=[Ref(PUBLIC_RTB)], ServiceName=Sub('com.amazonaws.${AWS::Region}.s3'), VpcEndpointType='Gateway', ) STORAGE_S3_ENDPOINT = VPCEndpoint( 'StorageS3Endpoint', VpcId=Ref(VPC), RouteTableIds=[Ref(STORAGE_RTB)], ServiceName=Sub('com.amazonaws.${AWS::Region}.s3'), VpcEndpointType='Gateway') RESOURCES = [] for count in az_count: resource = TPL.add_resource(EIP(f'Eip{count}', Domain='vpc')) RESOURCES.append(resource) TPL.add_resource(APP_S3_ENDPOINT) TPL.add_resource(PUBLIC_S3_ENDPOINT) TPL.add_resource(STORAGE_S3_ENDPOINT) SG_RULES = [] for subnet in layers['app']: RULE = SecurityGroupRule( IpProtocol="tcp", FromPort="443", ToPort="443", CidrIp=subnet, ) SG_RULES.append(RULE) ENDPOINT_SG = TPL.add_resource( SecurityGroup( 'VpcEndpointSecurityGroup', VpcId=Ref(VPC), GroupDescription='SG for all Interface VPC Endpoints', SecurityGroupIngress=SG_RULES, Tags=Tags(Name="sg-endpoints"), )) APP_SNS_ENDPOINT = VPCEndpoint( 'AppSNSEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.sns'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SNS_ENDPOINT) APP_SQS_ENDPOINT = VPCEndpoint( 'AppSQSEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.sqs'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SQS_ENDPOINT) APP_ECR_API_ENDPOINT = VPCEndpoint( 'AppECRAPIEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ecr.api'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_ECR_API_ENDPOINT) APP_ECR_DKR_ENDPOINT = VPCEndpoint( 'AppECRDKREndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ecr.dkr'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_ECR_DKR_ENDPOINT) APP_SECRETS_MANAGER_ENDPOINT = VPCEndpoint( 'AppSecretsManagerEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.secretsmanager'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SECRETS_MANAGER_ENDPOINT) APP_SSM_ENDPOINT = VPCEndpoint( 'AppSSMEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ssm'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SSM_ENDPOINT) APP_SSM_MESSAGES_ENDPOINT = VPCEndpoint( 'AppSSMMessagesEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ssmmessages'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SSM_MESSAGES_ENDPOINT) ################################################################################ # # OUTPUTS # TPL.add_output(object_outputs(VPC, name_is_id=True)) TPL.add_output(object_outputs(APP_SQS_ENDPOINT, name_is_id=True)) TPL.add_output(object_outputs(APP_SNS_ENDPOINT, name_is_id=True)) TPL.add_output( comments_outputs([{ 'EIP': Join(',', [GetAtt(resource, "AllocationId") for resource in RESOURCES]) }, { 'PublicSubnets': Join(',', [Ref(subnet) for subnet in PUBLIC_SUBNETS]) }, { 'StorageSubnets': Join(',', [Ref(subnet) for subnet in STORAGE_SUBNETS]) }, { 'ApplicationSubnets': Join(',', [Ref(subnet) for subnet in APP_SUBNETS]) }, { 'StackName': Ref('AWS::StackName') }, { 'VpcZoneId': Ref(DNS_HOSTED_ZONE) }])) return TPL
RUNTIME_VERSIONS = Parameter("BuildRuntimeVersion", Type="String", AllowedValues=MAPPINGS_PARAMS[3]) TEMPLATE.add_parameter(RUNTIME_LANGUAGE) TEMPLATE.add_parameter(RUNTIME_VERSIONS) TEMPLATE.add_mapping('Languages', MAPPINGS_PARAMS[1]) BUCKET = TEMPLATE.add_parameter( Parameter('PipelineBucket', Type="String", AllowedPattern="[a-z0-9-]+")) ROLE = role_build(Sub(f'arn:aws:s3:::${{{BUCKET.title}}}/*')) PROJECT = get_build_project( ROLE, RUNTIME_LANGUAGE.title, RUNTIME_VERSIONS.title, **{ 'Tags': { '10-technical:team': 'PlatformEngineering', '10-technical:runtime_language': Ref(RUNTIME_LANGUAGE), '10-technical:runtime_version': Ref(RUNTIME_VERSIONS) }, 'SourceType': "CODEPIPELINE", 'BuildSpec': "version: 0.2\nphases:\n install:\n commands:\n rsync --version || apt-get update && apt-get install rsync\n build:\n commands:\n - export HOME=$PWD\n - cd ..\n - echo $PWD\n - ls -lR\n - mkdir -p $HOME/build\n - rsync -av 00/python $HOME/build/\n - rsync -av 01/python $HOME/build/\nartifacts:\n files:\n - '**/*'\n base-directory: build\n" }) TEMPLATE.add_resource(ROLE) TEMPLATE.add_resource(PROJECT) TEMPLATE.add_output( object_outputs(PROJECT, True, RunTimeLanguage=RUNTIME_LANGUAGE, RunTimeVersions=RUNTIME_VERSIONS)) print(TEMPLATE.to_yaml())