AWS Cloud Practitioner — Lab 03 of 08

Lab 03 — Serverless Contact Form

Build a working serverless contact form using Lambda, API Gateway, and SES.

Beginner+~$0 Free Tier2–4 HoursRequires Lab 01

Lab Overview

PREREQ: Complete Lab 01 before this lab. You need an existing S3 website to add the form to.

Build a working contact form that emails submissions directly to your inbox. The entire backend runs serverlessly — no web server, no database, no monthly idle cost. Lambda runs only when someone submits the form.

ServicePurposeFree Tier
Amazon SESSends email when the form is submitted62,000 emails/mo free
AWS LambdaRuns your Python code to process the form submission1M requests/mo free
Amazon API GatewayCreates the HTTPS endpoint the form posts to1M calls/mo free
AWS IAMRole granting Lambda permission to send via SESAlways free

Step-by-Step Instructions

1
Amazon SES
Verify Your Email Address

SES requires you to verify an email address before you can send from it in sandbox mode.

  1. Search for SES (Simple Email Service) and click it
  2. In the left sidebar click Verified identities
  3. Click Create identity
  4. Identity type: Email address
  5. Enter your email address and click Create identity
  6. Open your inbox and click the verification link from AWS
  7. Return to SES — status should now show Verified
2
AWS IAM
Create the Lambda Execution Role
  1. Search for IAM and click it
  2. Left sidebar → RolesCreate role
  3. Trusted entity: AWS service → Use case: Lambda → Next
  4. Search for and attach AmazonSESFullAccess
  5. Search for and attach AWSLambdaBasicExecutionRole
  6. Role name: LambdaSESRoleCreate role
3
AWS Lambda
Create the Lambda Function
  1. Search for Lambda and click it
  2. Click Create functionAuthor from scratch
  3. Function name: ContactFormHandler
  4. Runtime: Python 3.12
  5. Execution role: Use an existing role → select LambdaSESRole
  6. Click Create function
  7. Delete all existing code and paste the code below
  8. Replace both email addresses with your verified SES email
  9. Click Deploy
import json
import boto3

ses = boto3.client('ses', region_name='us-east-1')

SENDER_EMAIL    = 'your-verified@email.com'  # replace
RECIPIENT_EMAIL = 'your-verified@email.com'  # replace

def lambda_handler(event, context):
    try:
        body    = json.loads(event.get('body', '{}'))
        name    = body.get('name', 'Unknown')
        email   = body.get('email', 'Unknown')
        message = body.get('message', 'No message')

        ses.send_email(
            Source=SENDER_EMAIL,
            Destination={'ToAddresses': [RECIPIENT_EMAIL]},
            Message={
                'Subject': {'Data': f'New contact from {name}'},
                'Body': {'Text': {'Data':
                    f'Name: {name}\\nEmail: {email}\\nMessage: {message}'
                }}
            }
        )
        return {
            'statusCode': 200,
            'headers': {'Access-Control-Allow-Origin': '*'},
            'body': json.dumps({'message': 'Email sent!'})
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'headers': {'Access-Control-Allow-Origin': '*'},
            'body': json.dumps({'error': str(e)})
        }
4
Amazon API Gateway
Create the API Endpoint
  1. Search for API Gateway and click it
  2. Click Create APIHTTP API → Build
  3. Add integration → Lambda → select ContactFormHandler
  4. API name: ContactFormAPI → Next
  5. Method: POST → Resource path: /contact → Next
  6. Stage name: prod → Next → Create
  7. Copy the Invoke URL (shown on the summary page)
  8. Go to CORS in the sidebar → Allow-Origin: * → Allow-Methods: POST, OPTIONS → Save
5
Amazon S3
Add the Contact Form to Your Website

Create a contact.html file and upload it to your S3 bucket. Replace YOUR_API_URL with your Invoke URL from Step 4.

<!DOCTYPE html>
<html><head><meta charset="UTF-8"/><title>Contact</title></head>
<body>
  <h1>Contact Us</h1>
  <label>Name</label>
  <input type="text" id="name"/>
  <label>Email</label>
  <input type="email" id="email"/>
  <label>Message</label>
  <textarea id="msg"></textarea>
  <button onclick="send()">Send</button>
  <p id="status"></p>
  <script>
    const API = 'YOUR_API_URL/contact';
    async function send() {
      const r = await fetch(API, { method:'POST',
        headers:{'Content-Type':'application/json'},
        body: JSON.stringify({
          name: document.getElementById('name').value,
          email: document.getElementById('email').value,
          message: document.getElementById('msg').value
        })
      });
      const d = await r.json();
      document.getElementById('status').textContent = d.message || d.error;
    }
  </script>
</body></html>
6
Web Browser
Test the Contact Form
  1. Open your S3 website and navigate to contact.html
  2. Fill in your name, your verified SES email, and a test message
  3. Click Send
  4. Check your inbox — the email should arrive within seconds
TIP: If the form hangs, check API Gateway → CORS settings and Lambda → CloudWatch Logs for errors.

Verification Checklist

What You Learned

Lab Cleanup

IMPORTANT: Delete these resources when finished.
#ResourceHow to Delete
1API GatewayAPI Gateway → ContactFormAPI → Actions → Delete
2LambdaLambda → ContactFormHandler → Actions → Delete
3IAM RoleIAM → Roles → LambdaSESRole → Delete
4S3 contact.htmlS3 → your bucket → contact.html → Delete