【问题标题】:How do I specify the CodeUri in my pipeline?如何在我的管道中指定 CodeUri?
【发布时间】:2020-01-15 20:21:34
【问题描述】:

我正在使用 CloudFormation 在 lambda 中做一个无服务器应用程序。

在我的 CodeBuild 项目中,我将其设置为压缩输出并将其放置在“myBucket\AWSServerless1.zip”中,它确实正确。

现在我正在处理我的 CodePipeline,我参考了原始 CodeBuild 项目。然而,现在它把它放在 codepipeline-us-west-##### 中。没关系。问题是 .zip 文件有一个 RANDOM 名称。 CodePipeline 会忽略我在 CodeBuild 项目中给它的名称。

在 serverless.template 中,我必须指定 CodeUri(出于某种奇怪的原因,这似乎是 CodeBuild 项目的输出)。如果我引用 AWSServerless1.zip,它可以正常工作(但它没有构建到那里,所以它的代码过时)......但是......

由于调用 CodeBuild 的 CodePipeline 给它一个随机名称,我应该如何在 serverless.template 中引用 ACTUAL BuildArtifact?

【问题讨论】:

  • 我也有过类似的经历。请删除 template.yaml 中的代码 URI 并尝试。我能够让它以这种方式工作。

标签: amazon-web-services aws-codepipeline


【解决方案1】:

我知道这很奇怪,我被 CodePipeline 的这种行为所困扰,然后不得不重写构建规范以使 CodePipeline 工作。 CodePipeline 会制作自己的 zip 文件,即使您也通过 CodeBuild 创建了自己的 zip,并且它也具有唯一的名称。

但是有一种方法,Codepipeline 将创建一个 zip 文件,但它会在将工件提供给 CodeDeploy 的同时将其解压缩。所以你不必担心它的名字。 CodeDeploy 将获得您的代码的解压缩版本。 CodePipeline 会跟踪名称,并始终指向最新的名称。

假设:

CodePipeline 创建工件:some-random-name.zip

some-random-name
       |- deploy/lib/lambda-code
       |- some-file.yaml

每当 CodePipeline 将工件提供给 CodeDeploy 时,它都会将其解压缩,以便您可以随时参考 some-random-name.zip 下的代码

因此,在您的情况下,当您在 SAM 模板中提供 CodeUri 时,只需提供文件夹名称 deploy,您的 lambda 代码就在其中。

Resources:
  Hello:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: example.MyHandler
      Runtime: java8
      CodeUri: deploy
      Description: ''
      MemorySize: 512
      Timeout: 15

希望这会有所帮助。

【讨论】:

  • 我正在使用 .NET Core 和 serverless.template。我尝试将各种东西放在那里,但似乎它需要成为 zip 的 S3 URL。我在部署阶段解决了这个问题,有 2 个部分,1)部署到 S3 容器以覆盖固定名称 zip 2)现在进行 cloudformation 部署
  • 如果我尝试在 serverless.template 中添加一些内容,例如“.”它错误地说它必须是 s3://... 呃...即使有解决方法,现在我遇到了他们不允许您更新 cloudformation 堆栈的情况。什么?为什么不允许您重新部署代码?我不知道……在我看来,AWS 太糟糕了。到目前为止 3 周试图让它运行。一切都很容易因无意义的错误而中断或失败。我真的在 Azure 的 CI/CD 中启动并运行了 2 小时,两者的经验都是 0。 AWS 3 周和计数:(。
  • 但无论如何 :)... 使用 serverless.template 是否可以在不先部署到 S3 的情况下引用构建工件清理?
【解决方案2】:

我遇到了同样的错误,我设法通过执行以下操作来解决它:

1- 在构建规范 (buildspec.yml) 上添加一个 sam package 命令(这会生成一个 package.yml,cloudformation 将使用它来部署 lambda )。

build:
  commands:
    - sam package
      --template-file ../template.yaml
      --output-template-file ../package.yml
      --s3-bucket onnera-ci-cd-bucketcode here

2- 添加 package.yml 以输出工件

artifacts:
  files:
    - DeviceProvisioning/package.yml

3- 在将部署的 template.yaml 上直接引用 CodeUri(在内部,这将通过 codebuild 的输出工件解析到存储桶)。

Resources:
  DeviceProvisioningFunction:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: DeviceProvisioningFunction/target/DeviceProvisioningFunction-1.0.jar

4- 在管道上使构建阶段的输出在部署阶段可用:

const buildOutput = [new codepipeline.Artifact()];
const buildAction = new codepipeline_actions.CodeBuildAction({
  actionName: 'CodeBuild',
  project: deviceProvisioning,
  input: sourceOutput,
  outputs: buildOutput, 
});

5- 使用构建输出指定部署操作的模板路径:

const deployAction = new codepipeline_actions.CloudFormationCreateUpdateStackAction({
  extraInputs: buildAction.actionProperties.outputs,
  actionName: "UpdateLambda",
  stackName: "DeviceProvisioningStack",
  adminPermissions: true,
  templatePath: buildOutput[0].atPath("package.yml"),
  cfnCapabilities: [CfnCapabilities.AUTO_EXPAND, CfnCapabilities.NAMED_IAM]
});

确保构建阶段的输出工件在部署阶段可用。

【讨论】:

    猜你喜欢
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2021-06-19
    • 2023-01-27
    相关资源
    最近更新 更多