This project demonstrates a serverless architecture using various AWS services to automate email reminders. The solution leverages Amazon Simple Email Service (SES), AWS Lambda, Amazon API Gateway, and AWS Step Functions to create a fully cloud-based workflow. The application runs in the browser, loading from an S3 bucket, and communicates with backend services via an API Gateway. Users can configure reminders for tasks, which are sent via email using SES, triggered by a state machine.
Architecture Diagram:
Stage 1: We verify two email addresses to be used with Amazon Simple Email Service (SES), which starts in sandbox mode to prevent unverified email usage. First, we verify the sending email address (used by the application to send reminders), by adding it in the SES console and confirming the email verification link. Next, we repeat the process to verify the customer email address (used for testing purposes). Both addresses are now whitelisted, enabling the application to send email reminders during testing and later stages of the application workflow.
Stage 2: We create and configure the email_reminder_lambda function, which will send email reminders using Amazon SES. First, an IAM execution role is created via CloudFormation to grant Lambda permissions to interact with SES, SNS, and CloudWatch logs. Then, we create the email_reminder_lambda function using Python in the AWS Lambda console. The function is configured to send emails, and the sender address (from Stage 1) is specified in the function code. Finally, we deploy the function, completing the configuration for sending emails on behalf of the application.
Stage 3: We create and configure the state machine, which manages the workflow of the serverless application. First, we create an IAM role using CloudFormation, which allows the state machine to interact with AWS services like Lambda, SNS, and CloudWatch Logs. Next, we build the state machine in AWS Step Functions using Amazon States Language (ASL) workflow that handles timer-based email reminders. The state machine invokes the previously created email_reminder_lambda function to send emails at scheduled intervals. Once the state machine is configured with the correct permissions, it is ready to coordinate AWS services and manage the flow of the serverless application.
Stage 4: We configure the API Lambda function and create the necessary API Gateway to enable communication between the client-side application and AWS services. First, we create the api_lambda function, which is triggered by API Gateway to initiate the state machine execution, handling the core logic of the application. Next, we set up the API Gateway, defining the API, resources, and methods to handle requests from the client. The API Gateway is linked to the api_lambda function for processing these requests. Finally, the API is deployed to the prod stage in API Gateway, generating an Invoke URL that will be used by the client-side component of the serverless application to interact with the system.
Stage 5: We create and configure the S3 bucket to host the static website for the serverless application. First, we create an S3 bucket and make it public, allowing access to the website files. Next, we enable static website hosting on the bucket and upload the front-end (html, css, js) files. The JavaScript file is updated to include the API Gateway Invoke URL, which enables communication between the static website and the serverless backend. Once the files are uploaded, the application can be tested by entering the required parameters (time, message, and email address), triggering the state machine through API Gateway, and watching the serverless workflow execute in Step Functions. At this point, the fully functional serverless application is running with no servers involved.
At the end of this setup, we have a fully functional serverless application that runs entirely on AWS services without the need for any servers. No servers were harmed, or even used, in this production, justifying the true power and scalability of serverless architecture!