-
Notifications
You must be signed in to change notification settings - Fork 28
/
serverless.example.yml
218 lines (212 loc) · 7.56 KB
/
serverless.example.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
service: stac-server
provider:
name: aws
runtime: nodejs18.x
stage: ${opt:stage, 'dev'}
region: ${opt:region, 'us-west-2'}
# uncomment this if using a bucket that already exists for deployment files
# deploymentBucket:
# name: my-deployment-bucket
logs:
restApi:
executionLogging: false
fullExecutionData: false
accessLogging: false
format: '{"requestId":"$context.requestId","ip":"$context.identity.sourceIp","caller":"$context.identity.caller","useragent" : "$context.identity.userAgent","requestTime":"$context.requestTime","httpMethod":"$context.httpMethod","resourcePath":"$context.resourcePath","status":"$context.status","protocol":"$context.protocol","responseLength":"$context.responseLength"}'
environment:
STAC_ID: "stac-server"
STAC_TITLE: "STAC API"
STAC_DESCRIPTION: "A STAC API using stac-server"
LOG_LEVEL: debug
STAC_DOCS_URL: https://stac-utils.github.io/stac-server/
OPENSEARCH_HOST:
Fn::GetAtt: [OpenSearchInstance, DomainEndpoint]
ENABLE_TRANSACTIONS_EXTENSION: false
OPENSEARCH_CREDENTIALS_SECRET_ID: ${self:service}-${self:provider.stage}-opensearch-user-creds
# comment STAC_API_ROOTPATH if deployed with a custom domain
STAC_API_ROOTPATH: "/${self:provider.stage}"
# PRE_HOOK: ${self:service}-${self:provider.stage}-preHook
# API_KEYS_SECRET_ID: ${self:service}-${self:provider.stage}-api-keys
# POST_HOOK: ${self:service}-${self:provider.stage}-postHook
# If you will be subscribing to post-ingest SNS notifications make
# sure that STAC_API_URL is set so that links are updated correctly
STAC_API_URL: "https://some-stac-server.example.com"
CORS_ORIGIN: "https://ui.example.com"
CORS_CREDENTIALS: true
iam:
role:
statements:
- Effect: Allow
Resource: "arn:aws:es:${aws:region}:${aws:accountId}:domain/*"
Action: "es:*"
- Effect: Allow
Action:
- sqs:GetQueueUrl
- sqs:SendMessage
- sqs:ReceiveMessage
- sqs:DeleteMessage
Resource:
Fn::GetAtt: [ingestQueue, Arn]
- Effect: Allow
Action:
- sns:Publish
Resource:
Fn::GetAtt: [postIngestTopic, TopicArn]
- Effect: Allow
Action: s3:GetObject
Resource: "arn:aws:s3:::usgs-landsat/*"
- Effect: Allow
Resource: arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:${self:provider.environment.OPENSEARCH_CREDENTIALS_SECRET_ID}-*
Action: secretsmanager:GetSecretValue
# - Effect: Allow
# Action: lambda:InvokeFunction
# Resource: arn:aws:lambda:${aws:region}:${aws:accountId}:function:${self:service}-${self:provider.stage}-preHook
# - Effect: Allow
# Action: secretsmanager:GetSecretValue
# Resource: arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:${self:service}-${self:provider.stage}-api-keys-*
# - Effect: Allow
# Action: lambda:InvokeFunction
# Resource: arn:aws:lambda:${aws:region}:${aws:accountId}:function:${self:service}-${self:provider.stage}-postHook
package:
individually: true
functions:
api:
description: stac-server API Lambda
handler: index.handler
package:
artifact: dist/api/api.zip
events:
- http:
method: ANY
path: "/"
cors: true
- http:
method: ANY
path: "{proxy+}"
cors: true
ingest:
description: stac-server Ingest Lambda
handler: index.handler
memorySize: 512
timeout: 60
environment:
POST_INGEST_TOPIC_ARN: !Ref postIngestTopic
package:
artifact: dist/ingest/ingest.zip
events:
- sqs:
arn:
Fn::GetAtt: [ingestQueue, Arn]
# preHook:
# description: stac-server pre-hook Lambda
# handler: index.handler
# memorySize: 512
# timeout: 25
# package:
# artifact: dist/pre-hook/pre-hook.zip
# postHook:
# description: stac-server post-hook Lambda
# handler: index.handler
# memorySize: 512
# timeout: 25
# package:
# artifact: dist/post-hook/post-hook.zip
resources:
Description: A STAC API running on stac-server
Resources:
ingestTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: ${self:service}-${self:provider.stage}-ingest
postIngestTopic:
# After a collection or item is ingested, the status of the ingest (success
# or failure) along with details of the collection or item are sent to this
# SNS topic. To take future action on items after they are ingested
# suscribe an endpoint to this topic
Type: AWS::SNS::Topic
Properties:
TopicName: ${self:service}-${self:provider.stage}-post-ingest
deadLetterQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:service}-${self:provider.stage}-dead-letter-queue
ingestQueue:
Type: AWS::SQS::Queue
Properties:
VisibilityTimeout: 120
ReceiveMessageWaitTimeSeconds: 5
QueueName: ${self:service}-${self:provider.stage}-queue
RedrivePolicy:
deadLetterTargetArn: !GetAtt deadLetterQueue.Arn
maxReceiveCount: 2
ingestQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
Queues:
- !Ref ingestQueue
PolicyDocument:
Statement:
- Sid: allow-sqs-sendmessage
Effect: Allow
Principal:
AWS: "*"
Action: SQS:SendMessage
Resource: !GetAtt ingestQueue.Arn
Condition:
ArnEquals:
aws:SourceArn: !Ref ingestTopic
ingestSubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint: !GetAtt ingestQueue.Arn
Protocol: sqs
Region: "${aws:region}"
TopicArn: !Ref ingestTopic
OpenSearchInstance:
Type: AWS::OpenSearchService::Domain
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
UpdatePolicy:
EnableVersionUpgrade: true
Properties:
DomainName: ${self:service}-${self:provider.stage}
EBSOptions:
EBSEnabled: true
VolumeType: gp3
VolumeSize: 35
ClusterConfig:
InstanceType: t3.small.search
InstanceCount: 1
DedicatedMasterEnabled: false
ZoneAwarenessEnabled: false
EngineVersion: OpenSearch_2.13
DomainEndpointOptions:
EnforceHTTPS: true
NodeToNodeEncryptionOptions:
Enabled: true
EncryptionAtRestOptions:
Enabled: true
AdvancedSecurityOptions:
Enabled: true # enables fine-grained access control
InternalUserDatabaseEnabled: true
# When deploying to a new environment for this first time, the master user
# must be set. Uncomment this, deploy, and then re-comment it before deploying
# again to an existing deployment
MasterUserOptions:
MasterUserName: admin
MasterUserPassword: ${env:OPENSEARCH_MASTER_USER_PASSWORD}
AccessPolicies:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal: { "AWS": "*" }
Action: "es:ESHttp*"
Resource: "arn:aws:es:${aws:region}:${aws:accountId}:domain/${self:service}-${self:provider.stage}/*"
Outputs:
OpenSearchEndpoint:
Value:
Fn::GetAtt: [OpenSearchInstance, DomainEndpoint]
Export:
Name: ${self:service}-${self:provider.stage}-os-endpoint
plugins:
- serverless-offline