{"id":18573130,"url":"https://github.com/localstack-samples/serverless-quiz-app","last_synced_at":"2025-04-10T07:31:51.278Z","repository":{"id":259856574,"uuid":"872385068","full_name":"localstack-samples/serverless-quiz-app","owner":"localstack-samples","description":"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)","archived":false,"fork":false,"pushed_at":"2025-04-09T23:06:38.000Z","size":1572,"stargazers_count":6,"open_issues_count":1,"forks_count":3,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-04-10T00:20:34.673Z","etag":null,"topics":["api-gateway","aws","cloudfront","dynamodb","eventbridge","lambda","localstack","s3","serverless","ses","sns","sqs"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/localstack-samples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-14T10:50:09.000Z","updated_at":"2025-03-03T07:26:21.000Z","dependencies_parsed_at":"2024-10-28T12:55:23.834Z","dependency_job_id":"7c35d742-be2e-4f92-94bd-b1778743ecc9","html_url":"https://github.com/localstack-samples/serverless-quiz-app","commit_stats":null,"previous_names":["localstack-samples/serverless-quiz-app"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack-samples%2Fserverless-quiz-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack-samples%2Fserverless-quiz-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack-samples%2Fserverless-quiz-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack-samples%2Fserverless-quiz-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/localstack-samples","download_url":"https://codeload.github.com/localstack-samples/serverless-quiz-app/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248176388,"owners_count":21060058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-gateway","aws","cloudfront","dynamodb","eventbridge","lambda","localstack","s3","serverless","ses","sns","sqs"],"created_at":"2024-11-06T23:08:07.353Z","updated_at":"2025-04-10T07:31:51.263Z","avatar_url":"https://github.com/localstack-samples.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serverless Quiz App\n\nThis 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).\nThe application enables users to create quizzes, participate by submitting answers, and view leaderboards for top scores.\nIt leverages various LocalStack features to highlight the platform's capabilities, including:\n\n-   Emulating cloud environments locally with **Core Cloud Emulator**.\n-   Utilizing **Resource Browsers** for inspecting local resources.\n-   Gaining insights into your development environment with **Stack Insights**.\n-   Integrating continuous testing with **LocalStack GitHub Actions** and **SDK**.\n-   Streaming security policies to refine access controls with **IAM Policy Stream**.\n-   Managing state snapshots and injecting resource state with **Cloud Pods**.\n-   Implementing chaos engineering to test system resilience with **Chaos API**.\n-   Utilizing **Ephemeral Instances** for temporary, isolated testing environments.\n-   Extending functionality with **LocalStack Extensions** for enhanced development workflows.\n\n## Architecture\n\n![Application Architecture](images/architecture.png)\n\nThe following resources are being deployed:\n\n-   **DynamoDB**: Stores quiz metadata in `Quizzes` and user data in `UserSubmissions` with indexing for leaderboards.\n-   **SQS**: Manages async submissions via `QuizSubmissionQueue`, with a DLQ for failed messages.\n-   **Lambda**: Executes serverless functions for creating, submitting, scoring, and fetching quizzes.\n-   **IAM**: Defines roles and policies to grant Lambdas and state machines access to necessary resources.\n-   **API Gateway**: Exposes REST endpoints for quiz operations, linking HTTP methods to Lambda functions.\n-   **SNS**: Sends alerts via `DLQAlarmTopic` and triggers `QuizzesWriteFailures` for chaos testing.\n-   **EventBridge Pipes**: Connects `QuizSubmissionDLQ` to SNS to handle dead-letter queue notifications.\n-   **Step Functions**: Manages email notification workflows with `SendEmailStateMachine`.\n-   **CloudFront**: Delivers frontend assets from S3 globally for fast user access.\n-   **S3**: Hosts static frontend assets in `webapp` bucket for CloudFront distribution.\n\n## Prerequisites\n\nSome of the features in this sample app require a LocalStack Pro license - make sure your Auth Token is configured in your terminal session.\n\n## Start LocalStack\n\nStart your LocalStack container with the following configuration:\n\n```bash\nlocalstack start\n```\n\nIf you run into specific CORS issues, disable it using a [browser extension](https://webextension.org/listing/access-control.html).\n\n## Local Deployment\n\n### AWS CLI (`awslocal`)\n\nTo deploy the app locally, run the following command:\n\n```bash\nbash bin/deploy.sh\n```\nThe output will be:\n\n```bash \nCloudFront URL: https://1e372b81.cloudfront.localhost.localstack.cloud\nAPI Gateway Endpoint: http://localhost:4566/_aws/execute-api/4xu5emxibf/test\n```\n\nNavigate 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.\n\n\u003c!-- ### CDK (AWS)\n\nTo deploy the application to AWS, ensure your account is bootstraped via `cdk bootstrap` and then run\n\n```bash\nAWS_CMD=aws CDK_CMD=cdk bash ./bin/deploy_cdk.sh\n``` --\u003e\n\n### CDK Local\n\nAlternatively the application can be deployed to LocalStack via `cdklocal`, our wrapper around the AWS CDK. Perform the following steps:\n\n1. Bootstrap LocalStack: `cd cdk \u0026\u0026 cdklocal bootstrap`\n2. Deploy the application: `AWS_CMD=awslocal CDK_CMD=cdklocal bash ./bin/deploy_cdk.sh`\n\n_Note: while the core quiz application works with CDK, additional features have not been implemented yet._\n\n## Local Testing\n\nTo run an automated test suite against the local deployment, run the following command:\n\n```bash\npip3 install -r tests/requirements-dev.txt\npytest tests/test_infra.py\n```\n\nThe 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.\n\n## Stack Insights\n\nWhile testing your app infrastructure, you can retrieve detailed API telemetry over [Stack Insights](https://app.localstack.cloud/stacks). This includes:\n\n-   Number of API calls\n-   Service invocations\n-   User agent (e.g.,  `aws-cli`,  `terraform`)\n-   Specific services called during the instance\n-   Use the slide toggle to select a time period to view specific API calls\n\n## Resource Browser\n\nYou can use Resource Browser to inspect \u0026 manage some of the local resources, such as:\n\n* [DynamoDB](https://app.localstack.cloud/inst/default/resources/dynamodb)\n* [Lambda](https://app.localstack.cloud/inst/default/resources/lambda/functions) \n* [API Gateway](https://app.localstack.cloud/inst/default/resources/apigateway)\n\nClick 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](https://app.localstack.cloud/inst/default/status). With the exception of EventBridge Pipes and STS, resources for all other services are accessible in a unified view.\n\n## Cloud Pods\n\nTo 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:\n\n```bash \nlocalstack restart\n```\n\nRun the following command to inject the infrastructure state from Cloud Pods:\n\n```bash \nlocalstack pod load serverless-quiz-app\n```\n\nMake sure your Auth Token is in your terminal session. You can get the link to the live app in the following fashion:\n\n```bash\nDISTRIBUTION_ID=$(awslocal cloudfront list-distributions | jq -r '.DistributionList.Items[0].Id')\necho \"https://$DISTRIBUTION_ID.cloudfront.localhost.localstack.cloud\"\n```\n\nYour app is now ready to be tested!\n\n## Extensions\n\nAfter 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](https://pypi.org/project/localstack-extension-mailhog/). Install the MailHog Extension through the [Extensions Manager](https://app.localstack.cloud/inst/default/extensions/manage) or by using the following command:\n\n```bash \nlocalstack extensions install localstack-extension-mailhog\n```\n\nDeploy the stack using the above script or Cloud Pods and submit a quiz response. Visit [**mailhog.localhost.localstack.cloud:4566**](https://mailhog.localhost.localstack.cloud:4566/) to see an email response with your scores.\n\nAlternatively, you can inspect the SES Developer endpoint for emails in the following manner:\n\n```bash \ncurl -s http://localhost.localstack.cloud:4566/_aws/ses\n```\n\n## Continuous Integration\n\nFor testing the app within the GitHub Actions workflow, you can refer to the provided workflow in [`integration-test.yml`](.github/workflows/integration-test.yml). This workflow utilizes the [`setup-localstack`](https://github.com/localstack/setup-localstack) action to start LocalStack, deploy the stack, execute tests, and perform final verification. Sample runs are available on the [Actions page](https://github.com/localstack-samples/serverless-quiz-app/actions/workflows/integration-test.yml).\n\n## IAM Policy Stream\n\nVisit the [IAM Policy Stream](https://app.localstack.cloud/inst/default/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.\n\nTo 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. \n\nToggle **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`:\n\n```json\n{\n    \"Effect\": \"Allow\",\n    \"Action\": [\"sqs:GetQueueUrl\", \"sqs:SendMessage\"],\n    \"Resource\": \"arn:aws:sqs:us-east-1:000000000000:QuizSubmissionQueue\"\n}\n```\n\nEngage 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.\n\nFind the missing policy statements and fix the IAM Policy on the [IAM Resource Browser](https://app.localstack.cloud/inst/default/resources/iam/roles) (for `SubmitQuizRole`) or patch it locally and update the policy using AWS CLI. \n\nHere is a [tutorial](https://blog.localstack.cloud/generating-testing-iam-policies-locally-with-localstack/) showcasing how you can do the above!\n\n## Chaos Engineering\n\nTo experiment with Chaos in your developer environment, visit the [Chaos Engineering dashboard](https://app.localstack.cloud/chaos-engineering). 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.\n\nThe 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.\n\nTo test this pattern, execute the automated test suite with the following command:\n\n```bash\npytest tests/test_outage.py\n``` \n\n## Ephemeral Instance\n\nTo 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:\n\n```bash\nbash bin/ephemeral.sh\n```\n\nThis 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.\n\n\u003e 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.\n\nYou 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`](.github/workflows/preview.yml) file, which employs the [`setup-localstack`](https://github.com/localstack/setup-localstack) GitHub Action. For practical implementation, view a [sample pull request](https://github.com/localstack-samples/serverless-quiz-app/pull/3) that demonstrates how this setup can enhance collaboration and facilitate acceptance testing.\n\n## License\n\nApache License 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalstack-samples%2Fserverless-quiz-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flocalstack-samples%2Fserverless-quiz-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalstack-samples%2Fserverless-quiz-app/lists"}