使用 CDK 部署时 AWS Lambda 不工作
AWS Lambda not working when deployed with CDK
我正在尝试使用 AWS CDK 部署 lambda,但它似乎 working/deployed 不正确。
管道中的 "box" 是绿色的,所以没有返回错误。
一切似乎都很好,但是当我 运行 它手动测试时,我收到下一条消息:
{
"errorType": "LambdaException",
"errorMessage": "Could not find the required 'QuickSight.Lambdas.SpiceRefresh.deps.json'. This file should be present at the root of the deployment package."
}
问题是,如果我手动将 artefact 下载到我的机器上,然后使用 Function package
上传按钮上传,它工作正常。
我有一个 Stack
,其中包含 CfnParametersCode
,这是我用来创建 lambda 的堆栈。
public class LambdaStack : Stack
{
public CfnParametersCode LambdaCode { get; set; }
//code
private Function BuildSpiceRefreshLambda()
{
LambdaCode = Code.FromCfnParameters();
var func = new Function(this, Constants.Lambda.LambdaName, new FunctionProps
{
Code = LambdaCode,
Handler = Constants.Lambda.LambdaHandler,
FunctionName = Constants.Lambda.LambdaName,
MemorySize = 1024,
Tracing = Tracing.ACTIVE,
Timeout = Duration.Seconds(480),
Runtime = Runtime.DOTNET_CORE_2_1,
Environment = new Dictionary<string, string>()
{
{"ENVIRONMENT", Fn.Ref(Constants.EnvironmentVariables.Environment)},
{"APPLICATION_NAME", Constants.Lambda.ApplicationName},
{"AWS_ACCOUNT_ID", Fn.Ref("AWS::AccountId")},
{"LOG_GROUP_NAME", Constants.Lambda.LogGroupName}
},
ReservedConcurrentExecutions = 1,
Role = SpiceRefreshLambdaRole,
Vpc = this.GetProjectVpc(),
SecurityGroups = new ISecurityGroup[]
{
securityGroup
}
});
return func;
}
}
然后我有了管道,其中一个步骤是构建 lambda:
var lambdaBuild = new PipelineProject(this, "appLambda", new PipelineProjectProps
{
BuildSpec = BuildSpec.FromObject(new Dictionary<string, object>
{
["version"] = "0.2",
["phases"] = new Dictionary<string, object>
{
["install"] = new Dictionary<string, object>
{
["commands"] = new string[]
{
"echo \"Installing lambda tools for dotnet\"",
"dotnet tool install -g Amazon.Lambda.Tools",
}
},
["build"] = new Dictionary<string, object>
{
["commands"] = new string[]
{
"echo \"Packaging app lambda\"",
"(cd app/src/Lambdas/app.Lambdas.Action; dotnet lambda package)"
}
}
},
["artifacts"] = new Dictionary<string, object>
{
["files"] = new[]
{
"app/src/Lambdas/app.Lambdas.Action/bin/Release/netcoreapp2.1/app.Lambdas.Action.zip",
}
}
}),
Environment = new BuildEnvironment
{
BuildImage = LinuxBuildImage.STANDARD_2_0
}
});
var lambdaBuildOutput = new Artifact_("LambdaBuildOutput");
new Amazon.CDK.AWS.CodePipeline.Pipeline(this, "appPipeline", new PipelineProps
{
ArtifactBucket = Bucket.FromBucketAttributes(this, "artifact-bucket", new BucketAttributes
{
BucketArn = "bucket",
EncryptionKey = "key"
}),
Role = "role",
Stages = new[]
{
new StageProps
{
StageName = "Source",
Actions = new[]
{
new CodeCommitSourceAction(new CodeCommitSourceActionProps
{
ActionName = "Source",
Repository = code,
Output = sourceOutput,
})
}
},
new StageProps
{
StageName = "Build",
Actions = new[]
{
new CodeBuildAction(new CodeBuildActionProps
{
ActionName = "Lambda_Build",
Project = lambdaBuild,
Input = sourceOutput,
Outputs = new[] {lambdaBuildOutput},
}),
}
},
new StageProps
{
StageName = "Deploy",
Actions = new[]
{
new CloudFormationCreateUpdateStackAction(new CloudFormationCreateUpdateStackActionProps
{
ActionName = "DeployLambdaapp",
TemplatePath = props.appLambdaStack.StackTemplate,
StackName = "appLambdaDeploymentStack",
AdminPermissions = true,
ParameterOverrides = props.appLambdaStack.LambdaCode.Assign(lambdaBuildOutput.S3Location),
ExtraInputs = new[] {lambdaBuildOutput},
Role = "role",
DeploymentRole = "deployRole"
}),
}
}
}
});
- 还有更多步骤,但它们不相关。
所以你可以看到我将 ParameterOverrides
应用到 props.appLambdaStack.LambdaCode.Assign(lambdaBuildOutput.S3Location)
这似乎没问题,因为当创建 lambda 时,它指定了大小,它与lambda 应该是,但是当我执行它时,我收到 "errorMessage": "Could not find the required 'QuickSight.Lambdas.SpiceRefresh.deps.json'. This file should be present at the root of the deployment package."
结果 Cloudformation 文件似乎也很好:
"appLambdaF0BB8286": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "appLambdaSourceBucketNameParameter"
},
"S3Key": {
"Ref": "appLambdaSourceObjectKeyParameter"
}
},
"Handler": "Constants.Lambda.LambdaHandler", //same as the constant in c#
//Rest of the properties
}
}
我在创建 post 之前进行了检查,大多数人都对处理程序有疑问。不幸的是,如果我手动下载 appLambdaSourceBucketNameParameter
、appLambdaSourceObjectKeyParameter
中的对象并将其上传到 lambda,它会完美运行。我认为这将排除我的问题。
知道哪里出了问题吗?
找到解决方案。
问题是我在工件中 returning lambda .zip
["files"] = new[]
{
"app/src/Lambdas/app.Lambdas.Action/bin/Release/netcoreapp2.1/app.Lambdas.Action.zip",
}
但我真正需要的是 return lambda 的二进制文件。 (发布文件夹)
["artifacts"] = new Dictionary<string, object>
{
["base-directory"] = "app/src/Lambdas/app.Lambdas.Action/bin/Release/netcoreapp2.1/publish",
["files"] = new[] { "**.*" }
}
没有其他改变,而且它起作用了。
Cloudformation 翻译:
在我导出之前 artifact::app.Lambdas.Action.zip
然后 AWS 试图找到二进制文件。
现在正在导出 artifact::**.*
,所以所有文件。
我正在尝试使用 AWS CDK 部署 lambda,但它似乎 working/deployed 不正确。 管道中的 "box" 是绿色的,所以没有返回错误。
一切似乎都很好,但是当我 运行 它手动测试时,我收到下一条消息:
{
"errorType": "LambdaException",
"errorMessage": "Could not find the required 'QuickSight.Lambdas.SpiceRefresh.deps.json'. This file should be present at the root of the deployment package."
}
问题是,如果我手动将 artefact 下载到我的机器上,然后使用 Function package
上传按钮上传,它工作正常。
我有一个 Stack
,其中包含 CfnParametersCode
,这是我用来创建 lambda 的堆栈。
public class LambdaStack : Stack
{
public CfnParametersCode LambdaCode { get; set; }
//code
private Function BuildSpiceRefreshLambda()
{
LambdaCode = Code.FromCfnParameters();
var func = new Function(this, Constants.Lambda.LambdaName, new FunctionProps
{
Code = LambdaCode,
Handler = Constants.Lambda.LambdaHandler,
FunctionName = Constants.Lambda.LambdaName,
MemorySize = 1024,
Tracing = Tracing.ACTIVE,
Timeout = Duration.Seconds(480),
Runtime = Runtime.DOTNET_CORE_2_1,
Environment = new Dictionary<string, string>()
{
{"ENVIRONMENT", Fn.Ref(Constants.EnvironmentVariables.Environment)},
{"APPLICATION_NAME", Constants.Lambda.ApplicationName},
{"AWS_ACCOUNT_ID", Fn.Ref("AWS::AccountId")},
{"LOG_GROUP_NAME", Constants.Lambda.LogGroupName}
},
ReservedConcurrentExecutions = 1,
Role = SpiceRefreshLambdaRole,
Vpc = this.GetProjectVpc(),
SecurityGroups = new ISecurityGroup[]
{
securityGroup
}
});
return func;
}
}
然后我有了管道,其中一个步骤是构建 lambda:
var lambdaBuild = new PipelineProject(this, "appLambda", new PipelineProjectProps
{
BuildSpec = BuildSpec.FromObject(new Dictionary<string, object>
{
["version"] = "0.2",
["phases"] = new Dictionary<string, object>
{
["install"] = new Dictionary<string, object>
{
["commands"] = new string[]
{
"echo \"Installing lambda tools for dotnet\"",
"dotnet tool install -g Amazon.Lambda.Tools",
}
},
["build"] = new Dictionary<string, object>
{
["commands"] = new string[]
{
"echo \"Packaging app lambda\"",
"(cd app/src/Lambdas/app.Lambdas.Action; dotnet lambda package)"
}
}
},
["artifacts"] = new Dictionary<string, object>
{
["files"] = new[]
{
"app/src/Lambdas/app.Lambdas.Action/bin/Release/netcoreapp2.1/app.Lambdas.Action.zip",
}
}
}),
Environment = new BuildEnvironment
{
BuildImage = LinuxBuildImage.STANDARD_2_0
}
});
var lambdaBuildOutput = new Artifact_("LambdaBuildOutput");
new Amazon.CDK.AWS.CodePipeline.Pipeline(this, "appPipeline", new PipelineProps
{
ArtifactBucket = Bucket.FromBucketAttributes(this, "artifact-bucket", new BucketAttributes
{
BucketArn = "bucket",
EncryptionKey = "key"
}),
Role = "role",
Stages = new[]
{
new StageProps
{
StageName = "Source",
Actions = new[]
{
new CodeCommitSourceAction(new CodeCommitSourceActionProps
{
ActionName = "Source",
Repository = code,
Output = sourceOutput,
})
}
},
new StageProps
{
StageName = "Build",
Actions = new[]
{
new CodeBuildAction(new CodeBuildActionProps
{
ActionName = "Lambda_Build",
Project = lambdaBuild,
Input = sourceOutput,
Outputs = new[] {lambdaBuildOutput},
}),
}
},
new StageProps
{
StageName = "Deploy",
Actions = new[]
{
new CloudFormationCreateUpdateStackAction(new CloudFormationCreateUpdateStackActionProps
{
ActionName = "DeployLambdaapp",
TemplatePath = props.appLambdaStack.StackTemplate,
StackName = "appLambdaDeploymentStack",
AdminPermissions = true,
ParameterOverrides = props.appLambdaStack.LambdaCode.Assign(lambdaBuildOutput.S3Location),
ExtraInputs = new[] {lambdaBuildOutput},
Role = "role",
DeploymentRole = "deployRole"
}),
}
}
}
});
- 还有更多步骤,但它们不相关。
所以你可以看到我将 ParameterOverrides
应用到 props.appLambdaStack.LambdaCode.Assign(lambdaBuildOutput.S3Location)
这似乎没问题,因为当创建 lambda 时,它指定了大小,它与lambda 应该是,但是当我执行它时,我收到 "errorMessage": "Could not find the required 'QuickSight.Lambdas.SpiceRefresh.deps.json'. This file should be present at the root of the deployment package."
结果 Cloudformation 文件似乎也很好:
"appLambdaF0BB8286": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "appLambdaSourceBucketNameParameter"
},
"S3Key": {
"Ref": "appLambdaSourceObjectKeyParameter"
}
},
"Handler": "Constants.Lambda.LambdaHandler", //same as the constant in c#
//Rest of the properties
}
}
我在创建 post 之前进行了检查,大多数人都对处理程序有疑问。不幸的是,如果我手动下载 appLambdaSourceBucketNameParameter
、appLambdaSourceObjectKeyParameter
中的对象并将其上传到 lambda,它会完美运行。我认为这将排除我的问题。
知道哪里出了问题吗?
找到解决方案。
问题是我在工件中 returning lambda .zip
["files"] = new[]
{
"app/src/Lambdas/app.Lambdas.Action/bin/Release/netcoreapp2.1/app.Lambdas.Action.zip",
}
但我真正需要的是 return lambda 的二进制文件。 (发布文件夹)
["artifacts"] = new Dictionary<string, object>
{
["base-directory"] = "app/src/Lambdas/app.Lambdas.Action/bin/Release/netcoreapp2.1/publish",
["files"] = new[] { "**.*" }
}
没有其他改变,而且它起作用了。
Cloudformation 翻译:
在我导出之前 artifact::app.Lambdas.Action.zip
然后 AWS 试图找到二进制文件。
现在正在导出 artifact::**.*
,所以所有文件。