1 | AWSTemplateFormatVersion: '2010-09-09'
|
2 | Description: 'stack: {{stackName}} | deployed by Kes'
|
3 | Parameters:
|
4 | CmrPassword:
|
5 | Type: String
|
6 | Description: 'Password used to publish CMR records. This is encrypted by Custom::Cumulus'
|
7 | Default: ""
|
8 | NoEcho: true
|
9 | ElasticSearchDomain:
|
10 | Type: String
|
11 | Description: 'ElasticSearch Url'
|
12 | NoEcho: true
|
13 | Default: 'noValue'
|
14 | LaunchpadPassphrase:
|
15 | Type: String
|
16 | Description: 'Passphrase of the Launchpad PIK certificate. This is encrypted by Custom::Cumulus'
|
17 | Default: ""
|
18 | NoEcho: true
|
19 | SecurityGroupId:
|
20 | Type: String
|
21 | Description: 'Security Group ID'
|
22 | Default: 'noValue'
|
23 | log2elasticsearchLambdaFunctionArn:
|
24 | Type: String
|
25 | Description: 'logToElasticsearch Lambda function ARN'
|
26 | {{#each apis}}
|
27 | {{#ifEquals name "backend" }}
|
28 | EcsCluster:
|
29 | Type: String
|
30 | AsyncOperationTaskDefinition:
|
31 | Type: String
|
32 | BulkDeleteLambdaFunctionArn:
|
33 | Type: String
|
34 | Description: 'BulkDelete Lambda function ARN'
|
35 | CreateReconciliationReportLambdaFunctionArn:
|
36 | Type: String
|
37 | Description: 'CreateReconciliationReport Lambda function ARN'
|
38 | EmsIngestReportLambdaFunctionArn:
|
39 | Type: String
|
40 | Description: 'EmsIngestReport Lambda function ARN'
|
41 | EmsDistributionReportLambdaFunctionArn:
|
42 | Type: String
|
43 | Description: 'EmsDistributionReport Lambda function ARN'
|
44 | EmsProductMetadataReportLambdaFunctionArn:
|
45 | Type: String
|
46 | Description: 'EmsProductMetadataReport Lambda function ARN'
|
47 | messageConsumerLambdaFunctionArn:
|
48 | Type: String
|
49 | Description: 'messageConsumer Lambda function ARN'
|
50 | ScheduleSFLambdaFunctionArn:
|
51 | Type: String
|
52 | Description: 'ScheduleSF Lambda function ARN'
|
53 | KinesisInboundEventLoggerLambdaFunctionArn:
|
54 | Type: String
|
55 | Description: 'KinesisInboundEventLogger Lambda function ARN'
|
56 | IndexFromDatabaseLambdaFunctionArn:
|
57 | Type: String
|
58 | Description: 'IndexFromDatabaseLambda Lambda function ARN'
|
59 | distributionRestApi:
|
60 | Type: String
|
61 | Description: Distribution REST API ID
|
62 | Default: 'noValue'
|
63 | {{/ifEquals}}
|
64 | {{/each}}
|
65 | {{# each parent.dynamos}}
|
66 | {{@key}}DynamoDB:
|
67 | Type: String
|
68 | Description: '{{@key}} Table name'
|
69 | {{/each}}
|
70 |
|
71 | Resources:
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | {{#each apis}}
|
77 | {{name}}RestApi:
|
78 | Type: AWS::ApiGateway::RestApi
|
79 | Properties:
|
80 | Name: {{../stackName}}-{{name}}
|
81 | {{#ifPrivateApi ../parent.apiConfigs name}}
|
82 | EndpointConfiguration:
|
83 | Types:
|
84 | - 'PRIVATE'
|
85 |
|
86 | Policy:
|
87 | Version: '2012-10-17'
|
88 | Statement:
|
89 | - Effect: "Allow"
|
90 | Principal: "*"
|
91 | Action: "*"
|
92 | Resource: "*"
|
93 | Condition:
|
94 | StringEquals:
|
95 | aws:SourceVpc: {{../../parent.vpc.vpcId}}
|
96 | {{/ifPrivateApi}}
|
97 | {{/each}}
|
98 |
|
99 | {{#each apis}}
|
100 | {{name}}ApiGatewayStage:
|
101 | Type: AWS::ApiGateway::Stage
|
102 | Properties:
|
103 | RestApiId:
|
104 | Ref: {{name}}RestApi
|
105 | StageName: {{../parent.apiStage}}
|
106 | {{#ifLogApiGatewayToCloudWatch ../parent.apiConfigs name}}
|
107 | AccessLogSetting:
|
108 | DestinationArn:
|
109 | Fn::GetAtt:
|
110 | - ApiGatewayCloudWatchLogGroup{{name}}
|
111 | - Arn
|
112 | Format: '{ "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "caller":"$context.identity.caller", "user":"$context.identity.user", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod", "resourcePath":"$context.resourcePath", "status":"$context.status", "protocol":"$context.protocol", "responseLength":"$context.responseLength" }'
|
113 | MethodSettings:
|
114 | - DataTraceEnabled: true
|
115 | HttpMethod: "*"
|
116 | LoggingLevel: INFO
|
117 | ResourcePath: "/*"
|
118 | MetricsEnabled: false
|
119 | {{/ifLogApiGatewayToCloudWatch}}
|
120 | DeploymentId:
|
121 | Ref: ApiGatewayDeployment1{{../parent.apiStage}}{{name}}
|
122 | {{/each}}
|
123 |
|
124 |
|
125 | {{# if apiMethods}}
|
126 | {{# each apiDependencies}}
|
127 | {{# if ../apiDeploy }}
|
128 | ApiGatewayDeployment1{{../parent.apiStage}}{{name}}:
|
129 | DependsOn:
|
130 | {{#each methods}}
|
131 | - {{name}}
|
132 | {{/each}}
|
133 | Type: AWS::ApiGateway::Deployment
|
134 | Properties:
|
135 | RestApiId:
|
136 | Ref: {{name}}RestApi
|
137 | {{/if}}
|
138 | {{/each}}
|
139 |
|
140 | {{#each apiMethods}}
|
141 | {{name}}:
|
142 | Type: AWS::ApiGateway::Method
|
143 | Properties:
|
144 | ResourceId:
|
145 | Ref: {{resource}}
|
146 | RestApiId:
|
147 | Ref: {{api}}RestApi
|
148 | HttpMethod: {{method}}
|
149 | AuthorizationType: NONE
|
150 | Integration:
|
151 | Type: AWS_PROXY
|
152 | IntegrationHttpMethod: POST
|
153 | Uri:
|
154 | Fn::Join:
|
155 | - ''
|
156 | - - 'arn:aws:apigateway:'
|
157 | - Ref: AWS::Region
|
158 | - :lambda:path/2015-03-31/functions/
|
159 | - Fn::GetAtt:
|
160 | - {{lambda}}LambdaFunction
|
161 | - Arn
|
162 | - /invocations
|
163 |
|
164 | {{/each}}
|
165 |
|
166 | {{#each apiMethodsOptions}}
|
167 | {{name}}:
|
168 | Type: AWS::ApiGateway::Method
|
169 | Properties:
|
170 | AuthorizationType: NONE
|
171 | HttpMethod: OPTIONS
|
172 | Integration:
|
173 | IntegrationResponses:
|
174 | - ResponseParameters:
|
175 | method.response.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
|
176 | method.response.header.Access-Control-Allow-Methods: '''OPTIONS,PUT,POST,GET,DELETE'''
|
177 | method.response.header.Access-Control-Allow-Origin: '''*'''
|
178 | ResponseTemplates:
|
179 | application/json: ''
|
180 | StatusCode: '200'
|
181 | RequestTemplates:
|
182 | application/json: '{statusCode:200}'
|
183 | Type: MOCK
|
184 | MethodResponses:
|
185 | - ResponseModels: {}
|
186 | ResponseParameters:
|
187 | method.response.header.Access-Control-Allow-Headers: true
|
188 | method.response.header.Access-Control-Allow-Methods: true
|
189 | method.response.header.Access-Control-Allow-Origin: true
|
190 | StatusCode: '200'
|
191 | RequestParameters:
|
192 | method.request.header.Authorization: true
|
193 | ResourceId:
|
194 | Ref: {{resource}}
|
195 | RestApiId:
|
196 | Ref: {{api}}RestApi
|
197 |
|
198 | {{/each}}
|
199 |
|
200 | {{#each apiResources}}
|
201 | {{name}}:
|
202 | Type: AWS::ApiGateway::Resource
|
203 | Properties:
|
204 | ParentId:
|
205 | {{# if firstParent}}
|
206 | Fn::GetAtt:
|
207 | - {{api}}RestApi
|
208 | - RootResourceId
|
209 | {{else}}
|
210 | {{#each parents}}
|
211 | {{this}}
|
212 | {{/each}}
|
213 | {{/if}}
|
214 | PathPart: '{{pathPart}}'
|
215 | RestApiId:
|
216 | Ref: {{api}}RestApi
|
217 |
|
218 | {{/each}}
|
219 |
|
220 |
|
221 | {{#each apis}}
|
222 | {{#ifLogApiGatewayToCloudWatch ../parent.apiConfigs name }}
|
223 |
|
224 |
|
225 | ApiGatewayCloudWatchLogGroup{{name}}:
|
226 | Type: AWS::Logs::LogGroup
|
227 | Properties:
|
228 | LogGroupName:
|
229 | Fn::Join:
|
230 | - ""
|
231 | - - "API-Gateway-Execution-Logs_"
|
232 | - Ref: {{name}}RestApi
|
233 | - "/{{../parent.apiStage}}"
|
234 | RetentionInDays: 30
|
235 |
|
236 | {{#if ../parent.logToSharedDestination }}
|
237 |
|
238 | ApiGatewayLogSubscription{{name}}:
|
239 | Type: AWS::Logs::SubscriptionFilter
|
240 | DependsOn:
|
241 | - ApiGatewayCloudWatchLogGroup{{name}}
|
242 | Properties:
|
243 | DestinationArn: "{{../parent.logToSharedDestination}}"
|
244 | FilterPattern: ""
|
245 | LogGroupName:
|
246 | Ref: ApiGatewayCloudWatchLogGroup{{name}}
|
247 | {{/if}}
|
248 | {{/ifLogApiGatewayToCloudWatch}}
|
249 |
|
250 |
|
251 |
|
252 | {{/each}}
|
253 |
|
254 | {{/if}}
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 | {{#each lambdas}}
|
263 | {{@key}}LambdaFunction:
|
264 | Type: AWS::Lambda::Function
|
265 | Properties:
|
266 | Code:
|
267 | S3Bucket: {{this.bucket}}
|
268 | S3Key: {{this.remote}}
|
269 | FunctionName: {{../stackName}}-{{@key}}
|
270 | Environment:
|
271 | Variables:
|
272 | stackName: {{../stackName}}
|
273 | public_buckets: {{{collectBuckets ../parent.buckets "public"}}}
|
274 | protected_buckets: {{{collectBuckets ../parent.buckets "protected"}}}
|
275 | {{#if this.useElasticSearch }}
|
276 | {{#if ../parent.es.name}}
|
277 | ES_HOST:
|
278 | Ref: ElasticSearchDomain
|
279 | {{/if}}
|
280 | {{/if}}
|
281 | {{# ifEquals this.urs_redirect "token"}}
|
282 | {{# if ../parent.api_backend_url}}
|
283 | TOKEN_REDIRECT_ENDPOINT: {{../parent.api_backend_url}}token
|
284 | {{else}}
|
285 | TOKEN_REDIRECT_ENDPOINT:
|
286 | Fn::Join:
|
287 | - ""
|
288 | - - "https://"
|
289 | - Ref: backendRestApi
|
290 | - ".execute-api."
|
291 | - {"Fn::Sub": "${AWS::Region}"}
|
292 | - ".amazonaws.com"
|
293 | - {{{getApiPortSuffix ../parent.apiConfigs "backend"}}}
|
294 | - "{{../parent.apiStage}}/token"
|
295 | {{/if}}
|
296 | {{/ifEquals}}
|
297 | {{# ifEquals this.urs_redirect "distribution"}}
|
298 | {{# if ../parent.api_distribution_url}}
|
299 | DISTRIBUTION_REDIRECT_ENDPOINT: {{../parent.api_distribution_url}}redirect
|
300 | {{/if}}
|
301 | {{#if ../parent.deployDistributionApi}}
|
302 | DISTRIBUTION_REDIRECT_ENDPOINT:
|
303 | Fn::Join:
|
304 | - ""
|
305 | - - "https://"
|
306 | - Ref: distributionRestApi
|
307 | - ".execute-api."
|
308 | - {"Fn::Sub": "${AWS::Region}"}
|
309 | - ".amazonaws.com"
|
310 | - {{{getApiPortSuffix ../parent.apiConfigs "distribution"}}}
|
311 | - "{{../parent.apiStage}}/redirect"
|
312 | {{/if}}
|
313 | {{/ifEquals}}
|
314 | {{# if this.useDistributionApi}}
|
315 | {{# if ../parent.api_distribution_url}}
|
316 | DISTRIBUTION_ENDPOINT: {{../parent.api_distribution_url}}
|
317 | {{/if}}
|
318 | {{#if ../deployDistributionApi}}
|
319 | DISTRIBUTION_ENDPOINT:
|
320 | Fn::Join:
|
321 | - ""
|
322 | - - "https://"
|
323 | - Ref: distributionRestApi
|
324 | - ".execute-api."
|
325 | - {"Fn::Sub": "${AWS::Region}"}
|
326 | - ".amazonaws.com"
|
327 | - {{{getApiPortSuffix ../parent.apiConfigs "distribution"}}}
|
328 | - "{{../parent.apiStage}}"
|
329 | {{/if}}
|
330 | {{/if}}
|
331 | {{#each this.envs}}
|
332 | {{# if this.function}}
|
333 | {{#if this.array}}
|
334 | {{@key}}:
|
335 | {{this.function}}:
|
336 | {{#each this.array}}
|
337 | - {{this}}
|
338 | {{/each}}
|
339 | {{/if}}
|
340 | {{#if this.value}}
|
341 | {{@key}}:
|
342 | {{this.function}}: {{this.value}}
|
343 | {{/if}}
|
344 | {{else}}
|
345 | {{@key}}: {{{this}}}
|
346 | {{/if}}
|
347 | {{/each}}
|
348 | Handler: {{this.handler}}
|
349 | MemorySize: {{this.memory}}
|
350 | {{# if this.apiRole }}
|
351 | Role: {{../parent.iams.lambdaApiGatewayRoleArn}}
|
352 | {{else if this.distributionRole}}
|
353 | Role: {{../parent.iams.distributionRoleArn}}
|
354 | {{else}}
|
355 | {{#ifEquals @key "executeMigrations"}}
|
356 | Role: {{../parent.iams.migrationRoleArn}}
|
357 | {{/ifEquals}}
|
358 | {{#ifNotEquals @key "executeMigrations"}}
|
359 | Role: {{../parent.iams.lambdaProcessingRoleArn}}
|
360 | {{/ifNotEquals}}
|
361 | {{/if}}
|
362 | Runtime: {{# if this.runtime}}{{this.runtime}}{{else}}nodejs8.10{{/if}}
|
363 | Timeout: {{this.timeout}}
|
364 | Tags:
|
365 | - Key: Project
|
366 | Value: {{../stackName}}
|
367 |
|
368 | {{# if this.launchInVpc }}
|
369 | {{# if ../parent.vpc }}
|
370 | VpcConfig:
|
371 | SecurityGroupIds:
|
372 | - Ref: SecurityGroupId
|
373 | SubnetIds:
|
374 | {{#each ../parent.vpc.subnets}}
|
375 | - {{this}}
|
376 | {{/each}}
|
377 | {{/if}}
|
378 | {{/if}}
|
379 |
|
380 | {{# if this.apiGateway }}
|
381 | {{@key}}LambdaPermissionApiGateway:
|
382 | Type: AWS::Lambda::Permission
|
383 | Properties:
|
384 | Action: lambda:InvokeFunction
|
385 | FunctionName:
|
386 | Fn::GetAtt:
|
387 | - {{@key}}LambdaFunction
|
388 | - Arn
|
389 | Principal: apigateway.amazonaws.com
|
390 | {{/if}}
|
391 |
|
392 | {{# if this.logToElasticSearch }}
|
393 | {{@key}}LogSubscription:
|
394 | Type: AWS::Logs::SubscriptionFilter
|
395 | DependsOn:
|
396 | - {{@key}}LogGroup
|
397 | Properties:
|
398 | DestinationArn:
|
399 | Ref: log2elasticsearchLambdaFunctionArn
|
400 | LogGroupName: '/aws/lambda/{{../stackName}}-{{@key}}'
|
401 | FilterPattern: ""
|
402 |
|
403 | {{@key}}LogGroup:
|
404 | Type: AWS::Logs::LogGroup
|
405 | Properties:
|
406 | LogGroupName: '/aws/lambda/{{../stackName}}-{{@key}}'
|
407 | RetentionInDays: 30
|
408 | {{/if}}
|
409 |
|
410 | {{#if this.logToSharedDestination }}
|
411 |
|
412 | {{@key}}LogSubscriptionToSharedDestination:
|
413 | Type: AWS::Logs::SubscriptionFilter
|
414 | DependsOn:
|
415 | - {{@key}}LogGroup
|
416 | Properties:
|
417 | DestinationArn: "{{this.logToSharedDestination}}"
|
418 | LogGroupName: '/aws/lambda/{{../stackName}}-{{@key}}'
|
419 | FilterPattern: ""
|
420 |
|
421 | {{@key}}LogGroup:
|
422 | Type: AWS::Logs::LogGroup
|
423 | Properties:
|
424 | LogGroupName: '/aws/lambda/{{../stackName}}-{{@key}}'
|
425 | RetentionInDays: 30
|
426 | {{/if}}
|
427 |
|
428 | {{# if this.addLogGroup }}
|
429 | {{@key}}LogGroup:
|
430 | Type: AWS::Logs::LogGroup
|
431 | Properties:
|
432 | LogGroupName: '/aws/lambda/{{../stackName}}-{{@key}}'
|
433 | RetentionInDays: 30
|
434 | {{/if}}
|
435 |
|
436 | {{/each}}
|
437 |
|
438 |
|
439 |
|
440 |
|
441 |
|
442 | Outputs:
|
443 | {{#each apis}}
|
444 | {{name}}RestApiResource:
|
445 | Value:
|
446 | Ref: {{name}}RestApi
|
447 | {{name}}RestApiResourceUrl:
|
448 | Value:
|
449 | Fn::Join:
|
450 | - ""
|
451 | - - "https://"
|
452 | - Ref: {{name}}RestApi
|
453 | - ".execute-api."
|
454 | - {"Fn::Sub": "${AWS::Region}"}
|
455 | - ".amazonaws.com"
|
456 | - {{{getApiPortSuffix ../parent.apiConfigs name}}}
|
457 | - "{{../parent.apiStage}}/"
|
458 | {{/each}}
|