如何使用现代版本的 CodePipeline 进行 S3 部署

Abe*_*end 7 amazon-s3 amazon-web-services aws-codepipeline aws-cdk static-web-apps

我正在尝试使用最新版本的 AWS CDK for typescript (1.128) 设置一个全新的管道。

管道的创建非常简单。我已经添加了源代码和构建阶段,没有任何问题。这里的目标是自动部署静态登陆页面。

到目前为止我有这段代码:

        const landingPageStep = new ShellStep(`${PREFIX}LandingPageCodeBuildStep`, {
            input: CodePipelineSource.connection(`${GIT_ORG}/vicinialandingpage`, GIT_MAIN, {
                connectionArn: GIT_CONNECTION_ARN, // Created using the AWS console
            }),
            installCommands: [
                'npm ci',
            ],
            commands: [
                'npm run build',
            ],
            primaryOutputDirectory: 'out',
        })

        const pipeline = new CodePipeline(this, `${PREFIX}Pipeline`, {
            pipelineName: `${PREFIX}Pipeline`,
            synth: new ShellStep(`${PREFIX}Synth`, {
                input: CodePipelineSource.connection(`${GIT_ORG}/viciniacdk`, GIT_MAIN, {
                    connectionArn: GIT_CONNECTION_ARN, // Created using the AWS console
                    }),
                commands: [
                    'npm ci',
                    'npm run build',
                    'npx cdk synth',
                ],
                additionalInputs: {
                    'landing_page': landingPageStep,
                },
            }),
        });
Run Code Online (Sandbox Code Playgroud)

我不确定如何实现的步骤是如何使用“landing_page”的输出部署到S3。在 Pipelines 的早期版本中,大量使用了 Artifacts 对象和 CodePipelineActions,与此类似,其中 sourceOutput 是 Artifact 对象:

    const targetBucket = new s3.Bucket(this, 'MyBucket', {});

    const pipeline = new codepipeline.Pipeline(this, 'MyPipeline');
    const deployAction = new codepipeline_actions.S3DeployAction({
        actionName: 'S3Deploy',
        stage: deployStage,
        bucket: targetBucket,
        input: sourceOutput,
    });
    const deployStage = pipeline.addStage({
        stageName: 'Deploy',
        actions: [deployAction],
    });
Run Code Online (Sandbox Code Playgroud)

现在它完全不同了,因为您可以访问 FileSet 对象,并且显然构建步骤旨在用于嵌套输出,如上面的示例所示。每个输出文件都保存在一个文件名丑陋的存储桶中,因此也不能直接访问。

我看到一些黑客方法用 CodeBuildStep 替换 ShellStep 并在 buildspec.yml 文件中用作构建后命令,如下所示:

aws s3 sync out s3://cicd-codebuild-static-website/
Run Code Online (Sandbox Code Playgroud)

但它是在构建阶段解决的,而不是在部署阶段解决的,在部署阶段它是理想的存在。

我在文档中没有看到任何有见地的内容,因此欢迎提出任何建议。谢谢!

kic*_*hik 3

您可以扩展Step和实施ICodePipelineActionFactory。它是一个获取codepipeline.IStage并添加您需要添加的任何操作的界面。

获得工厂步骤后,您可以将其作为方法选项的prepost选项传递addStage()

接近以下内容的东西应该有效:

class S3DeployStep extends Step implements ICodePipelineActionFactory {
  constructor(private readonly provider: codepipeline_actions.JenkinsProvider, private readonly input: FileSet) {
  }

  public produceAction(stage: codepipeline.IStage, options: ProduceActionOptions): CodePipelineActionFactoryResult {

    stage.addAction(new codepipeline_actions.S3DeployAction({
        actionName: 'S3Deploy',
        stage: deployStage,
        bucket: targetBucket,
        input: sourceOutput,
        runOrder: options.runOrder,
    }));

    return { runOrdersConsumed: 1 };
  }
}

// ...

pipeline.addStage(stage, {post: [new S3DeployStep()]});
Run Code Online (Sandbox Code Playgroud)

但一种更简单的方法是将BucketDeployment其作为堆栈部署的一部分来执行。它创建一个自定义资源,将数据从您的资产或另一个存储桶复制到存储桶。它不会在管道中获得自己的步骤,并且会在后台创建一个 Lambda 函数,但它使用起来更简单。

  • 请问“sourceOutput”来自哪里?使用“Pipeline”,您可以将输出配置为“Artifact”,但使用“CodePipeline”,它都是隐式的。 (3认同)
  • 我同意“BucketDeployment”更好,因为您甚至可以使 Cloudfront Cache 无效,但您不能使用工件/文件集作为输入(或者至少我不能这样做)。它期望代码位于同一个 CDK 包或存储桶中,这使其变得不太有用。您提供的解决方案非常有效,我建议您编辑答案以包含从“options.runOrder”获取的“runOrder”参数。如果您不这样做,该步骤将省略“pre”/“post”语句。我为此苦苦挣扎,哈哈。谢谢您的回答! (2认同)