Inspired by isitsnowinginpdx.com βοΈ
See blog post for more details π
A serverless weather reporting website that answers a single question: "Is it [condition] in [location]?" with a simple YES/NO response π―
This automated workflow:
- π Gets the current website status for a specified location
- π€οΈ Hits the OpenWeatherMap API to get current weather conditions
- π If the status has changed β updates the website with new weather conditions
- β° Runs automatically on a schedule via EventBridge Scheduler
My deployment of this site is here π
π΄ When the weather is happening (YES!):
π’ When the weather is NOT happening (Nope!):
- πͺ£ S3 - Static website hosting
- π CloudFront - Global CDN distribution
- β‘ Lambda - HTML generation and site updates (ARM64)
- π Step Functions - Orchestrates weather checks and updates
- β° EventBridge Scheduler - Triggers checks every 10 minutes
- π Systems Manager Parameter Store - Stores current site status
- π Secrets Manager - Stores OpenWeatherMap API key
- π CloudWatch - Alarm for monitoring Step Function failures
- π§ SNS - Optional email notifications (only when
ALERT_EMAIL
is configured)
- π Route53 - DNS hosted zone management
- π Certificate Manager - SSL certificates for HTTPS
- β©οΈ CloudFront Function - www β non-www redirects
- π’ Runtime: Node.js (version in
.nvmrc
) - π Language: TypeScript with strict configuration
- ποΈ Infrastructure: AWS CDK v2 for Infrastructure as Code
- π€οΈ API: OpenWeatherMap One Call API 3.0

Works out of the box with a CloudFront-generated domain (e.g., d123456789.cloudfront.net
) β¨
Requires additional domain stack deployed to us-east-1
region for SSL certificates π
- π’ Install Node.js (see
.nvmrc
for required version) - βοΈ Install AWS CLI and configure credentials
- π Get an API key from OpenWeatherMap
-
π₯ Clone the repository
-
π Create a Secret in AWS Secrets Manager:
- Name:
weather-site-api-key
- Value: Your OpenWeatherMap API key (plaintext)
- Name:
-
βοΈ Copy
.env.example
to.env
and configure:cp .env.example .env
- Set required variables:
WEATHER_LOCATION_LAT
,WEATHER_LOCATION_LON
,LOCATION_NAME
, etc. - Optionally set
ALERT_EMAIL
for email notifications when site status changes or system failures occur π§ - Leave
DOMAIN_NAME
empty for basic deployment
- Set required variables:
-
π¦ Install dependencies:
npm install
-
π€ Set AWS profile (optional):
export AWS_PROFILE=<your_aws_profile>
npm run deploy
The CloudFront URL will be output to the console π
us-east-1
region first!
- π Set
DOMAIN_NAME
in your.env
file - π Deploy domain stack to us-east-1:
npm run deploy -- --region us-east-1 --exclusively "*-domain"
- βοΈ Deploy weather stack to your preferred region:
npm run deploy -- --region us-west-2 --exclusively "*-weather"
- If your domain is not hosted in Route53, point your nameservers to Route53 (instructions) π
- For non-Route53 domains: Update nameservers quickly after domain stack deployment starts to prevent certificate validation failures β‘
- π Domain Stack: Must deploy to
us-east-1
(CloudFront SSL certificate requirement) π - βοΈ Weather Stack: Can deploy to any AWS region π
- π Route53 hosted zone for your domain
- π SSL certificates for both
example.com
andwww.example.com
- βοΈ CloudFront distribution with custom domain
- β©οΈ Automatic
www
β non-www redirect - π DNS A records pointing to CloudFront
- π DNS validation can take up to 30 minutes
- π Monitor AWS Console for certificate status
- β‘ Ensure nameservers are updated promptly for external domains
# Step 1: π Deploy domain resources (us-east-1 required)
npm run deploy -- --region us-east-1 --exclusively "myStack-domain"
# Step 2: βοΈ Deploy main application (any region)
npm run deploy -- --region us-west-2 --exclusively "myStack-weather"
npm run build # π¨ Compile TypeScript
npm run test # π§ͺ Run Jest tests
npm run format # β¨ Format code with Prettier
npm run lint # π Lint code with ESLint
npm run synth # π Generate CloudFormation templates
npm run diff # π Preview infrastructure changes
npm run deploy # π Interactive deployment
npm run deploy:ci # π€ CI/CD deployment (no prompts)
npm run destroy # π₯ Delete all stacks
Configure in .env
file:
- π
WEATHER_LOCATION_LAT
/WEATHER_LOCATION_LON
- Coordinates for weather checks - π·οΈ
LOCATION_NAME
- Display name for the location - π¦οΈ
WEATHER_TYPE
- Condition to check (snow, rain, etc.) - β°
SCHEDULES
- Cron expressions for check frequency - π·οΈ
STACK_PREFIX
- Prefix for all AWS resources - π
DOMAIN_NAME
- Optional custom domain - π§
ALERT_EMAIL
- Optional email for notifications when site status changes or system failures occur
Basic CDK snapshot tests are in the test/
folder:
npm run test
The weather site supports optional email notifications for two scenarios:
When the weather condition status changes (e.g., from "NO" to "YES" or vice versa), you'll receive an email notification with the new status.
If the Step Function fails (e.g., API errors, deployment issues), you'll receive CloudWatch alarm notifications.
-
Add your email address to the
.env
file:ALERT_EMAIL=your-email@example.com
-
Deploy the app:
npm run deploy
Or deploy the weather stack separately:
npm run cdk deploy -- --exclusively "*-weather"
-
Important: You will receive one confirmation email from AWS SNS that you must confirm by clicking the link. This single topic handles both status change notifications and system failure alerts.
- π§ SNS Topic - Handles email delivery (only when
ALERT_EMAIL
is set) - π CloudWatch Alarm - Monitors Step Function failures (always created, alarm action only when
ALERT_EMAIL
is set) - π¬ Email Subscription - Sends notifications to your specified email
To stop receiving emails:
- Remove
ALERT_EMAIL
from.env
- Redeploy the weather stack:
npm run deploy
This removes the SNS topic and alarm action, stopping all email notifications. The CloudWatch alarm remains for monitoring purposes.
To delete all resources:
npm run destroy
ποΈ Manually delete the weather-site-api-key
secret from AWS Secrets Manager.
See CONTRIBUTING.md for more info on our guidelines.