# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 AWSTemplateFormatVersion: '2010-09-09' Description: | Create based test infrastructure (VPC and IAM roles) for base-vpc-pipeline test Parameters: ProjectName: Description: Project name Type: String Default: 'sm-mlops' TestDSQuickstartRegion: Description: Region for data science quickstart use case test Type: String Default: 'eu-central-1' TestServiceCatalogRegion: Description: Region for service catalog deployment use case test Type: String Default: 'eu-west-1' Test2StepCFNRegion: Description: Region for 2-step CFN deployment use case test Type: String Default: 'eu-west-2' CfnArtifactS3BucketNamePrefix: Description: S3 bucket name prefix for artifact bucket Type: String Default: 'ilyiny-demo-cfn-artefacts' CodeCommitRepositoryArn: Description: ARN of CodeCommit repository with source code Type: String NotificationArn: Description: SNS ARN for pipeline events and manual approval events Type: String TestDSQuickstart: Type: String Description: Create and run CodePipeline for DS Quickstart use case AllowedValues: - 'YES' - 'NO' Default: 'YES' TestServiceCatalog: Type: String Description: Create and run CodePipeline for Service Catalog use case AllowedValues: - 'YES' - 'NO' Default: 'YES' Test2StepCFN: Type: String Description: Create and run CodePipeline for 2 step CFN use case AllowedValues: - 'YES' - 'NO' Default: 'YES' Conditions: TestDSQuickstartCondition: !Equals [ !Ref TestDSQuickstart, 'YES' ] TestServiceCatalogCondition: !Equals [ !Ref TestServiceCatalog, 'YES' ] Test2StepCFNCondition: !Equals [ !Ref Test2StepCFN, 'YES' ] Resources: CodePipelineServiceRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: codepipeline.amazonaws.com Action: 'sts:AssumeRole' Path: '/service-role/' RoleName: !Sub '${ProjectName}-${AWS::Region}-CodePipelineServiceRole' Policies: - PolicyName: CodePipelineServiceRoleInLinePolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'iam:PassRole' Resource: '*' Effect: 'Allow' Condition: StringEqualsIfExists: 'iam:PassedToService': - 'cloudformation.amazonaws.com' - 'elasticbeanstalk.amazonaws.com' - 'ec2.amazonaws.com' - 'ecs-tasks.amazonaws.com' - Action: - 'codecommit:CancelUploadArchive' - 'codecommit:GetBranch' - 'codecommit:GetCommit' - 'codecommit:GetRepository' - 'codecommit:GetUploadArchiveStatus' - 'codecommit:UploadArchive' Resource: '*' Effect: 'Allow' - Action: - 'codedeploy:CreateDeployment' - 'codedeploy:GetApplication' - 'codedeploy:GetApplicationRevision' - 'codedeploy:GetDeployment' - 'codedeploy:GetDeploymentConfig' - 'codedeploy:RegisterApplicationRevision' Resource: '*' Effect: 'Allow' - Action: - 'codestar-connections:UseConnection' Resource: '*' Effect: 'Allow' - Action: - 'elasticbeanstalk:*' - 'ec2:*' - 'elasticloadbalancing:*' - 'autoscaling:*' - 'cloudwatch:*' - 's3:*' - 'sns:*' - 'cloudformation:*' - 'rds:*' - 'sqs:*' - 'ecs:*' - 'ecr:*' - 'servicecatalog:*' Resource: '*' Effect: 'Allow' - Action: - 'lambda:InvokeFunction' - 'lambda:ListFunctions' Resource: '*' Effect: 'Allow' - Action: - 'opsworks:CreateDeployment' - 'opsworks:DescribeApps' - 'opsworks:DescribeCommands' - 'opsworks:DescribeDeployments' - 'opsworks:DescribeInstances' - 'opsworks:DescribeStacks' - 'opsworks:UpdateApp' - 'opsworks:UpdateStack' Resource: '*' Effect: 'Allow' - Action: - 'codebuild:BatchGetBuilds' - 'codebuild:StartBuild' - 'codebuild:BatchGetBuildBatches' - 'codebuild:StartBuildBatch' Resource: '*' Effect: 'Allow' - Action: - 'states:DescribeExecution' - 'states:DescribeStateMachine' - 'states:StartExecution' Resource: '*' Effect: 'Allow' - Action: - 'appconfig:StartDeployment' - 'appconfig:StopDeployment' - 'appconfig:GetDeployment' Resource: '*' Effect: 'Allow' CodePipelineDeployRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - cloudformation.amazonaws.com Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: CodePipelineDeployRoleInLinePolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'codecommit:CreateCommit' - 'codecommit:CreateRepository' - 'codecommit:DeleteRepository' - 'codecommit:GetRepository' - 'codecommit:ListRepositories' - 'codecommit:TagResource' - 'config:DescribeConfigurationRecorderStatus' - 'config:DescribeConfigurationRecorders' - 'ec2:DescribeAvailabilityZones' - 'ec2:CreateTags' - 'ec2:DeleteTags' - 'ec2:DescribeTags' - 'resource-groups:CreateGroup' - 'resource-groups:DeleteGroup' - 'resource-groups:Tag' - 'resource-groups:Untag' - 'ssm:AddTagsToResource' - 'ssm:DeleteParameter' - 'ssm:DeleteParameters' - 'ssm:GetParameter' - 'ssm:GetParameters' - 'ssm:PutParameter' - 'ssm:RemoveTagsFromResource' Resource: '*' Effect: 'Allow' - Action: - 'kms:*' Resource: '*' Effect: Allow - Action: - 'lambda:*' Resource: '*' Effect: Allow - Action: - sagemaker:ListDomains - sagemaker:CreateDomain - sagemaker:DescribeDomain - sagemaker:DeleteDomain - sagemaker:UpdateDomain - sagemaker:ListUserProfiles - sagemaker:CreateUserProfile - sagemaker:UpdateUserProfile - sagemaker:DeleteUserProfile - sagemaker:DescribeUserProfile - sagemaker:ListApps - sagemaker:CreateApp - sagemaker:DescribeApp - sagemaker:DeleteApp - sagemaker:UpdateApp - sagemaker:CreateNotebookInstanceLifecycleConfig - sagemaker:DeleteNotebookInstanceLifecycleConfig - sagemaker:DescribeNotebookInstanceLifecycleConfig Resource: - !Sub "arn:${AWS::Partition}:sagemaker:*:*:domain/*" - !Sub "arn:${AWS::Partition}:sagemaker:*:*:user-profile/*" - !Sub "arn:${AWS::Partition}:sagemaker:*:*:app/*" Effect: Allow - Action: - servicecatalog:AcceptPortfolioShare - sagemaker:EnableSagemakerServicecatalogPortfolio - sagemaker:DisableSagemakerServicecatalogPortfolio Resource: '*' Effect: Allow ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonEC2FullAccess' - 'arn:aws:iam::aws:policy/IAMFullAccess' - 'arn:aws:iam::aws:policy/AmazonS3FullAccess' - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess' - 'arn:aws:iam::aws:policy/AmazonVPCFullAccess' - 'arn:aws:iam::aws:policy/AWSServiceCatalogAdminFullAccess' - 'arn:aws:iam::aws:policy/AmazonElasticFileSystemFullAccess' - 'arn:aws:iam::aws:policy/AmazonSageMakerFullAccess' - 'arn:aws:iam::aws:policy/AWSCloudFormationFullAccess' - 'arn:aws:iam::aws:policy/AWSCodePipelineFullAccess' CodeBuildServiceRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: codebuild.amazonaws.com Action: 'sts:AssumeRole' Path: '/service-role/' Policies: - PolicyName: CodeBuildServiceRoleInLinePolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: '*' Effect: 'Allow' - Action: - 's3:*Object' - 's3:GetObjectVersion' - 's3:GetBucketAcl' - 's3:GetBucketLocation' - 's3:ListBucket' - 's3:PutObjectTagging' - 's3:CreateBucket' Resource: - !Sub 'arn:aws:s3:::codepipeline-${ProjectName}*' - !Sub 'arn:aws:s3:::codepipeline-${ProjectName}*/*' - !Sub 'arn:aws:s3:::${CfnArtifactS3BucketNamePrefix}*' - !Sub 'arn:aws:s3:::${CfnArtifactS3BucketNamePrefix}*/*}' Effect: 'Allow' - Action: - 'codecommit:GitPull' Resource: '*' Effect: 'Allow' - Action: - 'codebuild:CreateReportGroup' - 'codebuild:CreateReport' - 'codebuild:UpdateReport' - 'codebuild:BatchPutTestCases' - 'codebuild:BatchPutCodeCoverages' Resource: !Sub 'arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/*' Effect: 'Allow' CfnTemplateBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub '${ProjectName}-cfn-build-${AWS::Region}' Description: !Sub 'Building CFN templates for ${ProjectName}' ServiceRole: !GetAtt CodeBuildServiceRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: 'LINUX_CONTAINER' ComputeType: 'BUILD_GENERAL1_SMALL' Image: 'aws/codebuild/amazonlinux2-x86_64-standard:3.0' EnvironmentVariables: - Name: 'S3_BUCKET_NAME_PREFIX' Value: !Sub '${CfnArtifactS3BucketNamePrefix}' - Name: 'DEPLOYMENT_REGION' Value: !Ref AWS::Region Source: Type: CODEPIPELINE BuildSpec: buildspec.yml LogsConfig: CloudWatchLogs: Status: 'ENABLED' TimeoutInMinutes: 5 CloudWatchEventsTriggerRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: 'sts:AssumeRole' Path: '/service-role/' Policies: - PolicyName: CloudWatchEventsRoleInLinePolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'codepipeline:StartPipelineExecution' Resource: - !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${SetupEnvironmentPipeline}' - !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${BaseDeployPipeline}' - !If - TestDSQuickstartCondition - !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${DSQuickstartDeployPipeline}' - !Ref AWS::NoValue - !If - Test2StepCFNCondition - !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${2StepCFNDeployPipeline}' - !Ref AWS::NoValue - !If - TestDSQuickstartCondition - !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${ServiceCatalogDeployPipeline}' - !Ref AWS::NoValue Effect: 'Allow' CodeCommitTriggerEventRule: Type: AWS::Events::Rule Properties: Name: !Sub '${ProjectName}-codecommit-trigger-${AWS::Region}' Description: !Sub 'Rule to trigger a CodePipeline when ${CodeCommitRepositoryArn} is updated with a commit' RoleArn: !GetAtt CloudWatchEventsTriggerRole.Arn EventPattern: source: - 'aws.codecommit' detail-type: - 'CodeCommit Repository State Change' resources: - !Ref CodeCommitRepositoryArn detail: event: - 'referenceCreated' - 'referenceUpdated' referenceType: - "branch" referenceName: - 'master' - 'main' State: 'ENABLED' Targets: - Arn: !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${BaseDeployPipeline}' Id: !Sub commit-${BaseDeployPipeline} RoleArn: !GetAtt CloudWatchEventsTriggerRole.Arn - Arn: !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${SetupEnvironmentPipeline}' Id: !Sub commit-${SetupEnvironmentPipeline} RoleArn: !GetAtt CloudWatchEventsTriggerRole.Arn ######################################################################## # Pipelines ######################################################################## SetupEnvironmentPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub '${ProjectName}-${AWS::Region}-setup-environment' RoleArn: !GetAtt CodePipelineServiceRole.Arn ArtifactStores: - Region: !Ref AWS::Region ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${AWS::Region}' - Region: !Ref TestDSQuickstartRegion ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${TestDSQuickstartRegion}' - Region: !Ref Test2StepCFNRegion ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${Test2StepCFNRegion}' - Region: !Ref TestServiceCatalogRegion ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${TestServiceCatalogRegion}' Stages: # Stage: Source ----------------------------------------------- - Name: Source Actions: - Name: Source ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: '1' Configuration: PollForSourceChanges: 'false' RepositoryName: !Select ['5', !Split [":", !Ref CodeCommitRepositoryArn]] BranchName: 'master' OutputArtifacts: - Name: SourceArtifact # Stage: Build ----------------------------------------------- - Name: Build Actions: - Name: BuildCFNTemplates ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact Configuration: ProjectName: !Ref CfnTemplateBuildProject RunOrder: 1 # Stage: Deploy ----------------------------------------------- - Name: Deploy Actions: # Action 1 - Name: !Sub '${AWS::Region}-AutomationLambdas' ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: !Sub 'LambdasOut-${AWS::Region}' Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-automation' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::automation-pipeline.yaml' OutputFileName: 'lambdas-output.json' TemplateConfiguration: 'BuildArtifact::automation-pipeline.json' RunOrder: 1 # Action 2 - Name: !Sub '${AWS::Region}-SetupStackSetRole' ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: !Sub 'SetupStackSet-${AWS::Region}' Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-setup-stackset-execution-role' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::env-iam-setup-stackset-role.yaml' OutputFileName: 'setup-stackset-output.json' TemplateConfiguration: 'BuildArtifact::env-iam-setup-stackset-role.json' ParameterOverrides: !Sub '{ "AdministratorAccountId": "${AWS::AccountId}" }' RunOrder: 1 # Action 3 - Name: !Sub '${TestDSQuickstartRegion}-AutomationLambdas' ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestDSQuickstartRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: !Sub 'LambdasOut-${TestDSQuickstartRegion}' Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-automation' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::automation-pipeline.yaml' OutputFileName: 'lambdas-output.json' TemplateConfiguration: 'BuildArtifact::automation-pipeline.json' RunOrder: 1 # Action 4 - Name: !Sub '${Test2StepCFNRegion}-AutomationLambdas' ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref Test2StepCFNRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: !Sub 'LambdasOut-${Test2StepCFNRegion}' Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-automation' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::automation-pipeline.yaml' OutputFileName: 'lambdas-output.json' TemplateConfiguration: 'BuildArtifact::automation-pipeline.json' RunOrder: 1 # Action 5 - Name: !Sub '${TestServiceCatalogRegion}-AutomationLambdas' ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestServiceCatalogRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: !Sub 'LambdasOut-${TestServiceCatalogRegion}' Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-automation' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::automation-pipeline.yaml' OutputFileName: 'lambdas-output.json' TemplateConfiguration: 'BuildArtifact::automation-pipeline.json' RunOrder: 1 AutomationLambdaPipelineNotificationRule: Type: AWS::CodeStarNotifications::NotificationRule Properties: DetailType: 'FULL' EventTypeIds: - 'codepipeline-pipeline-pipeline-execution-failed' Name: !Sub '${SetupEnvironmentPipeline}-notifications' Resource: !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${SetupEnvironmentPipeline}' Status: 'ENABLED' Targets: - TargetAddress: !Ref NotificationArn TargetType: 'SNS' ######################################################################## BaseDeployPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub '${ProjectName}-${AWS::Region}-base' RoleArn: !GetAtt CodePipelineServiceRole.Arn ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${AWS::Region}' Stages: # Stage: Source ----------------------------------------------- - Name: Source Actions: - Name: Source ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: '1' Configuration: PollForSourceChanges: 'false' RepositoryName: !Select ['5', !Split [":", !Ref CodeCommitRepositoryArn]] BranchName: 'master' OutputArtifacts: - Name: SourceArtifact # Stage: Build ----------------------------------------------- - Name: Build Actions: - Name: BuildCFNTemplates ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact Configuration: ProjectName: !Ref CfnTemplateBuildProject RunOrder: 1 # Stage: Deploy ----------------------------------------------- - Name: Deploy Actions: # Action 1 - Name: BaseVPC ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: VPCOut Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: 'base-vpc' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::aws-vpc.template.yaml' OutputFileName: 'vpc-output.json' ParameterOverrides: !Sub '{ "AvailabilityZones": "${AWS::Region}a,${AWS::Region}b" }' TemplateConfiguration: 'BuildArtifact::base-vpc.json' RunOrder: 1 # Action 2 - Name: CoreIAMSharedRoles ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: CoreIAMSharedRolesOutput Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: 'base-core-iam-shared-roles' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::core-iam-shared-roles.yaml' OutputFileName: 'core-iam-shared-roles-output.json' TemplateConfiguration: 'BuildArtifact::core-iam-shared-roles.json' ParameterOverrides: !Sub '{ "DSAdministratorRoleName": "base-${AWS::Region}-DataScienceAdministrator", "SageMakerDetectiveControlExecutionRoleName": "base-${AWS::Region}-DSSageMakerDetectiveControlRole", "SCLaunchRoleName": "base-${AWS::Region}-DSServiceCatalogLaunchRole" }' RunOrder: 1 # Action 3 - Name: EnvironmentIAMRoles ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: I Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: 'e' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::env-iam.yaml' OutputFileName: 'i.json' TemplateConfiguration: 'BuildArtifact::env-iam.json' ParameterOverrides: !Sub '{ "EnvName":"${ProjectName}" }' RunOrder: 1 # Action 4 - Name: EnvironmentIAMTargetAccountRoles ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: TA Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: 't' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::env-iam-target-account-roles.yaml' OutputFileName: 'ta.json' TemplateConfiguration: 'BuildArtifact::env-iam-target-account-roles.json' ParameterOverrides: !Sub '{ "EnvName":"${ProjectName}", "PipelineExecutionRoleArn":"arn:aws:iam::${AWS::AccountId}:role/service-role/AmazonSageMakerServiceCatalogProductsUseRole", "AdministratorAccountId":"${AWS::AccountId}", "ModelS3KMSKeyArn":"*", "ModelBucketName":"*${AWS::Region}-${AWS::AccountId}-models" }' RunOrder: 1 # Action 5 - Name: BaseVPCTestPipeline ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: BuildArtifact - Name: I - Name: TA - Name: VPCOut OutputArtifacts: - Name: BaseVPCTestPipelineOutput Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-${AWS::Region}-VPC-pipeline' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::test-base-vpc-pipeline.yaml' OutputFileName: 'test-base-vpc-pipeline-output.json' TemplateConfiguration: 'BuildArtifact::test-base-vpc-pipeline.json' # There is a maximum size limit of 1024 for the JSON object that can be stored in the ParameterOverrides ParameterOverrides: !Sub '{"TestVPCRegion":"${AWS::Region}","DSTeamAdministratorRoleArn":{"Fn::GetParam":["I","i.json","DSTeamAdministratorRoleArn"]},"DataScientistRoleArn":{"Fn::GetParam":["I","i.json","DataScientistRoleArn"]},"SageMakerExecutionRoleArn":{"Fn::GetParam":["I","i.json","SageMakerExecutionRoleArn"]},"SageMakerPipelineExecutionRoleArn":{"Fn::GetParam":["I","i.json","SageMakerPipelineExecutionRoleArn"]},"SageMakerModelExecutionRoleName":{"Fn::GetParam":["TA","ta.json","SageMakerModelExecutionRoleName"]},"StackSetExecutionRoleName":{"Fn::GetParam":["TA","ta.json","StackSetExecutionRoleName"]},"SetupLambdaExecutionRoleArn":{"Fn::GetParam":["I","i.json","SetupLambdaExecutionRoleArn"]},"SCProjectLaunchRoleArn":{"Fn::GetParam":["I","i.json", "SCProjectLaunchRoleArn"]},"VPCId":{"Fn::GetParam":["VPCOut","vpc-output.json","VPCID"]},"S3VPCEndpointId":{"Fn::GetParam":["VPCOut","vpc-output.json","S3VPCEndpoint"]}}' RunOrder: 2 # Action 6 - Name: ApproveDeployment ActionTypeId: Category: Approval Owner: AWS Version: '1' Provider: Manual Configuration: CustomData: !Sub '${ProjectName} pipeline for base-VPC test is ready in ${AWS::AccountId}:${AWS::Region}. Start the pipeline to execute the test.' ExternalEntityLink: !Sub 'https://${AWS::Region}.console.aws.amazon.com/codesuite/codepipeline/pipelines/${ProjectName}-${AWS::Region}-VPC/view?region=${AWS::Region}' NotificationArn: !Ref NotificationArn RunOrder: 3 # Action 7 - Name: DeleteBaseVPCTestPipeline ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region Configuration: ActionMode: 'DELETE_ONLY' StackName: !Sub '${ProjectName}-${AWS::Region}-VPC-pipeline' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 4 # Action 8 - Name: DeleteEnvironmentIAMTargetAccountRoles ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region Configuration: ActionMode: 'DELETE_ONLY' StackName: 't' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 5 # Action 9 - Name: DeleteEnvironmentIAMRoles ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region Configuration: ActionMode: 'DELETE_ONLY' StackName: 'e' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 5 # Action 10 - Name: DeleteCoreIAMSharedRoles ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region Configuration: ActionMode: 'DELETE_ONLY' StackName: 'base-core-iam-shared-roles' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 5 # Action 11 - Name: DeleteBaseVPC ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref AWS::Region Configuration: ActionMode: 'DELETE_ONLY' StackName: 'base-vpc' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 5 BasePipelineNotificationRule: Type: AWS::CodeStarNotifications::NotificationRule Properties: DetailType: 'FULL' EventTypeIds: - 'codepipeline-pipeline-pipeline-execution-failed' - 'codepipeline-pipeline-pipeline-execution-succeeded' - 'codepipeline-pipeline-manual-approval-needed' Name: !Sub '${BaseDeployPipeline}-notifications' Resource: !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${BaseDeployPipeline}' Status: 'ENABLED' Targets: - TargetAddress: !Ref NotificationArn TargetType: 'SNS' ######################################################################## DSQuickstartDeployPipeline: Type: AWS::CodePipeline::Pipeline Condition: TestDSQuickstartCondition Properties: Name: !Sub '${ProjectName}-${AWS::Region}-ds-quickstart' RoleArn: !GetAtt CodePipelineServiceRole.Arn ArtifactStores: - Region: !Ref AWS::Region ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${AWS::Region}' - Region: !Ref TestDSQuickstartRegion ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${TestDSQuickstartRegion}' Stages: # Stage: Source ----------------------------------------------- - Name: Source Actions: - Name: Source ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: '1' Configuration: PollForSourceChanges: 'false' RepositoryName: !Select ['5', !Split [":", !Ref CodeCommitRepositoryArn]] BranchName: 'master' OutputArtifacts: - Name: SourceArtifact # Stage: Build ----------------------------------------------- - Name: Build Actions: - Name: BuildCFNTemplates ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact Configuration: ProjectName: !Ref CfnTemplateBuildProject EnvironmentVariables: !Sub '[{"name":"DEPLOYMENT_REGION","value":"${TestDSQuickstartRegion}","type":"PLAINTEXT"}]' RunOrder: 1 # Stage: Deploy ----------------------------------------------- - Name: Deploy Actions: # Action 1 - Name: 'DSQuickstart' ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestDSQuickstartRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: DSQuickStartArtifact Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-quickstart' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::data-science-environment-quickstart.yaml-packaged' OutputFileName: 'quickstart-output.json' TemplateConfiguration: 'BuildArtifact::data-science-environment-quickstart.json' ParameterOverrides: !Sub '{ "SeedCodeS3BucketName":"${CfnArtifactS3BucketNamePrefix}-${AWS::Region}" }' RunOrder: 1 # Action 2 - Name: ApproveDeployment ActionTypeId: Category: Approval Owner: AWS Version: '1' Provider: Manual Configuration: CustomData: !Sub '${ProjectName} for DS Quickstart test is deployed in ${AWS::AccountId}:${TestDSQuickstartRegion}.' ExternalEntityLink: !Sub 'https://${TestDSQuickstartRegion}.console.aws.amazon.com/cloudformation/home?region=${TestDSQuickstartRegion}' NotificationArn: !Ref NotificationArn RunOrder: 2 # Action 3 - Name: 'DeleteDSQuickstart' ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestDSQuickstartRegion Configuration: ActionMode: 'DELETE_ONLY' StackName: !Sub '${ProjectName}-quickstart' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 3 # Action 4 - Name: DeleteEFS ActionTypeId: Category: Invoke Owner: AWS Provider: Lambda Version: '1' Region: !Ref TestDSQuickstartRegion InputArtifacts: - Name: DSQuickStartArtifact Configuration: FunctionName: !Sub '${ProjectName}-automation-CleanUpEFS' UserParameters: '{"VPC":"delete", "FileName":"quickstart-output.json"}' RunOrder: 4 DSQuicksightPipelineNotificationRule: Type: AWS::CodeStarNotifications::NotificationRule Condition: TestDSQuickstartCondition Properties: DetailType: 'FULL' EventTypeIds: - 'codepipeline-pipeline-pipeline-execution-failed' - 'codepipeline-pipeline-pipeline-execution-succeeded' - 'codepipeline-pipeline-manual-approval-needed' Name: !Sub '${DSQuickstartDeployPipeline}-notifications' Resource: !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${DSQuickstartDeployPipeline}' Status: 'ENABLED' Targets: - TargetAddress: !Ref NotificationArn TargetType: 'SNS' ######################################################################## 2StepCFNDeployPipeline: Type: AWS::CodePipeline::Pipeline Condition: Test2StepCFNCondition Properties: Name: !Sub '${ProjectName}-${AWS::Region}-2S-CFN' RoleArn: !GetAtt CodePipelineServiceRole.Arn ArtifactStores: - Region: !Ref AWS::Region ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${AWS::Region}' - Region: !Ref Test2StepCFNRegion ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${Test2StepCFNRegion}' Stages: # Stage: Source ----------------------------------------------- - Name: Source Actions: - Name: Source ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: '1' Configuration: PollForSourceChanges: 'false' RepositoryName: !Select ['5', !Split [":", !Ref CodeCommitRepositoryArn]] BranchName: 'master' OutputArtifacts: - Name: SourceArtifact # Stage: Build ----------------------------------------------- - Name: Build Actions: - Name: BuildCFNTemplates ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact Configuration: ProjectName: !Ref CfnTemplateBuildProject EnvironmentVariables: !Sub '[{"name":"DEPLOYMENT_REGION","value":"${Test2StepCFNRegion}","type":"PLAINTEXT"}]' RunOrder: 1 # Stage: Deploy ----------------------------------------------- - Name: Deploy Actions: # Action 1 - Name: CoreMain ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref Test2StepCFNRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: CoreMainOutput Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-core' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::core-main.yaml-packaged' OutputFileName: 'core-main-output.json' TemplateConfiguration: 'BuildArtifact::core-main.json' ParameterOverrides: !Sub '{ "StackSetName":"${ProjectName}-core" }' RunOrder: 1 # Action 2 - Name: EnvironmentMain ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref Test2StepCFNRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: EnvMainOutput Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-env' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::env-main.yaml-packaged' OutputFileName: 'env-main-output.json' TemplateConfiguration: 'BuildArtifact::env-main.json' ParameterOverrides: !Sub '{ "EnvName":"${ProjectName}-env", "AvailabilityZones":"${Test2StepCFNRegion}a,${Test2StepCFNRegion}b", "SeedCodeS3BucketName":"${CfnArtifactS3BucketNamePrefix}-${AWS::Region}", "CreateEnvironmentIAMRoles":"YES", "CreateS3VPCEndpoint":"YES", "CreateVPC":"YES", "CreateNATGateways":"YES", "CreatePrivateSubnets":"YES", "CreateVPCFlowLogsToCloudWatch":"YES", "CreateVPCFlowLogsRole":"YES" }' RunOrder: 2 # Action 3 - Name: ApproveDeployment ActionTypeId: Category: Approval Owner: AWS Version: '1' Provider: Manual Configuration: CustomData: !Sub '${ProjectName} environment with 2-step CFN deployment use case ready for review in ${AWS::AccountId}:${Test2StepCFNRegion}' ExternalEntityLink: !Sub 'https://${Test2StepCFNRegion}.console.aws.amazon.com/cloudformation/home?region=${Test2StepCFNRegion}' NotificationArn: !Ref NotificationArn RunOrder: 3 # Action 4 - Name: DeleteEnvironment ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref Test2StepCFNRegion Configuration: ActionMode: 'DELETE_ONLY' StackName: !Sub '${ProjectName}-env' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 4 # Action 5 - Name: DeleteCore ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref Test2StepCFNRegion Configuration: ActionMode: 'DELETE_ONLY' StackName: !Sub '${ProjectName}-core' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 5 # Action 6 - Name: DeleteEFS ActionTypeId: Category: Invoke Owner: AWS Provider: Lambda Version: '1' Region: !Ref Test2StepCFNRegion InputArtifacts: - Name: EnvMainOutput Configuration: FunctionName: !Sub '${ProjectName}-automation-CleanUpEFS' UserParameters: '{"VPC":"delete","FileName":"env-main-output.json"}' RunOrder: 5 2StepCFNPipelineNotificationRule: Type: AWS::CodeStarNotifications::NotificationRule Condition: Test2StepCFNCondition Properties: DetailType: 'FULL' EventTypeIds: - 'codepipeline-pipeline-pipeline-execution-failed' - 'codepipeline-pipeline-pipeline-execution-succeeded' - 'codepipeline-pipeline-manual-approval-needed' Name: !Sub '${2StepCFNDeployPipeline}-notifications' Resource: !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${2StepCFNDeployPipeline}' Status: 'ENABLED' Targets: - TargetAddress: !Ref NotificationArn TargetType: 'SNS' ######################################################################## ServiceCatalogDeployPipeline: Type: AWS::CodePipeline::Pipeline Condition: TestServiceCatalogCondition Properties: Name: !Sub '${ProjectName}-${AWS::Region}-SC' RoleArn: !GetAtt CodePipelineServiceRole.Arn ArtifactStores: - Region: !Ref AWS::Region ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${AWS::Region}' - Region: !Ref TestServiceCatalogRegion ArtifactStore: Type: S3 Location: !Sub 'codepipeline-${ProjectName}-${TestServiceCatalogRegion}' Stages: # Stage: Source ----------------------------------------------- - Name: Source Actions: - Name: Source ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: '1' Configuration: PollForSourceChanges: 'false' RepositoryName: !Select ['5', !Split [":", !Ref CodeCommitRepositoryArn]] BranchName: 'master' OutputArtifacts: - Name: SourceArtifact # Stage: Build ----------------------------------------------- - Name: Build Actions: - Name: BuildCFNTemplates ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: '1' Region: !Ref AWS::Region InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact Configuration: ProjectName: !Ref CfnTemplateBuildProject EnvironmentVariables: !Sub '[{"name":"DEPLOYMENT_REGION","value":"${TestServiceCatalogRegion}","type":"PLAINTEXT"}]' RunOrder: 1 # Stage: Deploy ----------------------------------------------- - Name: Deploy Actions: # Action 1 - Name: Cleanup ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestServiceCatalogRegion Configuration: ActionMode: 'DELETE_ONLY' StackName: !Sub '${ProjectName}-core' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 1 # Action 2 - Name: CoreMain ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestServiceCatalogRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: CoreMainOutput Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-core' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::core-main.yaml-packaged' OutputFileName: 'core-main-output.json' TemplateConfiguration: 'BuildArtifact::core-main.json' ParameterOverrides: !Sub '{ "StackSetName":"${ProjectName}-core" }' RunOrder: 2 # Action 3 - Associate role with SC product - Name: AssociateSCProduct ActionTypeId: Category: Invoke Owner: AWS Provider: Lambda Version: '1' Region: !Ref TestServiceCatalogRegion InputArtifacts: - Name: CoreMainOutput Configuration: FunctionName: !Sub '${ProjectName}-automation-ProvisionProduct' UserParameters: '{ "Operation":"associate-role", "FileName":"core-main-output.json" }' RunOrder: 3 # Action 4 - Launch SC Product - Name: LaunchSCProduct ActionTypeId: Category: Invoke Owner: AWS Provider: Lambda Version: '1' Region: !Ref TestServiceCatalogRegion InputArtifacts: - Name: CoreMainOutput Configuration: FunctionName: !Sub '${ProjectName}-automation-ProvisionProduct' UserParameters: !Sub '{ "ProvisioningParameters": [ { "Key":"EnvName", "Value":"ds-product" }, { "Key":"EnvType", "Value":"dev" }, { "Key":"AvailabilityZones", "Value":"${TestServiceCatalogRegion}a,${TestServiceCatalogRegion}b" }, { "Key":"NumberOfAZs", "Value":"2" }, { "Key":"SeedCodeS3BucketName", "Value":"${CfnArtifactS3BucketNamePrefix}-${AWS::Region}" } ], "FileName":"core-main-output.json" }' RunOrder: 4 # Action 5 - Name: WaitAndApproveDeployment ActionTypeId: Category: Approval Owner: AWS Version: '1' Provider: Manual Configuration: CustomData: !Sub '${ProjectName} environment has launched Service Catalog product in ${AWS::AccountId}:${TestServiceCatalogRegion}' ExternalEntityLink: !Sub 'https://${TestServiceCatalogRegion}.console.aws.amazon.com/cloudformation/home?region=${TestServiceCatalogRegion}' NotificationArn: !Ref NotificationArn RunOrder: 5 # Action 6 - Name: GetSageMakerDomainId ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestServiceCatalogRegion InputArtifacts: - Name: BuildArtifact OutputArtifacts: - Name: GetSMDomainIdOutput Configuration: ActionMode: 'REPLACE_ON_FAILURE' StackName: !Sub '${ProjectName}-get-sm-domain-id' Capabilities: 'CAPABILITY_NAMED_IAM' RoleArn: !GetAtt CodePipelineDeployRole.Arn TemplatePath: 'BuildArtifact::get-sm-domain-id.yaml' OutputFileName: 'get-sm-domain-id-output.json' TemplateConfiguration: 'BuildArtifact::get-sm-domain-id.json' ParameterOverrides: !Sub '{ "GetSageMakerDomainIdLambdaArn":"arn:${AWS::Partition}:lambda:${TestServiceCatalogRegion}:${AWS::AccountId}:function:${ProjectName}-automation-GetSageMakerDomainId", "SSMParameterName":"ds-product-dev-sagemaker-domain-id" }' RunOrder: 6 # Action 7 - Delete SC Product - Name: TerminateSCProduct ActionTypeId: Category: Invoke Owner: AWS Provider: Lambda Version: '1' Region: !Ref TestServiceCatalogRegion InputArtifacts: - Name: CoreMainOutput Configuration: FunctionName: !Sub '${ProjectName}-automation-TerminateProduct' UserParameters: '{ "FileName":"core-main-output.json" }' RunOrder: 7 # Action 8 - Wait till termination of the SC product - Name: WaitAndApproveSCTermination ActionTypeId: Category: Approval Owner: AWS Version: '1' Provider: Manual Configuration: CustomData: !Sub 'Service Catalog product is being terminated in ${AWS::AccountId}:${TestServiceCatalogRegion}' ExternalEntityLink: !Sub 'https://${TestServiceCatalogRegion}.console.aws.amazon.com/cloudformation/home?region=${TestServiceCatalogRegion}' NotificationArn: !Ref NotificationArn RunOrder: 8 # Action 9 - Name: DeleteCore ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestServiceCatalogRegion Configuration: ActionMode: 'DELETE_ONLY' StackName: !Sub '${ProjectName}-core' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 9 # Action 10 - Name: DeleteEFS ActionTypeId: Category: Invoke Owner: AWS Provider: Lambda Version: '1' Region: !Ref TestServiceCatalogRegion InputArtifacts: - Name: GetSMDomainIdOutput Configuration: FunctionName: !Sub '${ProjectName}-automation-CleanUpEFS' UserParameters: '{ "VPC":"delete", "FileName":"get-sm-domain-id-output.json" }' RunOrder: 9 # Action 11 - Name: DeleteGetSMDomainId ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Region: !Ref TestServiceCatalogRegion Configuration: ActionMode: 'DELETE_ONLY' StackName: !Sub '${ProjectName}-get-sm-domain-id' RoleArn: !GetAtt CodePipelineDeployRole.Arn RunOrder: 9 ServiceCatalogPipelineNotificationRule: Type: AWS::CodeStarNotifications::NotificationRule Condition: TestServiceCatalogCondition Properties: DetailType: 'FULL' EventTypeIds: - 'codepipeline-pipeline-pipeline-execution-failed' - 'codepipeline-pipeline-pipeline-execution-succeeded' - 'codepipeline-pipeline-manual-approval-needed' Name: !Sub '${ServiceCatalogDeployPipeline}-notifications' Resource: !Sub 'arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${ServiceCatalogDeployPipeline}' Status: 'ENABLED' Targets: - TargetAddress: !Ref NotificationArn TargetType: 'SNS'