Let Them Draw is a fictional app that lets clients specify a desired picture which then gets produced by artists.
Some pictures are easy to produce and are free. Other pictures are more complex and require payment through a Stripe integration.
See this YouTube video for an overview of how it works.
Related Repositories:
Let Them Draw Architecture diagram file
The system behind the Let Them Draw app has 5 main components: the website, the receptionist, the artist, the databases, and the authentication stack.
Website (repository)
The website lets the clients see their orders and request a new picture.
It's built as a static website stored in an S3 bucket and distributed through CloudFront.
The clients sign-in using Cognito.
Receptionist (repository)
The receptionist handles providing a list of existing orders and accepts new requests.
This is accomplished with an API Gateway that forwards requests to a Lambda function which retrieves orders from a database and places new requests into a SQS queue. For requests that require payment, Stripe Checkout is used to handle the payment.
Artist (repository)
The artists take new requests and produce a picture for the client.
A Lambda function takes care of producing the pictures using the SQS queue to retrieve new requests, keeping the related information in the database up-to-date, storing the finished picture in an S3 bucket, and triggers an EventBridge event that in turn uses SNS to notify the client that the picture is ready.
The art database stores information about orders, for example the requirements and the status.
The shape database stores information about the available shapes and their price.
DynamoDB is used for this.
- requestId (primary key)
- userId (secondary key)
- requestDate (date)
- requirements (object (shape, color))
- status (string (new, paid, in progress, done, failed))
- pictureUrl (string)
- checkoutSessionId (string)
Users are limited to only seeing their own pictures by filtering on User Id in addition to the Request Id.
- shape (primary key)
- priceId (string)
- price (string)
Let Them Draw CI/CD Pipeline diagram file
The code that sets up and maintains the infrastructure of the app is configured through 4 pipelines: the main pipeline that sets up the whole AWS infrastructure, two additional pipelines that handle updates to the receptionist and artist components, and one that handles updates to the website. This separation allows independent updates to the infrastructure as needed.
Let Them Draw Monitoring diagram file
A monitoring stack is used to notify about failed pipeline runs or if the artist failed to produce a picture.
- If a queue triggers a lambda function, it's best to attach a dead letter queue to the queue so that the lambda function doesn't keep failing repeatedly and consume resources without producing a result.
- A dead letter queue can be attached to an SNS topic to notify about failed deliveries.
- The keyword "status" is a reserved word in DynamoDB, so it can't be used directly when updating an item. The workaround is to use expression attribute names to map the reserved word to a different name, for example "#status". See also Reserved words in DynamoDB.
- Parameter store are helpful to decouple stacks and break cyclic dependencies.
Based on the AWS Cost Calculator and using a low estimate for everyting, the monthly cost is about 13.51 USD.
The architecture of the app went through a few iterations to add additional features. Here is an animation of how it evolved.
The code of the artist function has tests to verify the funcionality. The code coverage of each succesful build is visualized in a CodeBuild report.
Sent when the artist lambda function fails to produce an image while processing a request.
When any of the build pipelines fail, an alert is sent.
- AWS CLI
- CDK CLI
Setup the GitHub connection:
- Go to the AWS Console
- Navigate to CodeBuild
- Go to Settings and then Connections
- Click on "Create connection"
- Select "GitHub" as the provider
- Set the connection name to "let-them-draw"
- Click "Connect to GitHub"
- Click "Install a new app"
- On GitHub, select the repository and click "Install & Authorize"
- On AWS, click "Connect"
- Copy the connection ARN
- Navigate to Parameter Store
- Click on "Create parameter"
- Set Name to "/let-them-draw/github-connection-arn"
- Paste the copied connection ARN from step 11 into the Value field
- Click on "Create parameter"
Setup the Environment parameter
- Navigate to Parameter Store
- Click on "Create parameter"
- Set Name to "/let-them-draw/environment"
- Set Value to either "dev" or "prod"
- Click on "Create parameter"
Setup the infrastructure-branch parameter
- Navigate to Parameter Store
- Click on "Create parameter"
- Set Name to "/let-them-draw/infrastructure-branch"
- Set Value to either "dev" or "main"
- Click on "Create parameter"
Setup the from-email parameter
- Navigate to Parameter Store
- Click on "Create parameter"
- Set Name to "/let-them-draw/from-email"
- Set Value to an email address that can be verified and will be used as the source address for outgoing emails
- Click on "Create parameter"
Setup the stripe-api-key parameter
- Navigate to Parameter Store
- Click on "Create parameter"
- Set Name to "/let-them-draw/stripe-api-key"
- Set Value to a Stripe API key
- Click on "Create parameter"
Setup the stripe-webhook-secret parameter
- Go to https://docs.stripe.com/
- In the bottom left, click on "Developers", then "Webhooks"
- Click on "Add endpoint"
- In the events filter, type "checkout"
- Select "checkout.session.completed", "checkout.session.expired", "checkout.session.async_payment_succeeded", and "checkout.session.async_payment_failed"
- Click "Continue"
- In the Endpoint URL field, enter the URL of the CloudFront URL and append "/api/stripe-webhook" to it
- Under the Signing secret section, click "Reveal secret"
- Copy the secret
- Navigate to Parameter Store in the AWS Console
- Click on "Create parameter"
- Set Name to "/let-them-draw/stripe-webhook-secret"
- Set Value to the copied secret
- Click on "Create parameter"
Setup the website-url parameter
- Navigate to Parameter Store
- Click on "Create parameter"
- Set Name to "/let-them-draw/website-url"
- Set Value to the "http://localhost:3000" and update it to the CloudFront URL when the website is deployed
- Click on "Create parameter"
Note that when SES is in sandbox mode, every email address needs to be verified. To verify an email address:
- Navigate to Amazon Simple Email Service
- Switch to Identities
- Click on "Create identity"
- Set Identity type to Email address
- Enter the email address
- Click on "Create identity"
- Click on the verification link in the email that was sent
Initialize CDK
cdk bootstrapDeploy all stacks
cdk deploy --all










