def __init__(self, scope: core.Construct, id: str, *, repo_name: str = None, bucket, **kwargs) -> None: super().__init__(scope, id, **kwargs) github_secret_personal_site = sm.Secret(self, 'github_secret_personal_site', description=f'{__name__} secret for github', \ secret_name='github_secret_personal_site') personal_site_pipeline = codepipeline.Pipeline( self, "Pipeline", pipeline_name="personal_site_github") source_output = codepipeline.Artifact() source_action = codepipeline_actions.GitHubSourceAction( action_name="GitHub_Source", owner=repo_name.split('/')[0], repo=repo_name.split('/')[1], oauth_token=core.SecretValue.secrets_manager( "github_secret_personal_site"), output=source_output, branch="master") deploy_action = codepipeline_actions.S3DeployAction( action_name="S3Deploy", bucket=bucket, input=source_output) #Add the stages defined above to the pipeline personal_site_pipeline.add_stage(stage_name="Source", actions=[source_action]) personal_site_pipeline.add_stage(stage_name="Deploy", actions=[deploy_action])
def setup_web_pipeline(self): """Setup the build pipeline. Using codepipeline to create a Web Pipeline with 3 stages: * Source: CodeCommitSourceAction * Build : CodeBuildActioin * Deploy: S3DeployAction Returns ------- aws_codepipeline.Pipeline """ source_output = cp.Artifact() build_output = cp.Artifact(self.config.web.build_output) return cp.Pipeline( self, 'WebPipeline', pipeline_name=self.config.web.pipeline, stages=[ cp.StageProps(stage_name='Source', actions=[ cp_actions.CodeCommitSourceAction( action_name='Source', repository=self.web_source, branch='master', output=source_output, ) ]), cp.StageProps(stage_name='Build', actions=[ cp_actions.CodeBuildAction( action_name='Build', project=self.web_build_project, input=source_output, outputs=[build_output]) ]), cp.StageProps( stage_name='Deploy', actions=[ cp_actions.S3DeployAction( action_name='Deploy', bucket=self.web_bucket, input=build_output, access_control=s3.BucketAccessControl.PUBLIC_READ) ]) ])
def add_react_build(stack: core.Stack, code_pipeline, source_output, bucket_arn: str): # Could refactor the bucket to be part of the stage # https://github.com/aws-samples/aws-cdk-examples/blob/master/typescript/static-site/static-site.ts # Need to move to a stack / into startuptoolbag # The codebuild project can be moved back out into the pipeline (bit awkward?) react_site_bucket = Bucket.from_bucket_arn(stack, id='SiteBucket', bucket_arn=bucket_arn) stack.build_output_artifact = codepipeline.Artifact() build_output_artifact = codepipeline.Artifact() codebuild_project = codebuild.PipelineProject( stack, "t-u-b-CDKCodebuild", project_name="t-u-b-CodebuildProject", build_spec=codebuild.BuildSpec.from_source_filename( filename='buildspec.yml'), environment=codebuild.BuildEnvironment(privileged=True), description='Pipeline for the-ultimate-boilerplate', timeout=core.Duration.minutes(60), ) build_action = codepipeline_actions.CodeBuildAction( action_name="ReactBuild", project=codebuild_project, input=source_output, outputs=[build_output_artifact]) s3_deploy = codepipeline_actions.S3DeployAction( action_name="ReactS3Push", input=build_output_artifact, bucket=react_site_bucket) # Would be more elegant to be one stage but the input to deploy must be created in a prior stage code_pipeline.add_stage(stage_name="ReactBuild", actions=[build_action]) code_pipeline.add_stage(stage_name="ReactDeploy", actions=[s3_deploy])
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here base_api = _apigw.RestApi(self, 'PetclinicApiGatewayWithCors') api_resource = base_api.root.add_resource('api') self.add_cors_options(api_resource) website_bucket = _s3.Bucket(self, 'PetclinicWebsite', website_index_document='index.html', public_read_access=True, removal_policy=core.RemovalPolicy.DESTROY) # Warm Lambda function Event rule event_rule = _events.Rule(self, 'PetclinicLambdaWarmRule', schedule=_events.Schedule.rate( core.Duration.minutes(3))) code = _commit.Repository( self, 'ServerlessCode', repository_name='spring-petclinic-static-resource') build_project = _build.PipelineProject( self, 'StaticWebBuild', build_spec=_build.BuildSpec.from_object({ 'version': 0.2, 'phases': { 'install': { 'runtime-versions': { 'java': 'openjdk8' }, 'commands': [] }, 'build': { 'commands': [ 'mv scripts/config.js scripts/config.js.origin', 'sed -e "s,http://localhost:8081/,$API_ENDPOINT,g" scripts/config.js.origin > scripts/config.js' ] }, }, 'artifacts': { 'files': '**/*' }, }), environment_variables={ 'API_ENDPOINT': _build.BuildEnvironmentVariable(value=base_api.url) }, environment=_build.BuildEnvironment( build_image=_build.LinuxBuildImage.STANDARD_2_0)) source_output = _pipeline.Artifact('SourceOutput') build_output = _pipeline.Artifact('BuildOutput') pipline = _pipeline.Pipeline( self, 'ServerlessPipeline', stages=[{ 'stageName': 'Source', 'actions': [ _action.CodeCommitSourceAction( action_name='CodeCommit_Source', repository=code, output=source_output) ] }, { 'stageName': 'Build', 'actions': [ _action.CodeBuildAction(action_name='CodeBuild_Static', project=build_project, input=source_output, outputs=[build_output]) ] }, { 'stageName': 'Deploy', 'actions': [ _action.S3DeployAction(action_name='Web_Static_Deploy', input=build_output, bucket=website_bucket) ] }]) core.CfnOutput(self, 'RuleArn', export_name='RuleArn', value=event_rule.rule_arn) core.CfnOutput(self, 'PetclinicApiGatewayWithCorsId', export_name='PetclinicApiGatewayWithCorsId', value=base_api.rest_api_id) core.CfnOutput(self, "PetclinicWebsiteUrl", export_name="PetclinicWebsiteUrl", value=website_bucket.bucket_website_url)
build_spec=codebuild.BuildSpec.from_source_filename( 'codepipeline/release-buildspec.yaml'), role=code_build_role, environment=codebuild.BuildEnvironment( build_image=codebuild.LinuxBuildImage.STANDARD_4_0, ) ), input=source_output, outputs=[release_output] ) ]), codepipeline.StageProps(stage_name='S3-Deploy', actions=[ codepipeline_actions.S3DeployAction( action_name='S3_Deployment', bucket=deployment_bucket, input=release_output, object_key=core.Token.as_string(core.SecretValue.secrets_manager( secret_id=deployment_secret['secret-id'], json_field=deployment_secret['json-fields']['deployment-path'])), ) ]), ]) notification_rule = notifications.CfnNotificationRule( stack, 'CodePipelineNotifications', detail_type='FULL', event_type_ids=[ 'codepipeline-pipeline-pipeline-execution-failed', 'codepipeline-pipeline-pipeline-execution-canceled', 'codepipeline-pipeline-pipeline-execution-succeeded' ], name='aws-emr-launch-codepipeline-notifications',
def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs): """ :param scope: Stack class, used by CDK. :param id: ID of the construct, used by CDK. :param prefix: Prefix of the construct, used for naming purposes. :param environment: Environment of the construct, used for naming purposes. :param configuration: Configuration of the construct. In this case APIGATEWAY_FAN_OUT_SCHEMA. :param kwargs: Other parameters that could be used by the construct. """ super().__init__(scope, id, **kwargs) self.prefix = prefix self.environment_ = environment self._configuration = configuration # Validating that the payload passed is correct validate_configuration( configuration_schema=S3_SPA_SIMPLE_PIPELINE_HOSTING_SCHEMA, configuration_received=self._configuration ) self._deployment_bucket = base_bucket(self, **self._configuration["hosting"]["bucket"]) artifact_bucket_name = ( f"{self.prefix}-{self._configuration['hosting']['bucket']['bucket_name']}-artifacts-{self.environment_}" ) artifact_bucket_config = {"bucket_name": artifact_bucket_name, "versioned": True, "public_read_access": False} self._deployment_artifact_bucket = base_bucket(self, **artifact_bucket_config) behaviour = cf.Behavior( is_default_behavior=self._configuration["hosting"]["cloudfront_distribution"]["origin_config"]["behaviours"][ "is_default_behavior" ] ) cloudfront_origins = cf.SourceConfiguration( behaviors=[behaviour], s3_origin_source=cf.S3OriginConfig(s3_bucket_source=self._deployment_bucket) ) self._cloudfront_distribution = cf.CloudFrontWebDistribution( self, id=self._configuration["hosting"]["cloudfront_distribution"]["name"], origin_configs=[cloudfront_origins], ) code_build_project_name = ( f"{self.prefix}-{self._configuration['pipeline']['stages']['build']['name']}-cbproject-{self.environment_}" ) self._codebuild_project = cb.Project( self, id=code_build_project_name, project_name=code_build_project_name, build_spec=cb.BuildSpec.from_object( { "version": self._configuration["pipeline"]["stages"]["build"].get("version", "0.2"), "phases": {"build": {"commands": self._configuration["pipeline"]["stages"]["build"]["commands"]}}, "artifacts": { "base-directory": self._configuration["pipeline"]["stages"]["build"]["build_directory"], "files": self._configuration["pipeline"]["stages"]["build"].get("files", "**/*"), }, } ), ) source_artifact = cp.Artifact(artifact_name="source_artifact") single_page_app_artifact = cp.Artifact(artifact_name="single_page_app_artifact") pipeline_name = f"{self.prefix}-{self._configuration['pipeline']['name']}-pipeline-{self.environment_}" self._s3_single_page_app_pipeline = cp.Pipeline( self, id=pipeline_name, pipeline_name=pipeline_name, artifact_bucket=self._deployment_artifact_bucket, ) self._s3_single_page_app_pipeline.add_stage( stage_name=self._configuration["pipeline"]["stages"]["github_source"]["name"], actions=[ cp_actions.GitHubSourceAction( action_name=self._configuration["pipeline"]["stages"]["github_source"]["name"], repo=self._configuration["pipeline"]["stages"]["github_source"]["repo"], owner=self._configuration["pipeline"]["stages"]["github_source"]["owner"], branch=self._configuration["pipeline"]["stages"]["github_source"]["branch"], oauth_token=core.SecretValue.secrets_manager( secret_id=self._configuration["pipeline"]["stages"]["github_source"]["oauth_token_secret_arn"], ), output=source_artifact, ) ], ) self._s3_single_page_app_pipeline.add_stage( stage_name=self._configuration["pipeline"]["stages"]["build"]["name"], actions=[ cp_actions.CodeBuildAction( action_name=self._configuration["pipeline"]["stages"]["build"]["name"], input=source_artifact, project=self._codebuild_project, outputs=[single_page_app_artifact], ) ], ) self._s3_single_page_app_pipeline.add_stage( stage_name=self._configuration["pipeline"]["stages"]["deploy"]["name"], actions=[ cp_actions.S3DeployAction( action_name=self._configuration["pipeline"]["stages"]["deploy"]["name"], bucket=self._deployment_bucket, input=single_page_app_artifact, ) ], )
def __init__(self, scope: core.Construct, id: str, website: WebsiteConstruct, **kwargs) -> None: super().__init__(scope, id, **kwargs) stack = core.Stack.of(self) repo = codecommit.Repository(self, 'Repository', repository_name=stack.stack_name.lower()) project = codebuild.PipelineProject( self, 'Builder', environment=codebuild.BuildEnvironment( build_image=codebuild.LinuxBuildImage.AMAZON_LINUX_2_3, compute_type=codebuild.ComputeType.LARGE), cache=codebuild.Cache.local(codebuild.LocalCacheMode.CUSTOM, ), build_spec=codebuild.BuildSpec.from_object({ 'version': 0.2, 'cache': { 'paths': ['nodemodules/**/*'], }, 'phases': { 'install': { 'runtime-versions': { 'nodejs': 12 } }, 'pre_build': { 'commands': ['echo Pre-build started on `date`', 'yarn install'] }, 'build': { 'commands': ['echo Build started on `date`', 'yarn build'] } }, 'artifacts': { 'files': ['**/*'], 'base-directory': 'dist' } }), ) source_artifact = codepipeline.Artifact('SourceArtifact') build_artifact = codepipeline.Artifact('BuildArtifact') pipeline = codepipeline.Pipeline( self, 'Pipeline', cross_account_keys=False, restart_execution_on_update=True, stages=[ codepipeline.StageProps( stage_name='Source', actions=[ codepipeline_actions.CodeCommitSourceAction( action_name='Source', repository=repo, output=source_artifact, ) ]), codepipeline.StageProps( stage_name='Build', actions=[ codepipeline_actions.CodeBuildAction( action_name='Build', project=project, input=source_artifact, outputs=[build_artifact], ) ]), codepipeline.StageProps( stage_name='Deploy', actions=[ codepipeline_actions.S3DeployAction( action_name='Deploy', input=build_artifact, bucket=website.bucket, extract=True, ) ]) ])
def __init__(self, scope: core.Construct, id: str, webhostingbucket, **kwargs): super().__init__(scope, id, **kwargs) prj_name = self.node.try_get_context('project_name') env_name = self.node.try_get_context('env') webhosting_bucket = s3.Bucket.from_bucket_name(self, id='webhosting-id', bucket_name=webhostingbucket ) cdn_id = ssm.StringParameter.from_string_parameter_name(self, id='cdnid', string_parameter_name=f'/{env_name}/app-distribution-id' ) source_repo = ccm.Repository.from_repository_name(self, id='repoid', repository_name='pryan-cdk-devops') artifact_bucket = s3.Bucket(self, id='artifactbucketid', encryption=s3.BucketEncryption.S3_MANAGED, access_control=s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL ) build_project = cb.PipelineProject(self, id='buildfrontend', project_name='BuildFrontend', description=f'{env_name} FrontEndProject project for SPA', environment=cb.BuildEnvironment( build_image=cb.LinuxBuildImage.STANDARD_3_0, environment_variables={ 'distributionid': cb.BuildEnvironmentVariable(value=cdn_id.string_value) } ), cache=cb.Cache.bucket(bucket=artifact_bucket, prefix='codebuild-cache'), build_spec=cb.BuildSpec.from_object({ 'version': '0.2', 'phases': { 'install': { 'commands': [ 'pip install awscli' ] }, 'pre_build': { 'commands': [ 'yarn install' ] }, 'build': { 'commands': [ 'yarn run build' ] }, 'post_build': { 'commands': [ 'aws cloudfront create-invalidation --distribution-id $distributionid --paths "/*" ' ] } }, 'artifacts': { 'files': [ 'build/**/*' ] }, 'cache': { 'paths': ['./node_modules/**/*'] } }) ) pipeline = cp.Pipeline(self, id='frontend-pipeline', pipeline_name=f"{prj_name}-{env_name}-frontend-pipeline", artifact_bucket=artifact_bucket, restart_execution_on_update=False ) source_output = cp.Artifact(artifact_name='source') build_output = cp.Artifact(artifact_name='build') pipeline.add_stage(stage_name='Source', actions=[ cp_actions.CodeCommitSourceAction( action_name='CodeCommitSource', repository=source_repo, output=source_output, branch='master' ) ]) pipeline.add_stage(stage_name='Build', actions=[ cp_actions.CodeBuildAction( action_name='Build', input=source_output, project=build_project, outputs=[build_output] ) ]) pipeline.add_stage(stage_name='Deploy', actions=[ cp_actions.S3DeployAction( action_name='Deploy', input=build_output, bucket=webhosting_bucket, extract=True ) ]) build_project.role.add_to_policy(iam.PolicyStatement( actions=['cloudfront:CreateInvalidation'], resources=['*'] ))
def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # The code that defines your stack goes here repository = codecommit.Repository( self, "slackops-repository", repository_name="slackops-pipeline-repo", description="Repo for the SlackOps Pipeline Demo", ) website_bucket = s3.Bucket(self, "website-bucket", removal_policy=core.RemovalPolicy.DESTROY, auto_delete_objects=True, public_read_access=True, website_index_document="index.html") manual_approval_topic = sns.Topic( self, "manual-approval-notification", ) artifact_bucket = s3.Bucket(self, "artifact-bucket", removal_policy=core.RemovalPolicy.DESTROY) source_artifact = codepipeline.Artifact(artifact_name="Source") deployment_artifact = codepipeline.Artifact(artifact_name="Deployment") pipeline = codepipeline.Pipeline( self, "slackops-pipeline", artifact_bucket=artifact_bucket, stages=[ codepipeline.StageOptions( stage_name="Source", actions=[ codepipeline_actions.CodeCommitSourceAction( repository=repository, branch="master", output=source_artifact, action_name="Source") ]), codepipeline.StageOptions( stage_name="Build", actions=[ codepipeline_actions.CodeBuildAction( input=source_artifact, action_name="Build", project=codebuild.PipelineProject( self, "build-project", build_spec=codebuild.BuildSpec. from_source_filename("buildspec.yml"), environment=codebuild.BuildEnvironment( build_image=codebuild.LinuxBuildImage. STANDARD_5_0), ), outputs=[deployment_artifact]) ]), codepipeline.StageOptions( stage_name=MANUAL_APPROVAL_STAGE_NAME, actions=[ codepipeline_actions.ManualApprovalAction( action_name=MANUAL_APPROVAL_ACTION_NAME, additional_information= "Please Approve the Deployment", notification_topic=manual_approval_topic, ) ]), codepipeline.StageOptions( stage_name="Deploy", actions=[ codepipeline_actions.S3DeployAction( bucket=website_bucket, input=deployment_artifact, access_control=s3.BucketAccessControl.PUBLIC_READ, action_name="deploy-to-s3") ]) ]) # Build the API Gateway to record the approval or rejection rest_api = apigateway.RestApi(self, "slackops-apigw", deploy_options=apigateway.StageOptions( stage_name="prod", )) root_resource = rest_api.root.add_resource("v1") approval_resource = root_resource.add_resource("approval") api_gateway_role = iam.Role(self, "slackops-apigw-role", assumed_by=iam.ServicePrincipal( service="apigateway.amazonaws.com", )) api_gateway_role.add_to_policy( iam.PolicyStatement(actions=["codepipeline:PutApprovalResult"], resources=[pipeline.pipeline_arn + "/*"])) # Double curlies to make str.format work mapping_template = """ #set($token = $input.params("token")) #set($response = $input.params("response")) {{ "actionName": "{action_name}", "pipelineName": "{pipeline_name}", "result": {{ "status": "$response", "summary": "" }}, "stageName": "{stage_name}", "token": "$token" }} """.format( action_name="approve-before-publication", pipeline_name=pipeline.pipeline_name, stage_name="Approval", ) approval_integration = apigateway.AwsIntegration( service="codepipeline", action="PutApprovalResult", integration_http_method="POST", options=apigateway.IntegrationOptions( credentials_role=api_gateway_role, request_parameters={ "integration.request.header.x-amz-target": "'CodePipeline_20150709.PutApprovalResult'", "integration.request.header.Content-Type": "'application/x-amz-json-1.1'", }, passthrough_behavior=apigateway.PassthroughBehavior.NEVER, request_templates={"application/json": mapping_template}, integration_responses=[ apigateway.IntegrationResponse( status_code='400', selection_pattern="4\d{2}", response_parameters={ 'method.response.header.error': 'integration.response.body' }), apigateway.IntegrationResponse( status_code='500', selection_pattern="5\d{2}", response_parameters={ 'method.response.header.error': 'integration.response.body' }), apigateway.IntegrationResponse( status_code='200', selection_pattern="2\d{2}", response_parameters={ 'method.response.header.response': 'integration.response.body' }), ])) approval_method = approval_resource.add_method( http_method="GET", request_validator=apigateway.RequestValidator( self, "request-validator", rest_api=rest_api, request_validator_name="ParamValidator", validate_request_parameters=True), request_parameters={ "method.request.querystring.token": True, "method.request.querystring.response": True, # Approved / Rejected }, method_responses=[ apigateway.MethodResponse( status_code='400', response_parameters={'method.response.header.error': True}), apigateway.MethodResponse( status_code='500', response_parameters={'method.response.header.error': True}), apigateway.MethodResponse( status_code='200', response_parameters={ 'method.response.header.response': True }), ], integration=approval_integration, ) # Notification mechanism ssm_parameter_webhook = ssm.StringParameter( self, "slackops-webhook-parameter", string_value="<replace-me>", parameter_name="/slackops/webhook-url") notification_lambda = _lambda.PythonFunction( self, "slackops-notification", entry=os.path.join(os.path.dirname(__file__), "..", "src"), index="index.py", handler="notification_handler", environment={ "WEBHOOK_URL_PARAMETER": ssm_parameter_webhook.parameter_name, "API_ENDPOINT": rest_api.url_for_path("/v1/approval"), }) notification_lambda.add_event_source( lambda_event_sources.SnsEventSource(topic=manual_approval_topic)) ssm_parameter_webhook.grant_read(notification_lambda) # Outputs core.CfnOutput(self, "repositoryHttps", value=repository.repository_clone_url_http) core.CfnOutput(self, "repositorySSH", value=repository.repository_clone_url_ssh) core.CfnOutput(self, "websiteUrl", value=website_bucket.bucket_website_url)
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) artifact_bucket = s3.Bucket( scope=self, id="s3-artifact", versioned=True, ) self.artifact_bucket = artifact_bucket oauth_token = core.SecretValue.secrets_manager( secret_id=SECRET_GITHUB_ID, json_field=SECRET_GITHUB_JSON_FIELD, ) # Codepipeline build_pipeline = codepipeline.Pipeline( scope=self, id="lambda-pipeline", restart_execution_on_update=True, ) source_output = codepipeline.Artifact() build_pipeline.add_stage(stage_name="Source", actions=[ codepipeline_actions.GitHubSourceAction( oauth_token=oauth_token, action_name="GitHub", owner="paujim", repo="cognito-MFA-flow", output=source_output, ) ]) build_specs = { "version": "0.2", "env": { "variables": { "GO111MODULE": "on", } }, "phases": { "build": { "commands": [ "cd Server", "go mod download", "go test ./...", "> go build -o main ./cmd/", "zip main.zip main", # pack the server "cd ..", "cd Client", "zip -r src.zip .", # pack the client ] } }, "artifacts": { "files": [ "Server/main.zip", "Client/src.zip", ], } } build_output = codepipeline.Artifact() build_pipeline.add_stage( stage_name="Build", actions=[ codepipeline_actions.CodeBuildAction( action_name="CodeBuild", project=codebuild.Project( scope=self, id="codebuild-build", build_spec=codebuild.BuildSpec.from_object( build_specs), ), input=source_output, outputs=[build_output]) ]) build_pipeline.add_stage( stage_name="Upload", actions=[ codepipeline_actions.S3DeployAction( bucket=artifact_bucket, input=build_output, action_name="S3Upload", extract=True, # object_key="Server/main.zip", ) ])
def __init__(self, scope: core.Construct, id: str, artifact_bucket: s3.Bucket, static_website_bucket: s3.Bucket, backend_fn: _lambda.Function, api: apigateway.LambdaRestApi, **kwargs) -> None: super().__init__(scope, id, **kwargs) fn = _lambda.Function( scope=self, id="source-update-function", runtime=_lambda.Runtime.PYTHON_3_8, handler="index.handler", # memory_size=500, timeout=core.Duration.seconds(10), code=_lambda.Code.from_asset( os.path.join("lambdas", "updateSource"))) fn.add_to_role_policy( statement=iam.PolicyStatement(actions=[ "lambda:UpdateFunctionCode", ], resources=[ backend_fn.function_arn, ])) fn.add_to_role_policy( statement=iam.PolicyStatement(actions=[ "s3:GetObject", ], resources=[ artifact_bucket.bucket_arn + "/Server/main.zip", ])) # Codepipeline deploy_pipeline = codepipeline.Pipeline( scope=self, id="deploy-pipeline", restart_execution_on_update=True, ) lambda_source_output = codepipeline.Artifact() client_source_output = codepipeline.Artifact() deploy_pipeline.add_stage(stage_name="Source", actions=[ codepipeline_actions.S3SourceAction( action_name="LambdaSource", bucket=artifact_bucket, bucket_key="Server/main.zip", output=lambda_source_output, ), codepipeline_actions.S3SourceAction( action_name="ClientSource", bucket=artifact_bucket, bucket_key="Client/src.zip", output=client_source_output, ) ]) build_specs = { "version": "0.2", "env": { "variables": { "REACT_APP_AUTH_URL": api.url, } }, "phases": { "install": { "commands": [ "npm install -g yarn", ] }, "build": { "commands": [ "npm install", "yarn test", "yarn build", ] } }, "artifacts": { "base-directory": "build", "files": [ "**/*", ], } } client_build_output = codepipeline.Artifact() deploy_pipeline.add_stage( stage_name="Build", actions=[ codepipeline_actions.CodeBuildAction( action_name="ClientBuild", project=codebuild.Project( scope=self, id="codebuild-client", build_spec=codebuild.BuildSpec.from_object( build_specs), ), input=client_source_output, outputs=[client_build_output]) ]) deploy_pipeline.add_stage(stage_name="Deploy", actions=[ codepipeline_actions.LambdaInvokeAction( lambda_=fn, inputs=[lambda_source_output], action_name="UpdateSource", user_parameters={ "functionName": backend_fn.function_name, "sourceBucket": artifact_bucket.bucket_name, "sourceKey": "Server/main.zip", }), codepipeline_actions.S3DeployAction( bucket=static_website_bucket, input=client_build_output, action_name="DeployClient", extract=True, ), ])
def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) self.source_output = code_pipeline.Artifact() source_action = codepipeline_actions.GitHubSourceAction(action_name="GitHub_Source", owner=startuptoolbag_config.github_user, repo=startuptoolbag_config.github_repo, oauth_token=core.SecretValue.secrets_manager( 'startuptoolbag-github-oath-token'), output=self.source_output, branch='master') # Note - this is an additional artifact per https://gist.github.com/JelsB/cff41685f12613d23a00951ce1531dbb application_code = code_pipeline.Artifact('application_code') cloud_assembly_artifact = code_pipeline.Artifact('cloudformation_output') synth_action = SimpleSynthAction( source_artifact=self.source_output, cloud_assembly_artifact=cloud_assembly_artifact, install_command='npm install -g aws-cdk && pip install -r requirements.txt', synth_command='cdk synth', additional_artifacts=[{'artifact': application_code, 'directory': './'}]) self.cdk_pipeline = CdkPipeline(self, "startuptoolbag-pipeline-project", cloud_assembly_artifact=cloud_assembly_artifact, source_action=source_action, synth_action=synth_action) # Can not be updated as it is in use by the sub stack bucket_name = startuptoolbag_config.website_domain_name if startuptoolbag_config.website_domain_name != "" else None www_site_bucket = s3.Bucket( self, f'WWW2_Bucket_{startuptoolbag_config.website_domain_name}', bucket_name=bucket_name, website_index_document='index.html', website_error_document='error.html', public_read_access=True, removal_policy=core.RemovalPolicy.DESTROY ) # Creates infrastructure including cloudfront and the public facing bucket ub_stage = CDKStage(self, "cdk-stage") cdk_stage = self.cdk_pipeline.add_application_stage(ub_stage) # Now need to build react and deploy # Challenges # 1. Cant get the bucket out of the stage # 2. Cant put the codebuild into the stage # 3. Cant create react build as a separate stage # 4. Cant export the bucket as a variable because the import attempts to run before the stage is synthesized build_output_artifact = code_pipeline.Artifact() codebuild_project = codebuild.PipelineProject( self, "startuptoolbag-CDKCodebuild", project_name="startuptoolbag-CodebuildProject", build_spec=codebuild.BuildSpec.from_source_filename(filename='buildspec.yml'), environment=codebuild.BuildEnvironment(privileged=True), description='React Build', timeout=core.Duration.minutes(60), ) self.build_action = codepipeline_actions.CodeBuildAction(action_name="ReactBuild", project=codebuild_project, input=application_code, outputs=[build_output_artifact]) self.s3_deploy = codepipeline_actions.S3DeployAction(action_name="ReactS3Push", input=build_output_artifact, bucket=www_site_bucket) self.cdk_pipeline.code_pipeline.add_stage(stage_name="ReactBuild", actions=[self.build_action]) self.cdk_pipeline.code_pipeline.add_stage(stage_name="ReactDeploy", actions=[self.s3_deploy]) self.output = core.CfnOutput( self, "WWWSITEBUCKETNAME", export_name="WWWSITEBUCKETNAME", value=www_site_bucket.bucket_name ) props = {'namespace': 'cdk-example-pipeline'} self.output_props = props.copy() self.output_props['WWWSITEBUCKETNAME'] = www_site_bucket
def __init__(self, scope: core.Construct, id: str, artifactbucket, **kwargs) -> None: super().__init__(scope, id, **kwargs) prj_name = self.node.try_get_context("project_name") env_name = self.node.try_get_context("env") artifact_bucket = s3.Bucket.from_bucket_name( self, 'artifactbucket', artifactbucket) github_token = core.SecretValue.secrets_manager( secret_id=f'{env_name}/github-token', json_field='github-token' ) pipeline = cp.Pipeline(self, 'test-pipeline', pipeline_name=f'{env_name}-{prj_name}', artifact_bucket=artifact_bucket, restart_execution_on_update=False, ) source_output = cp.Artifact(artifact_name='source') pipeline.add_stage(stage_name='Source', actions=[ cp_actions.GitHubSourceAction( oauth_token=github_token, output=source_output, repo='testLZFilter', branch='master', owner='manrodri', action_name='GitHubSource' ) ]) deploy_bucket = s3.Bucket(self, 'deploy-bucket', access_control=s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL, encryption=s3.BucketEncryption.S3_MANAGED, block_public_access=s3.BlockPublicAccess( block_public_acls=True, block_public_policy=True, ignore_public_acls=True, restrict_public_buckets=True ), removal_policy=core.RemovalPolicy.DESTROY ) deploy_action = cp_actions.S3DeployAction( action_name="S3Deploy", bucket=deploy_bucket, input=source_output, extract=False, object_key='aws-landing-zone-configuration.zip' ) pipeline.add_stage( stage_name='Deploy', actions=[ deploy_action ] ) # ssm params ssm.StringParameter( self, 'bucket-name', parameter_name=f'/{env_name}/{prj_name}/deploy-bucket-name', string_value=deploy_bucket.bucket_name) ssm.StringParameter( self, 'pipeline-arn', parameter_name=f'/{env_name}/{prj_name}/pipeline-name', string_value=pipeline.pipeline_arn)
def __init__(self, scope: core.Construct, id: str, *, repo_name: str = None, lambda_code_etl: lambda_.CfnParametersCode = None, lambda_code_serve: lambda_.CfnParametersCode = None, **kwargs) -> None: super().__init__(scope, id, **kwargs) code = codecommit.Repository.from_repository_name( self, "ImportedRepo", repo_name) build_pipeline = codebuild.PipelineProject( self, "BuildPipeline", build_spec=codebuild.BuildSpec.from_object( dict(version="0.2", phases=dict( install=dict(commands=[ "npm install aws-cdk", "npm update", "python -m pip install -r requirements.txt" ]), build=dict(commands=["npx cdk synth -o dist"])), artifacts={ "base-directory": "dist", "files": ["InfraStack.template.json"] }, environment=dict( buildImage=codebuild.LinuxBuildImage.STANDARD_2_0)))) build_infra = codebuild.PipelineProject( self, 'BuildInfra', build_spec=codebuild.BuildSpec.from_object( dict(version="0.2", phases=dict(install=dict(commands=[ "python -m pip install -r requirements.txt", "python lambda/test_etl.py" ]), ), artifacts={ "base-directory": "lambda", "files": [ "etl_module.py", "lambda-handler-etl.py", "lambda-handler-serve.py" ] }, environment=dict( buildImage=codebuild.LinuxBuildImage.STANDARD_2_0)))) build_website = codebuild.PipelineProject( self, 'PackageWebsite', build_spec=codebuild.BuildSpec.from_object( dict(version="0.2", phases=dict(install=dict(commands=[""]), ), artifacts={ "base-directory": "website", "files": ["*"] }, environment=dict( buildImage=codebuild.LinuxBuildImage.STANDARD_2_0)))) source_output = codepipeline.Artifact() build_pipeline_output = codepipeline.Artifact("BuildPipelineOutput") build_infra_output = codepipeline.Artifact("BuildInfraOutput") build_website_output = codepipeline.Artifact("BuildWebsiteOutput") infra_location = build_infra_output.s3_location params = lambda_code_etl.assign( bucket_name=infra_location.bucket_name, object_key=infra_location.object_key, object_version=infra_location.object_version) params.update( lambda_code_serve.assign( bucket_name=infra_location.bucket_name, object_key=infra_location.object_key, object_version=infra_location.object_version)) # make an S3 bucket to use to host static files website_bucket = s3.Bucket( self, id + "_s3-bucket", bucket_name=('cdk-s3-static-website-blog-pb-2'), public_read_access=True, removal_policy=core.RemovalPolicy.DESTROY, website_index_document="dashboard.html", website_error_document='error.html', cors=[ s3.CorsRule(allowed_methods=[s3.HttpMethods.GET], allowed_origins=['*']) ]) codepipeline.Pipeline( self, "Pipeline", stages=[ codepipeline.StageProps( stage_name="Source", actions=[ codepipeline_actions.CodeCommitSourceAction( action_name="CodeCommit_Source", repository=code, output=source_output) ]), codepipeline.StageProps( stage_name="Build", actions=[ codepipeline_actions.CodeBuildAction( action_name="Lambda_Build", project=build_infra, input=source_output, outputs=[build_infra_output]), codepipeline_actions.CodeBuildAction( action_name="CDK_Build", project=build_pipeline, input=source_output, outputs=[build_pipeline_output]), codepipeline_actions.CodeBuildAction( action_name="Website_Build", project=build_website, input=source_output, outputs=[build_website_output]) ]), codepipeline.StageProps( stage_name="Deploy", actions=[ codepipeline_actions. CloudFormationCreateUpdateStackAction( action_name="Infra_CFN_Deploy", template_path=build_pipeline_output.at_path( "InfraStack.template.json"), stack_name="InfraDeploymentStack", admin_permissions=True, parameter_overrides=params, extra_inputs=[build_infra_output]), codepipeline_actions.S3DeployAction( action_name='S3_Deploy', bucket=website_bucket, input=build_website_output, ) ]) ])