Bootstrap a AWS service with its ressources with SST
Follow the steps below to get started with the project.
typescript, nodejs, npm, gradle, smithy-vs code extension
install the dependencies
npm i
to generate the code, run the following command in the root directory of the project:
npm run codegen
add the profile innfactory-demo
into your aws config/credentials file in ~/.aws/
- Use
aws configure sso
to start the profile setup - As start URL set the URL shown in IAM Identity Provider (the url to the AWS access portal) and SSO Region to
eu-central-1
- (If already configured skip to step 4) You will be promted to verify your identity in your browser, select the profile that is authorized the aws account.
NOTE: If your microsoft isn't set to remember your login it might falsely select an unauthorized account.
- Select the aws account and role that you want to setup, make sure to name the profile
innfactory-demo
- run
npm run login
add the secrets mentioned in services/common/secretmanager/domain/models/secrets.ts
into the secretsmanager of your aws account
npm run start
If this is the first time. SST will prompt you to set a local stage name.
Enter a name to identify YOUR stage and press enter.
This will create a new stack in the AWS account.
You can change the stack name in the .sst
Folder in the stage
File.
All endpoints are secured by a cognito authorizer.
If you don't have a user create one via the aws cognito console or the cli and set your password (and thereby your account status to Comfirmed
) with the command npx aws cognito-idp admin-set-user-password --user-pool-id <your cognito user pool id> --username <your registered email> --password <your password> --permanent --profile innfactory-demo
. Thereafter create a file cognitoAuth.json
beneath the package.json
of the backend project containing the following json:
{
"UserPoolId": "your cognito user pool id",
"ClientId": "your cognito client id",
"AuthFlow": "ADMIN_USER_PASSWORD_AUTH",
"AuthParameters": {
"USERNAME": "your email",
"PASSWORD": "your password"
}
}
Thereafter use the idToken
of the response of the command npm run login:cognito
as bearer token with any query (copy the values of the base environment of insomnia into a private environment).
This service heavily uses some libraries you might want to learn more about
- SST - a fullstack application framework to build apps on AWS, based on CDK
- smithy - a interface definition language
- fp-ts - typed function programming for typescript
Smithy API models are defined in ./smithy-codegen/model/
. Generated code can be found in ./smithy-codegen/build/smithyprojections/smithy-codegen/source/typescript-ssdk-codegen/src/models
. Generated OpenAPI spec can be found in smithy-codegen/build/smithyprojections/smithy-codegen/source/openapi/
. Use the OpenAPI spec to generate a client e.g. for postman.
AWS Ressources are defined in ./stacks/
using SST and/or CDK. Entrypoint of the SST Application is ./sst.config.ts
- Definition of the api gateway(s) with its routes and lambda handlers
- As an example you can find a api gateway v1, which is used for REST endpoints
- Api gateway v2 is a HTTP and web socket api gateway
- Defines the (encrypted) tables of dynamoDb
- Manages the available KMS Keys
- Allows to create multiple cognito instances, differentiated by a predefined id
- Authorization via custom lambda handler
services/functions/auth/application/handler/cognitoLambdaAuthorizer.ts
to authenticate a user in one of many cognito instances - Example interactions with Cognito are found in
services/functions/users/infrastructure/cognitoRepository.ts
- Add the
userPoolIdEnvs
to the environment of a lambda handler to receive the cognito user pool id inCognitoRepository
- Add the
- Registers pre and post authentication lambda handlers to manage failed login attempts
- pre: increments counter and blocks requests if above threshold
- post: resets counter after successful login
- remove them or reset counter e.g. after change of password -> refer to
setPassword
inservices/functions/users/domain/services/userServiceImpl.ts
- Creates cloudwatch alarms and registers them to a sns topic
- The lambda handler of the sns topic sends the alarm to registered webhooks
- The webhooks are read from a aws secret which has to be of the format of
services/functions/alarms/domain/models/alarmRecipients.ts
- Currently there is only an implementation for teams webhooks
- The webhooks are read from a aws secret which has to be of the format of
- It is also possible to register a sns topic to the aws chatbot. The aws chatbot can format alarms and send them to registered webhooks
- Creates SQS Queues
Source code for the lambda handlers can be found in ./services/functions/
and ./services/common/
. Entrypoints of handlers are always located in ./services/functions/<domain_object>/application/handler/
where <domain_object>
stands for the name of a domain object.
- API Logic / Entrypoint
- Handlers for SQS Messages, refer to
./services/functions/users/application/handler/deleteByQueue.ts
for an example
Business Logic
Abstraction Logic to external services, like third party APIs, databases, auth providers etc.
Logging, Tracing and Metrics are done with AWS Powertools
Testing is done via SST and vitest. Tests are located at ./services/test/
.
Deploy a test stage
npm run deploy:test
Run the tests
npm run test
In this project migrations are one time jobs, typically executed right after a successful deployment. A migration could for example edit DynamoDB table fields or files in S3. To trigger the migrations use the api endpoint (refer to the smithy model or the ApiStack to find the endpoint) secured by a api key. Examine ./services/functions/migrations
and ./services/test/migrations
for better understanding.
Use the following command in your pipe to trigger the migration after a successful deploy
- on your dev/staging/production systems:
curl --fail-with-body -X POST '<replace with api url>/v1/migrations' -H "Authorization: $(aws secretsmanager get-secret-value --secret-id migrations-api-key | jq -r '.SecretString | fromjson | .apiKey')"
- on your test systems
curl --fail-with-body -X POST '<replace with api url>/v1/migrations' -H "Authorization: test-api-key"
-> Adjust the urls in the steps Trigger migration on
in the deployment worfklow in .github/workflows/deployment.yml
CDK is ramping up assets in S3 with each deploy which won't be deleted automatically. Refer to this issue for further information about the difficulties of deleting CDK assets and to track a future built in feature. This app makes use of a 3. party tool called Toolkit cleaner to determine and delete old and unused CDK assets. It is initialized in CdkAssetsCleanupStack. Deploy it once per AWS Account. Either as scheduled job or execute it manually as needed in the cloud console via the step function menu.
Opt out of anonymous telemetry collection: npx sst telemetry disable