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