【发布时间】:2020-07-23 21:39:44
【问题描述】:
我正在尝试使用 AWS CDK 的 Lambda 构建 CI/CD 管道。我们在这里使用一个 gradle 项目。此外,我遵循了示例documentation。我们定义了两个堆栈,分别是 APIStack 和 ApiStackPipeline,其中 APIStack 由 Lambda_Build 处理,ApiStackPipeline 由 CDK_BUILD 处理。
我们正在像 ApiStack 中初始化 Lambda 函数;
final Function contactFunction = Function.Builder.create(this, "contactFunction").role(roleLambda)
.runtime(Runtime.JAVA_8)
.code(lambdaCode)
.handler("com.buraktas.contact.main.ContactLambda::handleRequest")
.memorySize(512)
.timeout(Duration.minutes(1))
.environment(environment)
.description(Instant.now().toString()).build();
在这种情况下,我们将lambdaCode 参数设置为this.lambdaCode = new CfnParametersCode();,与文档中显示的相同(尽管我不确定它是如何得到的)。
现在我们将这个 lambdaCode 传递给 ApiStackPipeline,看起来像这样;
IRepository repository = Repository.fromRepositoryName(this, repoName, repoName);
IBucket bucket = Bucket.fromBucketName(this, "codepipeline-api", "codepipeline-api");
PipelineProject lambdaBuild = PipelineProject.Builder.create(this, "ApiBuild")
.buildSpec(BuildSpec.fromSourceFilename("lambda-buildspec.yml"))
.environment(BuildEnvironment.builder().buildImage(LinuxBuildImage.STANDARD_4_0).build())
.build();
PipelineProject cdkBuild = PipelineProject.Builder.create(this, "ApiCDKBuild")
.buildSpec(BuildSpec.fromSourceFilename("cdk-buildspec.yml"))
.environment(BuildEnvironment.builder().buildImage(LinuxBuildImage.STANDARD_4_0).build())
.build();
Artifact sourceOutput = new Artifact();
Artifact cdkBuildOutput = new Artifact("CdkBuildOutput");
Artifact lambdaBuildOutput = new Artifact("LambdaBuildOutput");
Pipeline.Builder.create(this, "ApiPipeline")
.stages(Arrays.asList(
StageProps.builder()
.stageName("Source")
.actions(Arrays.asList(
CodeCommitSourceAction.Builder.create()
.actionName("Source")
.repository(repository)
.output(sourceOutput)
.build()))
.build(),
StageProps.builder()
.stageName("Build")
.actions(Arrays.asList(
CodeBuildAction.Builder.create()
.actionName("Lambda_Build")
.project(lambdaBuild)
.input(sourceOutput)
.outputs(Arrays.asList(lambdaBuildOutput)).build(),
CodeBuildAction.Builder.create()
.actionName("CDK_Build")
.project(cdkBuild)
.input(sourceOutput)
.outputs(Arrays.asList(cdkBuildOutput))
.build()))
.build(),
StageProps.builder()
.stageName("Deploy")
.actions(Arrays.asList(
CloudFormationCreateUpdateStackAction.Builder.create()
.actionName("Lambda_CFN_Deploy")
.templatePath(cdkBuildOutput.atPath("ApiStackAlfa.template.json"))
.adminPermissions(true)
.parameterOverrides(lambdaCode.assign(lambdaBuildOutput.getS3Location()))
.extraInputs(Arrays.asList(lambdaBuildOutput))
.stackName("ApiStackAlfaDeployment")
.build()))
.build()))
.artifactBucket(bucket)
.restartExecutionOnUpdate(true)
.build();
这里我也分享了 *-buildspec.yml 文件;
lambda-buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
java: corretto8
build:
commands:
- echo current directory `pwd`
- echo building gradle project on `date`
- ./gradlew clean build
artifacts:
files:
- build/distributions/src.zip
discard-paths: yes
cdk-buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
nodejs: 10
java: corretto8
commands:
- echo installing aws-cdk on `date`
- npm install aws-cdk
build:
commands:
- echo current directory `pwd`
- ls -l
- echo building cdk project on `date`
- ./gradlew clean build
- npx cdk synth -o dist
post_build:
commands:
- echo listing files after build under dist
- ls -l dist
artifacts:
files:
- ApiStackAlfa.template.json
base-directory: dist
这是我得到的异常堆栈跟踪
Class not found: com.buraktas.api.main.Lambda: java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: com.buraktas.api.main.Lambda
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
最后在这里我分享了一个项目结构的简化版本,如果有帮助的话
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── buraktas
│ │ │ └── api
│ │ │ ├── main
│ │ │ │ ├── ApiMain.java
│ │ │ │ ├── ApiPipelineStack.java
│ │ │ │ ├── ApiStack.java
│ │ │ │ └── Lambda.java
│ │ │ └── repository
│ │ │ └── Repository.java
│ │ └── resources
│ │ └── log4j.properties
│ └── test
│ ├── java
│ │ ├── DocumentTest.java
│ │ └── JsonWriterSettingsTest.java
│ └── resources
│ └── request.http
看起来一切正常,管道已成功创建,并且 Source -> Build -> Deploy 步骤运行顺利。但是,当我触发我的 lambda 函数时,我得到了 ClassNotFoundException。我尝试使用 .zip 或 .jar(胖 jar)工件,但没有任何改变。
感谢您的帮助。
【问题讨论】:
-
找不到什么类?您能否列出您看到的确切异常消息?
-
嗨@Shawn 我从我的 CloudWatch 日志中为我的 lambda 堆栈共享了 ClassNotFoundException,此外还有一个简化版本我在 src 目录下的项目结构。如果您需要其他任何东西,请告诉我。谢谢!
标签: amazon-web-services aws-code-deploy aws-codepipeline aws-cdk