Skip to content

Commit c3e92cc

Browse files
author
Phil Varner
committed
add example permissions for post-ingest, add documentation for enabling post-ingest
1 parent 856f1b4 commit c3e92cc

File tree

4 files changed

+74
-26
lines changed

4 files changed

+74
-26
lines changed

README.md

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- [Migration](#migration)
99
- [0.x or 1.x -\> 2.x](#0x-or-1x---2x)
1010
- [Fine-grained Access Control](#fine-grained-access-control)
11+
- [Enabling Post-ingest SNS publishing](#enabling-post-ingest-sns-publishing)
1112
- [0.4.x -\> 0.5.x](#04x---05x)
1213
- [Elasticsearch to OpenSearch Migration](#elasticsearch-to-opensearch-migration)
1314
- [Preferred Elasticsearch to OpenSearch Migration Process](#preferred-elasticsearch-to-opensearch-migration-process)
@@ -135,6 +136,47 @@ As of 2.0.0, only OpenSearch is supported and only using fine-grained access con
135136
It is recommended to follow the migration path to upgrade to fine-grained access control
136137
first and then upgrade to stac-server 2.x.
137138

139+
#### Enabling Post-ingest SNS publishing
140+
141+
stac-server now has the ability to publish all ingested entities (Items and Collections)
142+
to an SNS topic. Follow these stesp to add this to an exisiting deployment. These
143+
configurations are also in the serverless.example.yml file, so reference that if it is
144+
unclear exactly where to add this in your config.
145+
146+
Explicitly set the provider/environment setting for STAC_API_URL so the ingested entities
147+
published to the topic will have their link hrefs set correctly. If this is not set,
148+
the entities will still be published, with with incorrect link hrefs.
149+
150+
```text
151+
STAC_API_URL: "https://some-stac-server.com"
152+
```
153+
154+
Add the SNS topic resource:
155+
156+
```text
157+
postIngestTopic:
158+
Type: AWS::SNS::Topic
159+
Properties:
160+
TopicName: ${self:service}-${self:provider.stage}-post-ingest
161+
```
162+
163+
For the `ingest` Lambda resource definition, configure the ARN to publish to by adding:
164+
165+
```text
166+
environment:
167+
POST_INGEST_TOPIC_ARN: !Ref postIngestTopic
168+
```
169+
170+
Add IAM permissions with the statement:
171+
172+
```text
173+
- Effect: Allow
174+
Action:
175+
- sns:Publish
176+
Resource:
177+
Fn::GetAtt: [postIngestTopic, TopicArn]
178+
```
179+
138180
### 0.4.x -> 0.5.x
139181

140182
#### Elasticsearch to OpenSearch Migration
@@ -521,11 +563,9 @@ aws lambda invoke \
521563
/dev/stdout
522564
```
523565

524-
Stac-server is now ready to ingest data!
525-
526566
#### OpenSearch fine-grained access control
527567

528-
As of version 2.0.0, stac-server on"ly supports fine-grained access control to
568+
As of version 2.0.0, stac-server only supports fine-grained access control to
529569
OpenSearch, and no longer supports "AWS Connection" mode.
530570

531571
**Warning**: Unfortunately, fine-grained access control cannot be enabled on an
@@ -634,8 +674,8 @@ so that stac-server can access them.
634674
The preferred mechanism for populating the OpenSearch credentials to stac-server is to
635675
create a secret in AWS Secret Manager that contains the username and password. The
636676
recommended name for this Secret corresponds
637-
to the stac-server deployment as `{stage}/{service}/opensearch`, e.g.,
638-
`dev/my-stac-server/opensearch`.
677+
to the stac-server deployment as `${service}-${stage}-opensearch-user-creds`, e.g.,
678+
`my-stac-server-dev-opensearch-user-creds`.
639679

640680
The Secret type should be "Other type of secret" and
641681
have two keys, `username` and `password`, with the appropriate
@@ -645,14 +685,14 @@ Add the `OPENSEARCH_CREDENTIALS_SECRET_ID` variable to the serverless.yml sectio
645685
`environment`:
646686

647687
```yaml
648-
OPENSEARCH_CREDENTIALS_SECRET_ID: ${self:provider.stage}/${self:service}/opensearch
688+
OPENSEARCH_CREDENTIALS_SECRET_ID: ${self:service}-${self:provider.stage}-opensearch-user-creds
649689
```
650690

651691
Add to the IAM Role Statements:
652692

653693
```yaml
654-
- Effect: "Allow"
655-
Resource: "arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:${self:provider.stage}/${self:service}/opensearch-*"
694+
- Effect: Allow
695+
Resource: arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:${self:provider.environment.OPENSEARCH_CREDENTIALS_SECRET_ID}-*
656696
Action: "secretsmanager:GetSecretValue"
657697
```
658698

@@ -674,6 +714,8 @@ OPENSEARCH_PASSWORD: xxxxxxxxxxx
674714
Setting these as environment variables can also be useful when running stac-server
675715
locally.
676716

717+
Stac-server is now ready to ingest data!
718+
677719
### Proxying Stac-server through CloudFront
678720

679721
The API Gateway URL associated with the deployed stac-server instance may not be the URL that you ultimately wish to expose to your API users. AWS CloudFront can be used to proxy to a more human readable URL. In order to accomplish this:

serverless.example.yml

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,25 @@ provider:
2929
iam:
3030
role:
3131
statements:
32-
- Effect: "Allow"
32+
- Effect: Allow
3333
Resource: "arn:aws:es:${aws:region}:${aws:accountId}:domain/*"
3434
Action: "es:*"
35-
- Effect: "Allow"
35+
- Effect: Allow
3636
Action:
3737
- sqs:GetQueueUrl
3838
- sqs:SendMessage
3939
- sqs:ReceiveMessage
4040
- sqs:DeleteMessage
4141
Resource:
4242
Fn::GetAtt: [ingestQueue, Arn]
43+
- Effect: Allow
44+
Action:
45+
- sns:Publish
46+
Resource:
47+
Fn::GetAtt: [postIngestTopic, Arn]
4348
- Effect: Allow
4449
Action: s3:GetObject
45-
Resource: 'arn:aws:s3:::usgs-landsat/*'
50+
Resource: "arn:aws:s3:::usgs-landsat/*"
4651
- Effect: Allow
4752
Resource: arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:${self:provider.environment.OPENSEARCH_CREDENTIALS_SECRET_ID}-*
4853
Action: secretsmanager:GetSecretValue
@@ -107,14 +112,14 @@ resources:
107112
Description: A STAC API running on stac-server
108113
Resources:
109114
ingestTopic:
110-
Type: "AWS::SNS::Topic"
115+
Type: AWS::SNS::Topic
111116
Properties:
112117
TopicName: ${self:service}-${self:provider.stage}-ingest
113118
postIngestTopic:
114-
# After a collection or item is ingested, the status of the ingest (success
115-
# or failure) along with details of the collection or item are sent to this
116-
# SNS topic. To take future action on items after they are ingested
117-
# suscribe an endpoint to this topic
119+
# After a collection or item is ingested, the status of the ingest (success
120+
# or failure) along with details of the collection or item are sent to this
121+
# SNS topic. To take future action on items after they are ingested
122+
# suscribe an endpoint to this topic
118123
Type: AWS::SNS::Topic
119124
Properties:
120125
TopicName: ${self:service}-${self:provider.stage}-post-ingest
@@ -156,7 +161,7 @@ resources:
156161
TopicArn: !Ref ingestTopic
157162
OpenSearchInstance:
158163
Type: AWS::OpenSearchService::Domain
159-
DeletionPolicy : Retain
164+
DeletionPolicy: Retain
160165
UpdateReplacePolicy: Retain
161166
UpdatePolicy:
162167
EnableVersionUpgrade: true
@@ -187,13 +192,13 @@ resources:
187192
MasterUserOptions:
188193
MasterUserName: admin
189194
MasterUserPassword: ${env:OPENSEARCH_MASTER_USER_PASSWORD}
190-
AccessPolicies:
191-
Version: "2012-10-17"
192-
Statement:
193-
- Effect: "Allow"
194-
Principal: { "AWS": "*" }
195-
Action: "es:ESHttp*"
196-
Resource: "arn:aws:es:${aws:region}:${aws:accountId}:domain/${self:service}-${self:provider.stage}/*"
195+
AccessPolicies:
196+
Version: "2012-10-17"
197+
Statement:
198+
- Effect: "Allow"
199+
Principal: { "AWS": "*" }
200+
Action: "es:ESHttp*"
201+
Resource: "arn:aws:es:${aws:region}:${aws:accountId}:domain/${self:service}-${self:provider.stage}/*"
197202
Outputs:
198203
OpenSearchEndpoint:
199204
Value:

src/lambdas/ingest/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const handler = async (event, _context) => {
5353

5454
if (event.create_indices) {
5555
await createIndex('collections')
56+
return
5657
}
5758

5859
const stacItems = isSqsEvent(event)

src/lib/ingest.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ export async function convertIngestObjectToDbObject(
2828
index = data.collection
2929
} else {
3030
throw new InvalidIngestError(
31-
`Expeccted data.type to be "Collection" or "Feature" not ${data.type}`
31+
`Expected data.type to be "Collection" or "Feature" not ${data.type}`
3232
)
3333
}
3434

3535
// remove any hierarchy links in a non-mutating way
3636
if (!data.links) {
37-
throw new InvalidIngestError('Expected a "links" proporty on the stac object')
37+
throw new InvalidIngestError('Expected a "links" property on the stac object')
3838
}
3939
const links = data.links.filter(
4040
(/** @type {{ rel: string; }} */ link) => !hierarchyLinks.includes(link.rel)

0 commit comments

Comments
 (0)