Deploy Laravel applications on AWS Lambda using Terraform. Zero server management, pay-per-request pricing, automatic scaling.
┌─────────────────┐
│ CloudFront │
│ (CDN + SSL) │
└────────┬────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ /build/* │ │ /css/* │ │ Everything │
│ /js/* │ │ /images/* │ │ else │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────┐ ┌───────────────┐
│ S3 Bucket │ │ API Gateway │
│ (Static Assets) │ │ HTTP API │
└───────────────────────────────┘ └───────┬───────┘
│
▼
┌───────────────┐
│ Lambda │
│ (PHP + Bref) │
└───────┬───────┘
│
┌───────────────────────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────┐
│ SQS │ │ RDS │ │ ... │
│ (Job Queue) │ │ (MySQL) │ │ │
└───────────────┘ └───────────────┘ └───────┘
- Multi-site support - Deploy multiple Laravel apps with one configuration
- Automatic scaling - Lambda scales to handle any traffic
- Zero servers - No EC2, no patching, no maintenance
- Queue processing - SQS integration with worker Lambda
- Static assets - S3 + CloudFront for CSS/JS/images
- Database - Connects to existing RDS instance
- Artisan commands - Dedicated Lambda for running artisan
- AWS account with appropriate permissions
- Terraform >= 1.0
- Existing VPC with private subnets (for RDS access)
- Existing RDS MySQL instance
- Domain managed in Route 53 or external DNS
-
Copy example configuration
cp terraform.tfvars.example terraform.tfvars
-
Edit terraform.tfvars with your values:
- VPC and subnet IDs
- RDS endpoint and credentials
- Site configuration (domain, database name, APP_KEY)
-
Initialize and apply
terraform init terraform plan terraform apply
-
Add DNS validation records (output after apply)
-
Deploy your Laravel code to the Lambda function
sites = {
my_app = {
name = "my-app"
domain = "app.example.com"
domain_aliases = ["www.app.example.com"]
db_name = "my_app_db"
app_key = "base64:..."
lambda_memory = 1024 # Optional, default 1024
lambda_timeout = 28 # Optional, max 28 for API Gateway
worker_memory = 512 # Optional
worker_timeout = 120 # Optional, max 900
enabled = true
}
}Add any environment variables your app needs:
custom_env_vars = {
MAIL_MAILER = "ses"
STRIPE_KEY = "sk_live_xxx"
PUSHER_APP_ID = "123456"
}Lambda functions are created with placeholder code. Deploy your actual Laravel app using:
Option 1: AWS CLI
cd your-laravel-app
zip -r deployment.zip . -x "*.git*" "node_modules/*" "tests/*"
aws lambda update-function-code \
--function-name my-app-web \
--zip-file fileb://deployment.zipOption 2: CI/CD Pipeline (recommended)
Set up GitHub Actions, GitLab CI, or AWS CodePipeline to deploy on push.
Your Laravel app needs these settings for Lambda:
LOG_CHANNEL=stderr
CACHE_DRIVER=array
SESSION_DRIVER=database
QUEUE_CONNECTION=sqsAdd to AppServiceProvider.php:
public function boot(): void
{
if ($this->app->environment('production') && env('APP_URL')) {
URL::forceRootUrl(env('APP_URL'));
URL::forceScheme('https');
}
}Typical costs for a low-traffic Laravel app:
| Resource | Monthly Cost |
|---|---|
| Lambda (1M requests) | ~$0.20 |
| API Gateway (1M requests) | ~$1.00 |
| CloudFront (10GB transfer) | ~$0.85 |
| S3 (1GB storage) | ~$0.02 |
| Total | ~$2-5/month |
Does not include RDS costs (shared with other apps)
After terraform apply:
cloudfront_domains- CloudFront URLs and distribution IDsapi_gateway_urls- Direct API Gateway endpointslambda_functions- Lambda function names (web, worker, artisan)sqs_queues- SQS queue URLscertificate_validation_records- DNS records for SSL validation
aws lambda invoke \
--function-name my-app-artisan \
--payload '{"command": "migrate --force"}' \
response.json