AWSTemplateFormatVersion: "2010-09-09" Description: Infrastructure for the registry extensions CICD pipeline Parameters: Env: Type: String Description: The environment, alpha, beta, or prod. In a sandbox these are all in one account, but the actual deployment is to three different accounts. AllowedValues: ["alpha", "beta", "prod"] PrefixLower: Type: String Description: The extension prefix lowercase, for example, awscommunity. BetaAccountId: Type: String Description: AccountId for the beta account, which pushes builds to the prod source bucket ProdAccountId: Type: String Description: Account ID for prod, required to share the KMS key so beta can deploy builds to the prod source bucket NotificationEmail: Type: String Description: Email address for pipeline notifications Conditions: IsBeta: !Equals - !Ref Env - beta IsProd: !Equals - !Ref Env - prod Resources: ArtifactBucket: Type: AWS::S3::Bucket Metadata: Comment: CodePipeline artifacts Properties: BucketName: !Sub "cep-${PrefixLower}-${Env}-${AWS::AccountId}-artifacts" ArtifactBucketPolicy: Type: AWS::S3::BucketPolicy Condition: IsBeta Metadata: Comment: Allows the beta account to use an assumed role in the prod account to drop builds into the prod account Properties: Bucket: !Ref ArtifactBucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: BetaProdCrossAccount Effect: Allow Principal: AWS: - !Sub "arn:aws:iam::${ProdAccountId}:root" Action: - s3:Put* - s3:Get* - s3:List* Resource: - !Sub "arn:aws:s3:::cep-${PrefixLower}-${Env}-${AWS::AccountId}-artifacts" - !Sub "arn:aws:s3:::cep-${PrefixLower}-${Env}-${AWS::AccountId}-artifacts/*" FastlyParameterPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Statement: - Action: - secretsmanager:GetSecretValue Effect: Allow Resource: - !Sub "arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:cep-${PrefixLower}-*" - Action: - ssm:GetParameter - ssm:GetParameters Effect: Allow Resource: - !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/cep-${PrefixLower}-*" Version: '2012-10-17' FastlyServicesDomainBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyServicesBackendBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyServicesHealthcheckBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyServicesServiceBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyDictionaryDictionaryBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyDictionaryDictionaryItemBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyLoggingS3BuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyLoggingSplunkBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyServicesDomainBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-services-domain" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" - Name: FASTLY_SERVICE_ID Type: PARAMETER_STORE Value: "cep-fastly-service-id" - Name: FASTLY_VERSION_ID Type: PARAMETER_STORE Value: "cep-fastly-version-id" ServiceRole: !GetAtt FastlyServicesDomainBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyServicesBackendBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-services-backend" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" - Name: FASTLY_SERVICE_ID Type: PARAMETER_STORE Value: "cep-fastly-service-id" - Name: FASTLY_VERSION_ID Type: PARAMETER_STORE Value: "cep-fastly-version-id" ServiceRole: !GetAtt FastlyServicesBackendBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyServicesHealthcheckBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-services-healthcheck" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" - Name: FASTLY_SERVICE_ID Type: PARAMETER_STORE Value: "cep-fastly-service-id" - Name: FASTLY_VERSION_ID Type: PARAMETER_STORE Value: "cep-fastly-version-id" ServiceRole: !GetAtt FastlyServicesHealthcheckBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyServicesServiceBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-services-service" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" ServiceRole: !GetAtt FastlyServicesServiceBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyDictionaryDictionaryBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-dictionary-dictionary" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" - Name: FASTLY_SERVICE_ID Type: PARAMETER_STORE Value: "cep-fastly-service-id" - Name: FASTLY_VERSION_ID Type: PARAMETER_STORE Value: "cep-fastly-version-id" ServiceRole: !GetAtt FastlyDictionaryDictionaryBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyDictionaryDictionaryItemBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-dictionary-dictionaryitem" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" - Name: FASTLY_SERVICE_ID Type: PARAMETER_STORE Value: "cep-fastly-service-id" - Name: FASTLY_VERSION_ID Type: PARAMETER_STORE Value: "cep-fastly-version-id" - Name: FASTLY_DICTIONARY_ID Type: PARAMETER_STORE Value: "cep-fastly-dictionary-id" ServiceRole: !GetAtt FastlyDictionaryDictionaryItemBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyLoggingS3BuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-logging-s3" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" - Name: FASTLY_SERVICE_ID Type: PARAMETER_STORE Value: "cep-fastly-service-id" - Name: FASTLY_VERSION_ID Type: PARAMETER_STORE Value: "cep-fastly-version-id" ServiceRole: !GetAtt FastlyLoggingS3BuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyLoggingSplunkBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-logging-splunk" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "placeholder-for-path-to-resource" - Name: FASTLY_SERVICE_ID Type: PARAMETER_STORE Value: "cep-fastly-service-id" - Name: FASTLY_VERSION_ID Type: PARAMETER_STORE Value: "cep-fastly-version-id" ServiceRole: !GetAtt FastlyLoggingSplunkBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyTlsCertificateBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyTlsCertificateBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-tls-certificate" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "Fastly-Tls-Certificate" - Name: FASTLY_TLS_CERTIFICATE Type: PARAMETER_STORE Value: "cep-fastly-tls-certificate" ServiceRole: !GetAtt FastlyTlsCertificateBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyTlsDomainBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyTlsDomainBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-tls-domain" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "Fastly-Tls-Domain" - Name: FASTLY_TLS_CERT_ID Type: PARAMETER_STORE Value: "cep-fastly-tls-cert-id" - Name: FASTLY_TLS_DOMAIN_ID Type: PARAMETER_STORE Value: "cep-fastly-tls-domain-id" - Name: FASTLY_TLS_CONFIG_ID Type: PARAMETER_STORE Value: "cep-fastly-tls-config-id" ServiceRole: !GetAtt FastlyTlsDomainBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" FastlyTlsPrivateKeysBuildProjectRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::ImportValue: !Sub "cep-${Env}-common-build-project-policy" - !Ref FastlyParameterPolicy FastlyTlsPrivateKeysBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub "${PrefixLower}-${Env}-${PrefixLower}-tls-privatekeys" Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_LARGE Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/cep-cicd:latest" ImagePullCredentialsType: SERVICE_ROLE PrivilegedMode: true Type: LINUX_CONTAINER EnvironmentVariables: - Name: RESOURCE_PATH Type: PLAINTEXT Value: "Fastly-Tls-PrivateKeys" - Name: FASTLY_PRIVATE_KEY Type: PARAMETER_STORE Value: "cep-fastly-tls-privatekey" ServiceRole: !GetAtt FastlyTlsPrivateKeysBuildProjectRole.Arn Source: Type: CODEPIPELINE BuildSpec: !Sub "${Env}-buildspec.yml" SourceBucket: Type: AWS::S3::Bucket Metadata: Comment: The name is important here since it gets constructed by the webhook handler and CodeBuild job to drop the build into the correct bucket. We only use a one webhook for AwsCommunity and 3rd parties. Properties: BucketName: !Sub "cep-source-${AWS::AccountId}-${Env}-${PrefixLower}" VersioningConfiguration: Status: Enabled PipelineRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "cep-${PrefixLower}-${Env}-pipeline-role" AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codepipeline.amazonaws.com Version: '2012-10-17' Policies: - PolicyName: "inline-pipeline-policy" PolicyDocument: Statement: - Action: "sts:AssumeRole" Effect: Allow Resource: - !Sub "arn:aws:iam::${ProdAccountId}:role/${PrefixLower}-registry-extensions-publish-role" - Action: - s3:GetObject* - s3:GetBucket* - s3:List* - s3:DeleteObject* - s3:PutObject* - s3:Abort* Effect: Allow Resource: - !GetAtt ArtifactBucket.Arn - !Join - '' - - !GetAtt ArtifactBucket.Arn - /* - !GetAtt SourceBucket.Arn - !Join - '' - - !GetAtt SourceBucket.Arn - /* - Action: - codebuild:StartBuild - codebuild:BatchGetBuilds Effect: Allow Resource: - !GetAtt FastlyServicesDomainBuildProject.Arn - !GetAtt FastlyServicesBackendBuildProject.Arn - !GetAtt FastlyServicesHealthcheckBuildProject.Arn - !GetAtt FastlyServicesServiceBuildProject.Arn - !GetAtt FastlyDictionaryDictionaryBuildProject.Arn - !GetAtt FastlyDictionaryDictionaryItemBuildProject.Arn - !GetAtt FastlyLoggingS3BuildProject.Arn - !GetAtt FastlyLoggingSplunkBuildProject.Arn - !GetAtt FastlyTlsCertificateBuildProject.Arn - !GetAtt FastlyTlsDomainBuildProject.Arn - !GetAtt FastlyTlsPrivateKeysBuildProject.Arn - Action: - kms:* Effect: Allow Resource: "*" - Action: - sns:Publish Effect: Allow Resource: !Sub "arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${PrefixLower}-${Env}-pipeline-topic" PipelineKey: Type: AWS::KMS::Key Metadata: Comment: Required for cross account deployment from beta CodePipeline to the prod bucket Condition: IsBeta DeletionPolicy: Delete UpdateReplacePolicy: Delete Properties: Description: This key is used by the CEP beta build process to deploy builds to the prod bucket KeyPolicy: Statement: - Action: - kms:Create* - kms:Describe* - kms:Enable* - kms:List* - kms:Put* - kms:Update* - kms:Revoke* - kms:Disable* - kms:Get* - kms:Delete* - kms:ScheduleKeyDeletion - kms:CancelKeyDeletion - kms:GenerateDataKey - kms:TagResource - kms:UntagResource Effect: Allow Principal: AWS: - !Sub "arn:aws:iam::${ProdAccountId}:root" - !Sub "arn:aws:iam::${AWS::AccountId}:role/Admin" Resource: "*" - Action: - kms:Encrypt - kms:Decrypt - kms:ReEncrypt - kms:GenerateDataKey* - kms:DescribeKey Effect: Allow Principal: AWS: - !GetAtt PipelineRole.Arn - !Sub "arn:aws:iam::${ProdAccountId}:root" - !GetAtt FastlyServicesDomainBuildProjectRole.Arn - !GetAtt FastlyServicesBackendBuildProjectRole.Arn - !GetAtt FastlyServicesHealthcheckBuildProjectRole.Arn - !GetAtt FastlyServicesServiceBuildProjectRole.Arn - !GetAtt FastlyDictionaryDictionaryBuildProjectRole.Arn - !GetAtt FastlyDictionaryDictionaryItemBuildProjectRole.Arn - !GetAtt FastlyLoggingS3BuildProjectRole.Arn - !GetAtt FastlyLoggingSplunkBuildProjectRole.Arn - !GetAtt FastlyTlsCertificateBuildProjectRole.Arn - !GetAtt FastlyTlsPrivateKeysBuildProjectRole.Arn - !GetAtt FastlyTlsDomainBuildProjectRole.Arn Resource: "*" MultiRegion: true PipelineKeyAlias: Type: AWS::KMS::Alias Condition: IsBeta Properties: AliasName: !Sub "alias/cep-${PrefixLower}-pipeline-publish-key" TargetKeyId: !Ref PipelineKey WaitForPipelineRole: Type: Custom::Delay DependsOn: PipelineRole Properties: ServiceToken: !GetAtt DelayFunction.Arn SecondsToSleep: 10 Pipeline: Type: AWS::CodePipeline::Pipeline DependsOn: WaitForPipelineRole Metadata: Comment: This pipeline runs integ tests on all extensions, then drops the build into the prod account for publishing Properties: Name: !Sub "cep-${Env}-${PrefixLower}" RoleArn: !GetAtt PipelineRole.Arn ArtifactStore: !If - IsBeta - Type: S3 Location: !Ref ArtifactBucket EncryptionKey: Id: !Ref PipelineKey Type: KMS - Type: S3 Location: !Ref ArtifactBucket EncryptionKey: !Ref AWS::NoValue Stages: - Name: Source Actions: - Name: S3Source ActionTypeId: Category: Source Owner: AWS Provider: S3 Version: 1 Configuration: S3Bucket: !Ref SourceBucket S3ObjectKey: "source.zip" PollForSourceChanges: true OutputArtifacts: - Name: extensions-source - Name: FastlyResourceBuilds Actions: - Name: FastlyServicesDomain InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyServicesDomainBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Services-Domain" } ] RunOrder: 1 - Name: FastlyServicesBackend InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyServicesBackendBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Services-Backend" } ] RunOrder: 1 - Name: FastlyServicesHealthcheck InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyServicesHealthcheckBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Services-Healthcheck" } ] RunOrder: 1 - Name: FastlyServicesService InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyServicesServiceBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Services-Service" } ] RunOrder: 1 - Name: FastlyDictionaryDictionary InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyDictionaryDictionaryBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Dictionary-Dictionary" } ] RunOrder: 1 - Name: FastlyDictionaryDictionaryItem InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyDictionaryDictionaryItemBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Dictionary-DictionaryItem" } ] RunOrder: 2 - Name: FastlyLoggingS3 InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyLoggingS3BuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Logging-S3" } ] RunOrder: 1 - Name: FastlyLoggingSplunk InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyLoggingSplunkBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Logging-Splunk" } ] RunOrder: 1 - Name: FastlyTlsCertificate InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyTlsCertificateBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Tls-Certificate" } ] RunOrder: 1 - Name: FastlyTlsDomain InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyTlsDomainBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Tls-Domain" } ] RunOrder: 1 - Name: FastlyTlsPrivateKeys InputArtifacts: - Name: extensions-source ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref FastlyTlsPrivateKeysBuildProject EnvironmentVariables: |- [ { "name": "RESOURCE_PATH", "type": "PLAINTEXT", "value": "Fastly-Tls-PrivateKeys" } ] RunOrder: 1 - !If - IsBeta - Name: CopyBuildToProd Actions: - Name: Copy RoleArn: !Sub "arn:aws:iam::${ProdAccountId}:role/${PrefixLower}-registry-extensions-publish-role" InputArtifacts: - Name: extensions-source ActionTypeId: Category: Deploy Owner: AWS Provider: S3 Version: 1 Configuration: BucketName: !Sub "cep-source-${ProdAccountId}-prod-${PrefixLower}" Extract: false ObjectKey: source.zip KMSEncryptionKeyARN: !GetAtt PipelineKey.Arn - !Ref AWS::NoValue PublishBuildBucketRole: Type: AWS::IAM::Role Condition: IsBeta Metadata: Comment: Allows the beta account to put builds into the prod bucket Properties: RoleName: !Sub "cep-${PrefixLower}-publish-role" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - s3.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: put-builds PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: s3:PutObject Resource: - !Sub "arn:aws:s3:::cep-source-${ProdAccountId}-prod-${PrefixLower}" - !Sub "arn:aws:s3:::cep-source-${ProdAccountId}-prod-${PrefixLower}/*" PipelineTopic: Type: AWS::SNS::Topic Metadata: Comment: Topic for pipeline notifications DependsOn: Pipeline Properties: TopicName: !Sub "${PrefixLower}-${Env}-pipeline-topic" Subscription: - Endpoint: !Ref NotificationEmail Protocol: email WaitForPipeline: Type: Custom::Delay DependsOn: - Pipeline Properties: ServiceToken: !GetAtt DelayFunction.Arn SecondsToSleep: 10 WaitForTopic: Type: Custom::Delay DependsOn: - PipelineTopic - PipelineTopicPolicy Properties: ServiceToken: !GetAtt DelayFunction.Arn SecondsToSleep: 10 PipelineTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Id: MyTopicPolicy Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sns:Publish Resource: !Ref PipelineTopic Topics: - !Ref PipelineTopic PipelineEventRole: Type: AWS::IAM::Role Metadata: Comment: Allows the event rule to push to the topic Properties: RoleName: !Sub "cep-${Env}-${PrefixLower}-pipeline-event-role" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: put-events PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sns:Publish Resource: !Ref PipelineTopic PipelineEventRule: Type: AWS::Events::Rule DependsOn: WaitForTopic Properties: Description: Watch for pipeline success and failure EventPattern: source: - aws.codepipeline detail-type: - CodePipeline Pipeline Execution State Change detail: pipeline: - !Ref Pipeline state: - SUCCEEDED - FAILED Name: !Sub "cep-${PrefixLower}-${Env}-pipelines" Targets: - Arn: !Sub "arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${PrefixLower}-${Env}-pipeline-topic" Id: pipeline-topic-target InputTransformer: InputTemplate: '"The pipeline <pipeline> from account <account> has <state> at <at>."' InputPathsMap: pipeline: "$.detail.pipeline" state: "$.detail.state" at: "$.time" account: "$.account" # Prod account resources PublishBuildBucketPolicy: Type: AWS::S3::BucketPolicy Condition: IsProd Metadata: Comment: Allows the beta account to drop builds into the prod account. Properties: Bucket: !Ref SourceBucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: BetaAccountPut Effect: Allow Principal: AWS: - !Sub "arn:aws:iam::${BetaAccountId}:root" - !GetAtt PublishCrossAccountRole.Arn Action: s3:PutObject Resource: - !Sub "arn:aws:s3:::cep-source-${ProdAccountId}-prod-${PrefixLower}" - !Sub "arn:aws:s3:::cep-source-${ProdAccountId}-prod-${PrefixLower}/*" PublishCrossAccountRole: Type: AWS::IAM::Role Condition: IsProd Metadata: Comment: Assumed by codepipeline in the beta account to access the prod source bucket Properties: RoleName: !Sub "${PrefixLower}-registry-extensions-publish-role" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: - !Sub "arn:aws:iam::${BetaAccountId}:root" Action: sts:AssumeRole Path: / Policies: - PolicyName: cross-account-pipeline-deploy PolicyDocument: Version: 2012-10-17 Statement: - Action: - s3:Get* - s3:List* - s3:Put* Effect: Allow Resource: - !Sub "arn:aws:s3:::cep-source-${ProdAccountId}-prod-${PrefixLower}" - !Sub "arn:aws:s3:::cep-source-${ProdAccountId}-prod-${PrefixLower}/*" - !Sub "arn:aws:s3:::cep-${PrefixLower}-beta-${BetaAccountId}-artifacts" - !Sub "arn:aws:s3:::cep-${PrefixLower}-beta-${BetaAccountId}-artifacts/*" - Action: - kms:Encrypt - kms:Decrypt - kms:ReEncrypt - kms:GenerateDataKey* - kms:DescribeKey Effect: Allow Resource: - !Sub "arn:aws:kms:${AWS::Region}:${BetaAccountId}:key/*" # Delay Function to solve race conditions where the resource is not actually ready DelayFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: "lambda-logs" PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - "arn:aws:logs:*:*:*" DelayFunction: Type: AWS::Lambda::Function Properties: Handler: delay.handler Timeout: 120 Role: !GetAtt DelayFunctionRole.Arn Runtime: python3.7 Code: delay.py MemorySize: 1024