@@ -4,15 +4,22 @@ package cfn
44
55import (
66 "context"
7+ "encoding/json"
8+ "errors"
79 "log"
810 "net/http"
911
12+ "github.com/aws/aws-lambda-go/events"
1013 "github.com/aws/aws-lambda-go/lambdacontext"
1114)
1215
1316// CustomResourceLambdaFunction is a standard form Lambda for a Custom Resource.
1417type CustomResourceLambdaFunction func (context.Context , Event ) (reason string , err error )
1518
19+ // SNSCustomResourceLambdaFunction is a standard form Lambda for a Custom Resource
20+ // that is triggered via a SNS topic.
21+ type SNSCustomResourceLambdaFunction func (context.Context , events.SNSEvent ) (reason string , err error )
22+
1623// CustomResourceFunction is a representation of the customer's Custom Resource function.
1724// LambdaWrap will take the returned values and turn them into a response to be sent
1825// to CloudFormation.
@@ -73,3 +80,24 @@ func lambdaWrapWithClient(lambdaFunction CustomResourceFunction, client httpClie
7380func LambdaWrap (lambdaFunction CustomResourceFunction ) (fn CustomResourceLambdaFunction ) {
7481 return lambdaWrapWithClient (lambdaFunction , http .DefaultClient )
7582}
83+
84+ // LambdaWrapSNS wraps a Lambda handler with support for SNS-based custom
85+ // resources. Usage and purpose otherwise same as LambdaWrap().
86+ func LambdaWrapSNS (lambdaFunction CustomResourceFunction ) SNSCustomResourceLambdaFunction {
87+ inner := LambdaWrap (lambdaFunction )
88+ return func (ctx context.Context , event events.SNSEvent ) (reason string , err error ) {
89+ if len (event .Records ) != 1 {
90+ err = errors .New ("expected exactly 1 incoming record" )
91+ return
92+ }
93+
94+ message := event .Records [0 ].SNS .Message
95+
96+ var innerEvent Event
97+ if err = json .Unmarshal ([]byte (message ), & innerEvent ); err != nil {
98+ return
99+ }
100+
101+ return inner (ctx , innerEvent )
102+ }
103+ }
0 commit comments