@@ -8,6 +8,7 @@ import {AuthorizationType} from "aws-cdk-lib/aws-apigateway"
8
8
import * as apiGWv2 from "aws-cdk-lib/aws-apigatewayv2"
9
9
import { HttpLambdaIntegration , WebSocketLambdaIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations"
10
10
import { LogGroup , RetentionDays } from "aws-cdk-lib/aws-logs"
11
+ import { Construct } from "constructs" ;
11
12
12
13
const app = new core . App ( )
13
14
@@ -16,136 +17,199 @@ const env = {
16
17
account : app . node . tryGetContext ( 'account' ) || process . env [ 'CDK_DEFAULT_ACCOUNT' ] || process . env [ 'AWS_ACCOUNT' ] ,
17
18
}
18
19
19
- const prefix = "SampleApp"
20
-
21
- const stack = new core . Stack ( app , "SampleLambdaApp" , { env} )
22
-
23
- const handler = new lambda . DockerImageFunction ( stack , `${ prefix } Container` , {
24
- code : lambda . DockerImageCode . fromImageAsset ( "src" ) ,
25
- memorySize : 128 ,
26
- timeout : core . Duration . minutes ( 1 ) ,
27
- architecture : lambda . Architecture . X86_64 ,
28
- logGroup : new LogGroup ( stack , `${ prefix } LogGroup` , {
29
- logGroupName : `/aws/lambda/${ prefix } Container` ,
30
- retention : RetentionDays . THREE_MONTHS ,
31
- removalPolicy : core . RemovalPolicy . DESTROY ,
32
- } )
33
- } )
34
-
35
- handler . addToRolePolicy ( new iam . PolicyStatement ( {
36
- effect : Effect . ALLOW ,
37
- actions : [
38
- "execute-api:ManageConnections" ,
39
- ] ,
40
- resources : [
41
- `arn:${ core . Aws . PARTITION } :execute-api:*:${ core . Aws . ACCOUNT_ID } :*/*/*/*`
42
- ] ,
43
- } ) )
44
-
45
- const integrationV1 = new apiGWv1 . LambdaIntegration ( handler )
46
-
47
- const integrationV2 = new HttpLambdaIntegration ( "HTTPAPI" , handler )
48
-
49
- const restAPI = new apiGWv1 . RestApi ( stack , `${ prefix } API-REST` , {
50
- restApiName : "sample-app-rest" ,
51
- cloudWatchRole : false ,
52
- endpointTypes : [ apiGWv1 . EndpointType . REGIONAL ] ,
53
- minCompressionSize : Size . kibibytes ( 100 ) ,
54
- policy : new iam . PolicyDocument ( {
55
- statements : [
56
- new iam . PolicyStatement ( {
57
- effect : Effect . ALLOW ,
58
- principals : [
59
- new iam . AnyPrincipal ( )
60
- ] ,
61
- actions : [
62
- "execute-api:Invoke"
63
- ] ,
64
- resources : [
65
- "execute-api:/*"
66
- ] ,
67
- conditions : {
68
- StringEquals : {
69
- "aws:PrincipalOrgID" : [
70
- "o-aq4agy4d07" // dmgw
20
+ class SampleLambdaApp extends core . Stack {
21
+ constructor ( scope : Construct , id : string , props ?: core . StackProps ) {
22
+ super ( scope , id , props )
23
+
24
+ const code = lambda . DockerImageCode . fromImageAsset ( "src" )
25
+ const logGroup = new LogGroup ( this , "LogGroup" , {
26
+ logGroupName : `/aws/lambda/${ id } ` ,
27
+ retention : RetentionDays . THREE_MONTHS ,
28
+ removalPolicy : core . RemovalPolicy . DESTROY ,
29
+ } )
30
+
31
+ const handler = new lambda . DockerImageFunction ( this , "Container" , {
32
+ code,
33
+ memorySize : 128 ,
34
+ timeout : core . Duration . minutes ( 1 ) ,
35
+ architecture : lambda . Architecture . X86_64 ,
36
+ logGroup,
37
+ environment : {
38
+ DEBUG_DUMP_PAYLOAD : "1" ,
39
+ WEBSOCKET_RESPONSE_MODE : "return" ,
40
+ } ,
41
+ } )
42
+
43
+ const bufferedUrl = handler . addFunctionUrl ( {
44
+ invokeMode : lambda . InvokeMode . BUFFERED ,
45
+ } )
46
+
47
+ const streamHandler = new lambda . DockerImageFunction ( this , "StreamHandler" , {
48
+ code,
49
+ memorySize : 128 ,
50
+ timeout : core . Duration . minutes ( 1 ) ,
51
+ architecture : lambda . Architecture . X86_64 ,
52
+ logGroup,
53
+ environment : {
54
+ DEBUG_DUMP_PAYLOAD : "1" ,
55
+ LAMBDA_INVOKE_MODE : "response_stream" ,
56
+ WEBSOCKET_RESPONSE_MODE : "post_to_connection" ,
57
+ } ,
58
+ } )
59
+
60
+ const streamUrl = streamHandler . addFunctionUrl ( {
61
+ invokeMode : lambda . InvokeMode . RESPONSE_STREAM ,
62
+ } )
63
+
64
+ const integrationV1 = new apiGWv1 . LambdaIntegration ( handler )
65
+
66
+ const integrationV2 = new HttpLambdaIntegration ( "HTTPAPI" , handler )
67
+
68
+ const restAPI = new apiGWv1 . RestApi ( this , "RESTAPI" , {
69
+ cloudWatchRole : false ,
70
+ endpointTypes : [ apiGWv1 . EndpointType . REGIONAL ] ,
71
+ minCompressionSize : Size . kibibytes ( 100 ) ,
72
+ policy : new iam . PolicyDocument ( {
73
+ statements : [
74
+ new iam . PolicyStatement ( {
75
+ effect : Effect . ALLOW ,
76
+ principals : [
77
+ new iam . AnyPrincipal ( )
71
78
] ,
72
- }
73
- } ,
79
+ actions : [
80
+ "execute-api:Invoke"
81
+ ] ,
82
+ resources : [
83
+ "execute-api:/*"
84
+ ] ,
85
+ conditions : {
86
+ StringEquals : {
87
+ "aws:PrincipalOrgID" : [
88
+ "o-aq4agy4d07" // dmgw
89
+ ] ,
90
+ }
91
+ } ,
92
+ } )
93
+ ]
94
+ } )
95
+ } )
96
+
97
+ restAPI . root . addProxy ( {
98
+ anyMethod : true ,
99
+ defaultIntegration : integrationV1 ,
100
+ defaultMethodOptions : {
101
+ authorizationType : AuthorizationType . IAM ,
102
+ }
103
+ } )
104
+
105
+ const deploy = new apiGWv1 . Deployment ( this , `RESTAPIDeployment` , {
106
+ api : restAPI ,
107
+ } )
108
+
109
+ const stages = [ "dev" ] . map ( stageName => {
110
+ const stage = new apiGWv1 . Stage ( this , `RESTAPIStage-${ stageName } ` , {
111
+ stageName,
112
+ deployment : deploy ,
74
113
} )
75
- ]
76
- } )
77
- } )
78
-
79
- restAPI . root . addProxy ( {
80
- anyMethod : true ,
81
- defaultIntegration : integrationV1 ,
82
- defaultMethodOptions : {
83
- authorizationType : AuthorizationType . IAM ,
114
+ handler . addPermission ( `FuncPolicyAPIRESTStage-${ stageName } ` , {
115
+ principal : new iam . ServicePrincipal ( "apigateway.amazonaws.com" ) ,
116
+ action : "lambda:InvokeFunction" ,
117
+ sourceArn : restAPI . arnForExecuteApi ( "*" , "/*" , stageName )
118
+ } )
119
+ return stage
120
+ } )
121
+
122
+ handler . addPermission ( `Func-Policy-API-REST` , {
123
+ principal : new iam . ServicePrincipal ( "apigateway.amazonaws.com" ) ,
124
+ action : "lambda:InvokeFunction" ,
125
+ sourceArn : restAPI . arnForExecuteApi ( )
126
+ } )
127
+
128
+ const httpAPI = new apiGWv2 . HttpApi ( this , "HTTPAPI" , {
129
+ createDefaultStage : true ,
130
+ } )
131
+
132
+ httpAPI . addRoutes ( {
133
+ path : "/{proxy+}" ,
134
+ methods : [
135
+ apiGWv2 . HttpMethod . ANY ,
136
+ ] ,
137
+ integration : integrationV2 ,
138
+ } )
139
+
140
+ new apiGWv2 . HttpStage ( this , "APIStage" , {
141
+ httpApi : httpAPI ,
142
+ stageName : "test" ,
143
+ autoDeploy : true ,
144
+ } )
145
+
146
+ const webSocketApi1 = new apiGWv2 . WebSocketApi ( this , "WebsocketAPI1" , {
147
+ routeSelectionExpression : "$request.body.action" ,
148
+ connectRouteOptions : {
149
+ integration : new WebSocketLambdaIntegration ( "WebsocketAPIConnect" , handler ) ,
150
+ } ,
151
+ disconnectRouteOptions : {
152
+ integration : new WebSocketLambdaIntegration ( "WebsocketAPIDisconnect" , handler ) ,
153
+ } ,
154
+ defaultRouteOptions : {
155
+ integration : new WebSocketLambdaIntegration ( "WebsocketAPIDefault" , handler ) ,
156
+ returnResponse : true ,
157
+ } ,
158
+ } )
159
+
160
+ new apiGWv2 . WebSocketStage ( this , "WebsocketAPIProd1" , {
161
+ stageName : "prod" ,
162
+ webSocketApi : webSocketApi1 ,
163
+ autoDeploy : true ,
164
+ } )
165
+
166
+ const webSocketApi2 = new apiGWv2 . WebSocketApi ( this , "WebsocketAPI2" , {
167
+ routeSelectionExpression : "$request.body.action" ,
168
+ connectRouteOptions : {
169
+ integration : new WebSocketLambdaIntegration ( "WebsocketAPIConnect" , streamHandler ) ,
170
+ } ,
171
+ disconnectRouteOptions : {
172
+ integration : new WebSocketLambdaIntegration ( "WebsocketAPIDisconnect" , streamHandler ) ,
173
+ } ,
174
+ defaultRouteOptions : {
175
+ integration : new WebSocketLambdaIntegration ( "WebsocketAPIDefault" , streamHandler ) ,
176
+ } ,
177
+ } )
178
+
179
+ webSocketApi2 . grantManageConnections ( streamHandler )
180
+
181
+ new apiGWv2 . WebSocketStage ( this , "WebsocketAPIProd2" , {
182
+ stageName : "prod" ,
183
+ webSocketApi : webSocketApi2 ,
184
+ autoDeploy : true ,
185
+ } )
186
+
187
+ new core . CfnOutput ( this , "LambdaURL" , {
188
+ value : bufferedUrl . url ,
189
+ } )
190
+
191
+ new core . CfnOutput ( this , "LambdaURLStream" , {
192
+ value : streamUrl . url ,
193
+ } )
194
+
195
+ new core . CfnOutput ( this , "APIGatewayV1URL" , {
196
+ value : restAPI . url ,
197
+ } )
198
+
199
+ new core . CfnOutput ( this , "APIGatewayV2URL" , {
200
+ value : httpAPI . apiEndpoint ,
201
+ } )
202
+
203
+ new core . CfnOutput ( this , "WebSocketAPIURLReturn" , {
204
+ value : webSocketApi1 . apiEndpoint ,
205
+ } )
206
+
207
+ new core . CfnOutput ( this , "WebSocketAPIURLStream" , {
208
+ value : webSocketApi2 . apiEndpoint ,
209
+ } )
84
210
}
85
- } )
86
-
87
- const deploy = new apiGWv1 . Deployment ( stack , `${ prefix } -API-REST-Deploy` , {
88
- api : restAPI ,
89
- } )
90
-
91
- const stages = [ "dev" ] . map ( stageName => {
92
- const stage = new apiGWv1 . Stage ( stack , `${ prefix } -API-REST-Stage-${ stageName } ` , {
93
- stageName,
94
- deployment : deploy ,
95
- } )
96
- handler . addPermission ( `${ prefix } Func-Policy-API-REST-Stage-${ stageName } ` , {
97
- principal : new iam . ServicePrincipal ( "apigateway.amazonaws.com" ) ,
98
- action : "lambda:InvokeFunction" ,
99
- sourceArn : restAPI . arnForExecuteApi ( "*" , "/*" , stageName )
100
- } )
101
- return stage
102
- } )
103
-
104
- handler . addPermission ( `${ prefix } Func-Policy-API-REST` , {
105
- principal : new iam . ServicePrincipal ( "apigateway.amazonaws.com" ) ,
106
- action : "lambda:InvokeFunction" ,
107
- sourceArn : restAPI . arnForExecuteApi ( )
108
- } )
109
-
110
- const httpAPI = new apiGWv2 . HttpApi ( stack , `${ prefix } API-HTTP` , {
111
- apiName : "sample-app-http" ,
112
- createDefaultStage : true ,
113
- } )
114
-
115
- httpAPI . addRoutes ( {
116
- path : "/{proxy+}" ,
117
- methods : [
118
- apiGWv2 . HttpMethod . ANY ,
119
- ] ,
120
- integration : integrationV2 ,
121
- } )
122
-
123
- new apiGWv2 . HttpStage ( stack , `${ prefix } APIStage` , {
124
- httpApi : httpAPI ,
125
- stageName : "test" ,
126
- autoDeploy : true ,
127
- } )
128
-
129
- const integrationWS = new WebSocketLambdaIntegration ( "WebsocketAPI" , handler )
130
-
131
- const webSocketApi = new apiGWv2 . WebSocketApi ( stack , `${ prefix } API-WS` , {
132
- apiName : "websocket-api" ,
133
- routeSelectionExpression : "$request.body.action" ,
134
- connectRouteOptions : {
135
- integration : integrationWS ,
136
- } ,
137
- disconnectRouteOptions : {
138
- integration : integrationWS ,
139
- } ,
140
- defaultRouteOptions : {
141
- integration : integrationWS ,
142
- } ,
143
- } )
144
-
145
- new apiGWv2 . WebSocketStage ( stack , `${ prefix } API-WS-Prod` , {
146
- stageName : "prod" ,
147
- webSocketApi,
148
- autoDeploy : true ,
149
- } )
211
+ }
212
+
213
+ new SampleLambdaApp ( app , "SampleLambdaApp" , { env} )
150
214
151
215
app . synth ( )
0 commit comments