Homework series for CPSC 5910 Cloud Computing Seattle University
By Lynn Trickey with assistance from Cursor AI agent
Changed since last homework submission
- Added DynamoDB tables for sales records
- Added API in inventory_api to record sales from store POS systems
- Added view in employee_site to set up reports to run
- Added Lambda to generate repts under report_lambda
- Added EventBridge to schedule runing reports lambda
- Added S3 Config to save & load past reports
-
Follow pre-deployment setup instructions to set SSH key and AWS credentials (if not already set)
-
Make sure Docker Desktop is running
-
Deploy app to AWS:
cd /infrastructure terraform init terraform apply(See Deployment Process for more detailed instructions)
-
Once deployment is complete, Create user in Cognito User pool for new Employee website, submitting an email to create a user with.
cd .. # go to root directory ./scripts/create_employee_user.sh --email <ENTER YOUR EMAIL HERE>
Output should look like this:
User created successfully! Username: your_email Email: your_email Temporary password: j8@wVFbN0j7T Status: FORCE_CHANGE_PASSWORD -
Use the temporary password to login at the employee site url (part of terraform outputs). It should be in this format:
employee_site_url = "http://product-catalogue-test-employee-site-<aws_account_id>.s3-website-us-east-1.amazonaws.com" -
Once logged in, choose the 'reports' tab at the top of the page
-
Click add new schedule
-
Setup a report to run every minute (filtered by store or category)
-
Run the traffic generator to create some sales. Each call picks a random store, fetches its in-stock inventory, and submits a basket of 1–3 random items. All stores and products are eligible on every run; with enough calls (e.g.
--calls 50across 5 stores) coverage is well-distributed.
# Default: 20 calls at 2/sec
./scripts/traffic_generator.sh
# Custom rate and call count
./scripts/traffic_generator.sh --calls 50 --rate 5- Run restock if needed Resets inventory quantities after the traffic generator depletes stock.
# Restock all items to 500 units (default)
./scripts/restock.sh
# Restock only depleted items (quantity <= 10)
./scripts/restock.sh --low-only --threshold 10-
Verify API Gateway endpoints still work (previous assignment, optional)
cd .. # go to root directory ./scripts/test_api_gateway.sh
Everything below must be installed and configured on your local machine for the deployment and scripts to work.
- AWS credentials — Set as environment variables or in
~/.aws/credentials. See Pre-Deployment Setup and Getting AWS Credentials. - Terraform — Used by
terraform applyand by scripts that read Terraform outputs. - AWS CLI — Used by deploy scripts,
create_employee_user.sh,seed_dynamodb.sh, and others. Configure with the same credentials as above. - Node.js 18+ and npm — Used to build the customer and employee React frontends during deploy.
- jq — Required by
seed_dynamodb.sh(and by Terraform-triggered seeding duringterraform apply). - Docker Desktop — Must be installed and running. Used to build and push container images to ECR for the customer and employee sites.
- SSH key — Required for Inventory API EC2 deployment and for
check_status.sh/check_and_seed_db.sh. See SSH Key Setup.
Optional for some scripts: Python 3 (e.g. for test_api_gateway.sh and manual Inventory API packaging).
macOS (Homebrew):
brew install jqWindows (PowerShell as Administrator):
- Using Chocolatey:
choco install jq - Using winget:
winget install jq.jq - Or download the Windows binary from jqlang.github.io/jq and add the folder containing
jq.exeto your PATH.
Linux:
- Debian/Ubuntu:
sudo apt-get update && sudo apt-get install -y jq - RHEL/CentOS/Fedora:
sudo yum install -y jqorsudo dnf install -y jq - Arch:
sudo pacman -S jq
Verify: jq --version
macOS:
- Download the appropriate installer (Apple Silicon or Intel) from Docker Desktop for Mac.
- Open the
.dmg, drag Docker to Applications, then open Docker from Applications. Allow privileged helper when prompted. - Ensure Docker is running (whale icon in the menu bar) before running
terraform applyor deploy scripts.
Windows:
- Download the installer from Docker Desktop for Windows. You need WSL 2; the installer can enable it.
- Run the installer, restart if asked, then start “Docker Desktop” from the Start menu.
- Ensure Docker is running before
terraform applyor deploy scripts.
Linux:
- Follow Install Docker Engine for your distribution. For the full Desktop experience (GUI), use Docker Desktop for Linux.
- Start the Docker service (e.g.
sudo systemctl start dockeror start Docker Desktop) before running Terraform or deploy scripts.
Verify: docker run hello-world
- Terraform: Install Terraform — e.g. macOS:
brew install terraform; Windows:choco install terraformor download the binary. - AWS CLI: Install or update the AWS CLI — e.g. macOS:
brew install awscli; Windows:msiinstaller orpip install awscli. - Node.js: Node.js downloads (LTS 18+). macOS:
brew install node; Windows: use the installer orwinget install OpenJS.NodeJS.LTS.
AWS Credentials and SSH Key are required to run Terraform Deployment
Before running Terraform, you need to configure your AWS credentials and SSH key. If you're using temporary credentials (common with AWS Academy/AWS Educate), you'll need to set three environment variables:
AWS Academy/AWS Educate:
- Download the credentials CSV file from your AWS Academy account
- The file contains: Access Key ID, Secret Access Key, and Session Token
Either set with export, or configure in ~./aws/credentials file like so:
[default]
aws_access_key_id = YOUR_AWS_KEY_ID
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
aws_session_token = YOUR_SESSION_TOKEN_HEREFor temporary credentials (Access Key starts with "ASIA"):
export AWS_ACCESS_KEY_ID="your-access-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
export AWS_SESSION_TOKEN="your-session-token"For permanent credentials:
export AWS_ACCESS_KEY_ID="your-access-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
# AWS_SESSION_TOKEN not needed for permanent credentialsCheck if your credentials are set:
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
echo $AWS_SESSION_TOKEN # Only needed for temporary credentialsNote: Temporary credentials expire. If you get "InvalidClientTokenId" errors, you may need to download fresh credentials from AWS Academy.
To deploy to EC2 instances, you need an SSH key pair. The Terraform configuration uses the key name specified in infrastructure/variables.tf (default: vockey).
-
Download the private key file:
- Download
vockey.pem(or your key pair's.pemfile) from AWS Academy or AWS Console - Save it to
~/.ssh/vockey.pem
- Download
-
Set correct permissions:
chmod 600 ~/.ssh/vockey.pemImportant: SSH requires private key files to have permissions
0600(readable/writable by owner only). If permissions are too open (e.g.,0644), SSH will refuse to use the key and you'll get a "Permission denied" error. -
Verify permissions:
ls -l ~/.ssh/vockey.pemShould show:
-rw-------(owner read/write only)
Troubleshooting:
- If you get "WARNING: UNPROTECTED PRIVATE KEY FILE!" or "bad permissions", run
chmod 600 ~/.ssh/vockey.pem - If you download a new key file, remember to set permissions again
- Make sure the key name in Terraform variables matches your actual key name in AWS
For local development, both the Flask WebApp and FastAPI Inventory Service can run without DynamoDB by using JSON seed files from the seed_data/ directory.
Both services include .env files for local development configuration:
Flask WebApp (server/.env):
# Disable DynamoDB for local development (use JSON seed files instead)
USE_DYNAMODB=0
# Point Flask to the FastAPI inventory service for stock/sales data
INVENTORY_API_BASE_URL=http://127.0.0.1:9000FastAPI Inventory Service (inventory_api/.env):
# Disable DynamoDB for local development (use JSON seed files from ../seed_data instead)
USE_DYNAMODB=0Both services automatically load their respective .env files if python-dotenv is installed (included in requirements.txt). You don't need to manually export these variables unless you prefer not to use the .env files.
1. Start the FastAPI Inventory Service:
cd inventory_api
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -r requirements.txt # Includes python-dotenv
# The .env file will be loaded automatically
# Run the service
uvicorn main:app --reload --port 9000The inventory API will read from ../seed_data/products_by_store.json when USE_DYNAMODB=0.
2. Start the Flask WebApp:
In a separate terminal:
cd server
python -m venv .venv # If you haven't already
source .venv/bin/activate
pip install -r requirements.txt # Install Flask dependencies (includes python-dotenv)
# The .env file will be loaded automatically by Flask
# Run Flask (adjust command based on how you start Flask)
python app.py
# or: flask run --port 8000The Flask app will:
- Read products and stores from
../seed_data/products.jsonand../seed_data/stores.json - Forward stock/sales requests to the FastAPI inventory service at
http://127.0.0.1:9000
3. Start the React Frontend (optional for full-stack testing):
cd site
npm install
npm run devThe React app will connect to Flask at http://localhost:8000.
- Seed data location: All seed data files (
products.json,stores.json,products_by_store.json,categories.json) are located at the repo root inseed_data/(moved fromserver/seed_data/). - No AWS credentials needed: When
USE_DYNAMODB=0, neither service requires AWS credentials or DynamoDB access. - Service communication: Flask calls the FastAPI inventory service for all stock/sales data. Make sure the inventory service is running before starting Flask.
Customer Site:
React SPA (S3) → Flask API (ECS Fargate / Docker) → DynamoDB
→ Inventory API (EC2)
→ S3 Product Images
Employee Site:
React SPA (S3) → Flask BFF (ECS Fargate / Docker) → Customer API (ECS Fargate)
→ Inventory API (EC2)
Inventory API:
FastAPI (EC2) → DynamoDB
Public API:
API Gateway → Inventory API (EC2)
The following must be installed and available on the machine running terraform apply:
- Docker Desktop — must be running. Docker is used to build and push container images to ECR for both the customer and employee sites.
- Node.js 18+ — used to build the React frontends before uploading to S3.
- AWS CLI — configured with valid credentials (
~/.aws/credentials). For Learner Lab, re-copy credentials each session. - Terraform — the infrastructure is defined in
infrastructure/. - SSH Key — required for deploying the Inventory API to its EC2 instance (see SSH Key Setup).
cd infrastructure
terraform init # first time only
terraform apply # builds, packages, and deploys everythingYou will need to input yes to allow terraform apply to make the required changes.
- Creates AWS infrastructure (ECS Fargate clusters, ALBs, ECR, S3 buckets, EC2 for Inventory API, DynamoDB, API Gateway, Cognito, etc.)
- Uploads product images to S3
- Deploys the Inventory API to EC2 via SCP
- Seeds DynamoDB tables with product data
- Builds the Customer API Docker image locally and pushes to ECR
- Builds the Customer React frontend and uploads to S3
- Deploys customer ECS service
- Builds the Employee BFF Docker image locally and pushes to ECR
- Builds the Employee React frontend and uploads to S3
- Deploys employee ECS service
| Script | Purpose |
|---|---|
deploy_customer_site.sh |
Builds Customer API Docker image, pushes to ECR, builds React frontend, uploads to S3, redeploys ECS |
deploy_employee_site.sh |
Builds Employee BFF Docker image, pushes to ECR, builds React frontend, uploads to S3, redeploys ECS |
seed_dynamodb.sh |
Seeds DynamoDB tables with product data |
upload_images_to_s3.sh |
Uploads product images to S3 |
package_inventory_api.sh |
Packages Inventory API for EC2 deployment |
deploy_inventory_api_remote.sh |
Deploys Inventory API to EC2 |
Access the applications:
terraform output customer_site_url # Customer site (S3 static website)
terraform output customer_api_alb_url # Customer API (ALB)
terraform output employee_site_url # Employee site (S3 static website)
terraform output employee_bff_alb_url # Employee BFF API (ALB)Fully Automated: Tables are automatically seeded during terraform apply from seed_data/ directory on your local machine. No manual steps required.
What Gets Seeded:
- 100 products
- 5 stores
- 85 inventory items (products by store)
- 64 categories
Manual Re-seeding (optional, only if you need to reset data):
INFRASTRUCTURE_DIR=./infrastructure ./scripts/seed_dynamodb.shNote: Seeding runs automatically whenever DynamoDB tables are created or recreated by Terraform.
- Back up the old state (just in case):
cp infrastructure/terraform.tfstate infrastructure/terraform.tfstate.old-lab cp infrastructure/.terraform.lock.hcl infrastructure/.terraform.lock.hcl.bak 2>/dev/null || true
- Delete the stale state:
rm -f infrastructure/terraform.tfstate rm -f infrastructure/terraform.tfstate.backup rm -rf infrastructure/.terraform