This project describes how to set up a complete AWS-based raffle application using DynamoDB, Lambda, API Gateway, mTLS, and S3 + CloudFront hosting.
Table name: raffle
Partition key: email
Table class: Standard-IA (Infrequent Access)
Each participant record contains:
| Attribute | Type | Description |
|---|---|---|
email |
String | The participant’s email address (unique identifier) |
name |
String | The participant’s full name |
phone |
String | The participant’s phone number |
won |
String | Indicates if the participant has won |
Create an IAM role that allows Lambda functions to access DynamoDB and CloudWatch Logs with the following managed policies:
AmazonDynamoDBFullAccess_v2AWSLambdaDynamoDBExecutionRoleAWSLambdaInvocation-DynamoDBCloudWatchLogsFullAccess
Use Node.js 22.x runtime. After creation, reduce the timeout to 1 second except with draw having a 3 seconds timeout.
| Function | Description |
|---|---|
apply |
Accepts participant details and adds a new item to the raffle table |
count |
Retrieves the total number of participants in the table |
draw |
Randomly selects three participants and updates their won field to mark them as winners |
For each function, create appropriate test cases to validate behavior and edge cases.
(Optional) Create a custom domain, e.g. faresahmed.link.
- Generate an HTTPS certificate using AWS Certificate Manager (ACM) for
api.faresahmed.link. - Validate it using DNS.
Create an HTTP API named raffle, add the Lambda functions as integrations, and configure routes as follows:
| Method | Path | Integration |
|---|---|---|
POST |
/apply |
raffle_apply |
GET |
/count |
raffle_count |
GET |
/draw |
raffle_draw |
Enable Auto-Deploy on the default stage.
- Add custom domain
api.faresahmed.linkand attach the previously created certificate. - In Route53, create a new record for
api.faresahmed.linkas an Alias to the API Gateway domain. - Back in API Gateway, create an API Mapping to map the domain to the
raffleAPI, optionally under the path/raffle.
Test your API:
curl https://api.faresahmed.link/raffle/countExpected output: the number of participants in the DynamoDB table.
Follow AWS’s mTLS setup guide.
- Create a Root CA certificate and client certificates.
- Upload
RootCA.pemto an S3 bucket. - In API Gateway, enable mTLS on your custom domain by providing the S3 URI for
RootCA.pem. - Disable the default API endpoint (
API: raffle) as prompted. - Wait for the update to complete.
After enabling mTLS, browsers or clients without the client certificate will be rejected.
Test using curl:
curl --key my_client.key --cert my_client.pem https://api.faresahmed.link/raffle/countAdd the client certificate to your browser to test secure access. Reference: aboutssl.org/ssl-guide
Follow the S3 Static Website Hosting Guide.
-
Create an S3 bucket for your frontend.
-
Enable Static Website Hosting, with the index document set to
apply.html. -
Allow public access and add a bucket policy to permit read access to all files.
-
Create a CloudFront distribution:
- Origin: the S3 bucket.
- Domain name:
faresahmed.link - Certificate: use one created in us-east-1 for TLS.
After deployment, create a DNS record in Route53 pointing your domain name to the CloudFront distribution.
To allow your frontend domain to call the API, add the following origins to your API Gateway’s CORS settings:
https://faresahmed.link
https://www.faresahmed.link
Set them under Access-Control-Allow-Origin.
