Exemple #1
0
    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])
Exemple #2
0
    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)
                    ])
            ])
Exemple #3
0
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])
Exemple #4
0
    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)
Exemple #5
0
                    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,
                )
            ],
        )
Exemple #7
0
    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,
                        )
                    ])
            ])
Exemple #8
0
    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)
Exemple #10
0
    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",
                )
            ])
Exemple #11
0
    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
Exemple #13
0
    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,
                        )
                    ])
            ])