This project was provisioned by deploy-stack. It contains a production-ready AWS ECS Fargate architecture and a GitHub Actions deployment pipeline.
This infrastructure provisions a highly available Application Load Balancer (ALB) and an ECS Fargate container (Size: Micro (0.25 vCPU, 512MB RAM)).
- Estimated Monthly Cost: ~$25.00 / month
- Note: AWS bills by the hour. If you destroy this stack after a few hours of testing, it will cost less than $0.20.
⚠️ DISCLAIMER: This cost is a rough estimate. AWS pricing changes and varies by region. You are solely responsible for all AWS charges incurred by deploying this infrastructure. The creators ofdeploy-stackare not liable for unexpected cloud costs, compromised credentials, or runaway billing. Always monitor your AWS Billing Dashboard and set up budget alerts.
-
Initial Provisioning:
cd terraform terraform init terraform apply -
Push Secrets (Optional): If your application requires environment variables, create a local
.envfile and sync it directly to AWS Secrets Manager:npx deploy-stack secrets push .env
-
Automated CI/CD (Keyless via OIDC): Push this repository to GitHub. Your deployment pipeline uses AWS IAM OpenID Connect (OIDC) to authenticate securely with temporary credentials—no long-lived AWS secret keys are required in GitHub Secrets. Every push to
mainwill automatically build, package, and deploy your application.
AWS only permits one GitHub Actions OIDC provider per AWS account. If terraform apply fails with an EntityAlreadyExists error regarding the OIDC provider, it indicates GitHub Actions was previously configured in this account.
The Fix:
Open terraform/oidc.tf and update the default value of create_oidc_provider to false:
variable "create_oidc_provider" {
type = bool
default = false # <--- Change this from true to false
}Re-run terraform apply to link directly to your existing provider.
If you are done testing and want to stop all AWS billing, you must destroy the infrastructure.
Because our Terraform configuration is set to force-delete the ECR image repository (even if images are present), teardown is a single, clean command:
cd terraform
terraform destroyType yes when prompted. This will permanently delete the Load Balancer, ECS cluster, log groups, and associated networking components.
Before you push your code to GitHub, ensure your application is configured to run inside a Docker container and respond to AWS Load Balancer health checks.
AWS constantly pings your container to ensure it is alive. If you configured a custom health check path (e.g., /api/health) during the CLI setup, you must create that route in your application. If AWS receives a 404 Not Found, it will assume your app is broken and terminate the container.
Make sure your app returns a 200 OK at your configured path:
- Next.js (App Router): Create
app/api/health/route.tsreturning a 200 response. - Express.js: Add
app.get('/api/health', (req, res) => res.sendStatus(200)); - FastAPI/Python: Add
@app.get("/api/health")returning a 200 status.
Next.js must be configured in "standalone" mode so it can bundle a minimal Node.js server. Without this, your GitHub Actions Docker build will crash.
Open next.config.js or next.config.ts in your root directory and add output: 'standalone':
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
output: 'standalone', // <--- Add this exact line
};
export default nextConfig;When running inside a Docker container, your server must bind to all network interfaces (0.0.0.0), not just localhost or 127.0.0.1. If you bind to localhost, the AWS Load Balancer will not be able to route traffic to your application.
Make sure your app is configured correctly:
- Express.js:
app.listen(port, '0.0.0.0', () => ...) - FastAPI:
uvicorn.run(app, host="0.0.0.0", port=8000)