Golang中如何在Lambda使用Cfn.response
Golang中如何在Lambda使用Cfn.response 我正在尝试通过使用自定义资源让Lambda函数向AWS内部的CloudFormation部署发送消息。执行流程应该是:
- CloudFormation开始部署并执行
- Lambda执行任务,然后向CloudFormation发送响应以指示任务已完成
- CloudFormation部署剩余资源
我尝试利用以下包来完成这项工作:
我的代码如下:
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/cfn"
"github.com/aws/aws-lambda-go/lambda"
)
// Event 是函数将从cloudformation接收的结构体
// 其结构应模仿附带事件(sampleevent.json)的结构
type Event struct {
StackID string `json:"StackId"`
ResponseURL string `json:"ResponseURL"`
ResourceProperties struct {
SourceBucket string `json:"SourceBucket"`
SourcePrefix string `json:"SourcePrefix"`
Bucket string `json:"Bucket"`
List []string `json:"List"`
} `json:"ResourceProperties"`
RequestType string `json:"RequestType"`
ResourceType string `json:"ResourceType"`
RequestID string `json:"RequestId"`
LogicalResourceID string `json:"LogicalResourceId"`
}
func handler(ctx context.Context, event Event) {
r := cfn.NewResponse(&cfn.Event{
RequestID: event.RequestID,
ResponseURL: event.ResponseURL,
LogicalResourceID: event.LogicalResourceID,
StackID: event.StackID,
})
const StatusSuccess cfn.StatusType = "SUCCESS"
er := r.Send
if er != nil {
fmt.Println(er)
}
}
func main() {
lambda.Start(handler)
}
事件JSON如下:
{
"StackId": "arn:aws:cloudformation:us-west-2:EXAMPLE/stack-name/guid",
"ResponseURL": "http://pre-signed-S3-url-for-response",
"ResourceProperties": {
"SourceBucket": "iamyourfather22",
"SourcePrefix": "WebApplication/1_StaticWebHosting",
"Bucket": "wildrydes-ap-southeast-2",
"List": [
"1",
"2",
"3"
]
},
"RequestType": "Create",
"ResourceType": "Custom::TestResource",
"RequestId": "unique id for this create request",
"LogicalResourceId": "MyTestResource"
}
当.send运行时,我可以看到它获取了正确的URL,但一直缺少成功消息。当Lambda执行时,它会记录无效的响应对象“”不是有效的ResponseStatus。
如何将ResponseStatus注入到接收器类型中,以便它随.send方法一起发送?
如果术语使用有误,我表示歉意,我学习GO才一个月。很喜欢它,但学习曲线确实很陡峭。
更多关于Golang中如何在Lambda使用Cfn.response的实战教程也可以访问 https://www.itying.com/category-94-b0.html
您的处理程序签名不正确。应该是以下之一:
- func ()
- func () error
- func (TIn) error
- func () (TOut, error)
- func (context.Context) error
- func (context.Context, TIn) error
- func (context.Context) (TOut, error)
- func (context.Context, TIn) (TOut, error)
参见:https://docs.aws.amazon.com/lambda/latest/dg/go-programming-model-handler-types.html
更多关于Golang中如何在Lambda使用Cfn.response的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的帮助。通过将我的处理程序设置为以下内容,成功使其工作:
func handler(ctx context.Context, event cfn.Event)
忘记了Todd McLeod的第一课:Go语言的核心就是类型。我引用了错误的事件类型,这让我陷入了困惑。
谢谢, Steve
在您的代码中,问题在于没有正确设置响应状态和响应数据。cfn.NewResponse 创建了一个响应对象,但您需要调用其方法来设置状态和数据,然后发送响应。
以下是修正后的代码:
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/cfn"
"github.com/aws/aws-lambda-go/lambda"
)
type Event struct {
StackID string `json:"StackId"`
ResponseURL string `json:"ResponseURL"`
ResourceProperties struct {
SourceBucket string `json:"SourceBucket"`
SourcePrefix string `json:"SourcePrefix"`
Bucket string `json:"Bucket"`
List []string `json:"List"`
} `json:"ResourceProperties"`
RequestType string `json:"RequestType"`
ResourceType string `json:"ResourceType"`
RequestID string `json:"RequestId"`
LogicalResourceID string `json:"LogicalResourceId"`
}
func handler(ctx context.Context, event Event) {
// 创建响应对象
response := cfn.NewResponse(&cfn.Event{
RequestID: event.RequestID,
ResponseURL: event.ResponseURL,
LogicalResourceID: event.LogicalResourceID,
StackID: event.StackID,
})
// 设置响应状态为SUCCESS
response.Status = cfn.StatusSuccess
// 设置响应数据(可选)
response.Data = map[string]interface{}{
"Message": "Custom resource operation completed successfully",
}
// 发送响应
if err := response.Send(); err != nil {
fmt.Printf("Error sending response: %v\n", err)
return
}
fmt.Println("Successfully sent response to CloudFormation")
}
func main() {
lambda.Start(handler)
}
关键修改点:
- 直接设置
response.Status = cfn.StatusSuccess来指定成功状态 - 可选地设置
response.Data来包含返回给CloudFormation的数据 - 调用
response.Send()而不是将方法赋值给变量
如果您需要处理不同的请求类型(Create/Update/Delete),可以这样扩展:
func handler(ctx context.Context, event Event) {
response := cfn.NewResponse(&cfn.Event{
RequestID: event.RequestID,
ResponseURL: event.ResponseURL,
LogicalResourceID: event.LogicalResourceID,
StackID: event.StackID,
})
// 根据请求类型处理逻辑
switch event.RequestType {
case "Create":
fmt.Println("Handling Create request")
// 执行创建逻辑
response.Status = cfn.StatusSuccess
response.Data = map[string]interface{}{
"Message": "Resource created successfully",
}
case "Update":
fmt.Println("Handling Update request")
// 执行更新逻辑
response.Status = cfn.StatusSuccess
response.Data = map[string]interface{}{
"Message": "Resource updated successfully",
}
case "Delete":
fmt.Println("Handling Delete request")
// 执行删除逻辑
response.Status = cfn.StatusSuccess
response.Data = map[string]interface{}{
"Message": "Resource deleted successfully",
}
default:
response.Status = cfn.StatusFailed
response.Reason = fmt.Sprintf("Unknown request type: %s", event.RequestType)
}
if err := response.Send(); err != nil {
fmt.Printf("Error sending response: %v\n", err)
}
}
这样设置后,Lambda函数将能够正确地向CloudFormation发送包含成功状态的响应。

