This project showcases a fully serverless quiz application designed to demonstrate LocalStack's capabilities in supporting local cloud development, debugging, and testing throughout the entire software development lifecycle (SDLC). The application enables users to create quizzes, participate by submitting answers, and view leaderboards for top scores. It leverages various LocalStack features to highlight the platform's capabilities, including:
- Emulating cloud environments locally with Core Cloud Emulator.
- Utilizing Resource Browsers for inspecting local resources.
- Gaining insights into your development environment with Stack Insights.
- Integrating continuous testing with LocalStack GitHub Actions and SDK.
- Streaming security policies to refine access controls with IAM Policy Stream.
- Managing state snapshots and injecting resource state with Cloud Pods.
- Implementing chaos engineering to test system resilience with Chaos API.
- Utilizing Ephemeral Instances for temporary, isolated testing environments.
- Extending functionality with LocalStack Extensions for enhanced development workflows.
The following resources are being deployed:
- DynamoDB: Stores quiz metadata in
Quizzes
and user data inUserSubmissions
with indexing for leaderboards. - SQS: Manages async submissions via
QuizSubmissionQueue
, with a DLQ for failed messages. - Lambda: Executes serverless functions for creating, submitting, scoring, and fetching quizzes.
- IAM: Defines roles and policies to grant Lambdas and state machines access to necessary resources.
- API Gateway: Exposes REST endpoints for quiz operations, linking HTTP methods to Lambda functions.
- SNS: Sends alerts via
DLQAlarmTopic
and triggersQuizzesWriteFailures
for chaos testing. - EventBridge Pipes: Connects
QuizSubmissionDLQ
to SNS to handle dead-letter queue notifications. - Step Functions: Manages email notification workflows with
SendEmailStateMachine
. - CloudFront: Delivers frontend assets from S3 globally for fast user access.
- S3: Hosts static frontend assets in
webapp
bucket for CloudFront distribution.
Some of the features in this sample app require a LocalStack Pro license - make sure your Auth Token is configured in your terminal session.
Start your LocalStack container with the following configuration:
EXTRA_CORS_ALLOWED_ORIGINS='*' DISABLE_CUSTOM_CORS_APIGATEWAY=1 DISABLE_CUSTOM_CORS_S3=1 localstack start
If you run into specific CORS issues, disable it using a browser extension.
To deploy the app locally, run the following command:
bash bin/deploy.sh
The output will be:
CloudFront URL: https://1e372b81.cloudfront.localhost.localstack.cloud
API Gateway Endpoint: http://localhost:4566/_aws/execute-api/4xu5emxibf/test
Navigate to the CloudFront URL to check out the app. The script would also seed some quiz data and user data to make local testing easier.
To deploy the application to AWS, ensure your account is bootstraped via cdk bootstrap
and then run
AWS_CMD=aws CDK_CMD=cdk bash ./bin/deploy_cdk.sh
Alternatively the application can be deployed to LocalStack via cdklocal
, our wrapper around the AWS CDK. Perform the following steps:
- Bootstrap LocalStack:
cd cdk && cdklocal bootstrap
- Deploy the application:
AWS_CMD=awslocal CDK_CMD=cdklocal bash ./bin/deploy_cdk.sh
Note: while the core quiz application works with CDK, additional features have not been implemented yet.
To run an automated test suite against the local deployment, run the following command:
pip3 install -r tests/requirements-dev.txt
pytest tests/test_infra.py
The automated tests utilize the AWS SDK for Python (boto3) and the requests
library to interact with the Quiz App API. They automate the creation of quizzes, submission of answers, and retrieval of scores and leaderboard details to verify the app's functionality in an end-to-end manner.
While testing your app infrastructure, you can retrieve detailed API telemetry over Stack Insights. This includes:
- Number of API calls
- Service invocations
- User agent (e.g.,
aws-cli
,terraform
) - Specific services called during the instance
- Use the slide toggle to select a time period to view specific API calls
You can use Resource Browser to inspect & manage some of the local resources, such as:
Click on the resources to inspect their configurations and observe how they operate locally with detailed granularity. You can view additional running services on the Status Page. With the exception of EventBridge Pipes and STS, resources for all other services are accessible in a unified view.
To avoid deploying from scratch, you can setup the local development environment using Cloud Pods. To setup the entire stack using Cloud Pods, re-start your LocalStack container:
localstack restart
Run the following command to inject the infrastructure state from Cloud Pods:
localstack pod load serverless-quiz-app
Make sure your Auth Token is in your terminal session. You can get the link to the live app in the following fashion:
DISTRIBUTION_ID=$(awslocal cloudfront list-distributions | jq -r '.DistributionList.Items[0].Id')
echo "https://$DISTRIBUTION_ID.cloudfront.localhost.localstack.cloud"
Your app is now ready to be tested!
After a quiz response is submitted, a Step Functions state machine triggers SES to send an email if an address is provided. To view the email, you can utilize the LocalStack MailHog Extension. Install the MailHog Extension through the Extensions Manager or by using the following command:
localstack extensions install localstack-extension-mailhog
Deploy the stack using the above script or Cloud Pods and submit a quiz response. Visit mailhog.localhost.localstack.cloud:4566 to see an email response with your scores.
Alternatively, you can inspect the SES Developer endpoint for emails in the following manner:
curl -s http://localhost.localstack.cloud:4566/_aws/ses
For testing the app within the GitHub Actions workflow, you can refer to the provided workflow in integration-test.yml
. This workflow utilizes the setup-localstack
action to start LocalStack, deploy the stack, execute tests, and perform final verification. Sample runs are available on the Actions page.
Visit the IAM Policy Stream to view the permissions required for each API call. This feature enables you to explore and progressively enhance security as your application develops.
To get started, restart the LocalStack container using the command localstack restart
and load the Cloud Pod. Then, click on Enable Stream. You can un-select Show internal calls to prevent IAM policies that are unnecessary for the demo.
Toggle Enforce IAM Policies to enable strict IAM enforcement. For demo purpose, the following policy statement has been removed from the configurations/submit_quiz_policy.json
:
{
"Effect": "Allow",
"Action": ["sqs:GetQueueUrl", "sqs:SendMessage"],
"Resource": "arn:aws:sqs:us-east-1:000000000000:QuizSubmissionQueue"
}
Engage with the application or run tests to generate a policy stream for various services. During this process, you may notice some IAM Violations. These are intentionally included to demonstrate how the IAM Policy Stream can be used to test policies in a secure developer setting, helping to identify and resolve missing policies to ensure everything works in production environments.
Find the missing policy statements and fix the IAM Policy on the IAM Resource Browser (for SubmitQuizRole
) or patch it locally and update the policy using AWS CLI.
To experiment with Chaos in your developer environment, visit the Chaos Engineering dashboard. Here, you can inject various chaos scenarios, such as rendering the DynamoDB service unavailable in the us-east-1
region or introducing a 90% occurrence of ProvisionedThroughputExceededException
errors in your DynamoDB calls to observe how the application handles these disruptions.
The application is designed with a robust architectural pattern: if a new quiz is created during a DynamoDB outage, the response is captured in an SNS topic, forwarded to an SQS queue, and then processed by a Lambda function which continues to attempt processing until the DynamoDB table is available again.
To test this pattern, execute the automated test suite with the following command:
pytest tests/test_outage.py
To launch a short-lived, encapsulated deployment of the application on a remote LocalStack instance, you can utilize LocalStack Ephemeral Instances. Execute the following command to create an instance, deploy the resources, and retrieve the application URL:
bash bin/ephemeral.sh
This setup process typically takes about 1-2 minutes. Each Ephemeral Instance will remain active for 2 hours. If continuous availability is required for demo purposes, the instance will need to be recreated every 2 hours.
Alternatively, you can initiate the Ephemeral Instance through the Web App and load the
serverless-quiz-app
Cloud Pod. Note that the frontend of the app depends on local backend APIs (localhost:4566
) and will not function in this remote setup. Future enhancements are planned to address this limitation by allowing the injection of the Ephemeral Instance URL into resources using an environment variable.
You can utilize GitHub Actions to launch an Ephemeral Instance with your app stack deployed, facilitating Application Previews. The process is outlined in the preview.yml
file, which employs the setup-localstack
GitHub Action. For practical implementation, view a sample pull request that demonstrates how this setup can enhance collaboration and facilitate acceptance testing.
Apache License 2.0