Deploy your site to AWS S3 and CloudFront
Deploying Content
Deploy your built site to AWS using the astrolock deploy command.
Warning
Infrastructure must exist first. See Site Provisioning.
You’ll need:
- Deployer credentials (from site provisioning)
- AWS CLI configured with correct profile
- Deployment target in
.astrolock/astrolock.yaml
Deployment Configuration
Add your deployment target to .astrolock/astrolock.yaml:
deploy:
default: "production"
targets:
production:
platform: "aws"
url: "https://www.example.com"
aws:
profile: "www.example.com" # AWS CLI profile name
bucket: "www.example.com" # S3 bucket name
region: "us-east-1" # AWS region
cloudfront_distribution: "E123ABC" # CloudFront distribution ID (optional)
staging:
platform: "aws"
url: "https://staging.example.com"
aws:
profile: "staging.example.com"
bucket: "staging.example.com"
region: "us-east-1"
cloudfront_distribution: "E456DEF"
Tip
Get these values from your Terraform output: cd terraform/astrolock_site && make info
Deploying Your Site
First Deployment
# 1. Build production site
astrolock build
# 2. Preview deployment (dry-run)
astrolock deploy production
# 3. Deploy for real
astrolock deploy production --execute
Updating Your Site
# Quick deploy (if already built)
astrolock deploy production --skip-build --execute
# Full rebuild + deploy
astrolock build && astrolock deploy production --execute
Multiple Environments
# Deploy to staging
astrolock deploy staging --execute
# Deploy to production
astrolock deploy production --execute
What Happens During Deployment
- Build Check: Ensures
dist/exists (or runs build if needed) - AWS Validation: Checks AWS CLI profile and credentials
- S3 Sync: Uploads files to S3 bucket
- CloudFront Invalidation: Clears CDN cache (if distribution ID provided)
- Verification: Confirms deployment succeeded
AWS CLI Profile Setup
If you don’t have AWS credentials configured yet:
# Get credentials from deployer package (generated during site setup)
# See: terraform/astrolock_site/make deployer-package
# Configure AWS CLI profile
aws configure --profile www.example.com
# AWS Access Key ID: [from deployer package]
# AWS Secret Access Key: [from deployer package]
# Default region: us-east-1
# Default output format: json
# Test credentials
aws sts get-caller-identity --profile www.example.com
Warning
Use the deployer credentials (limited S3/CloudFront access), NOT the provisioner credentials (full infrastructure access).
CI/CD Deployment
GitHub Actions
name: Deploy to AWS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy
run: |
npm install -g astrolock
astrolock build
astrolock deploy production --execute
Required Secrets (Settings → Secrets):
AWS_ACCESS_KEY_ID- From deployer packageAWS_SECRET_ACCESS_KEY- From deployer package
Deployment Options
Dry Run (Default)
Preview what would be deployed without making changes:
astrolock deploy production
Shows:
- Files to upload
- Files to delete
- CloudFront invalidation plan
Execute Deployment
astrolock deploy production --execute
Skip Build
If you’ve already built the site:
astrolock deploy production --skip-build --execute
Troubleshooting
Issue: An error occurred (AccessDenied) when calling the PutObject operation
Fix:
# Verify correct profile
aws sts get-caller-identity --profile www.example.com
# Check credentials in ~/.aws/credentials
cat ~/.aws/credentials | grep -A3 www.example.comIssue: Old content still visible after deployment
Cause: CloudFront caching (can take 5-15 minutes)
Fix:
# Manual invalidation
aws cloudfront create-invalidation \
--distribution-id E123ABC \
--paths "/*" \
--profile www.example.comIssue: The config profile (www.example.com) could not be found
Fix:
# List configured profiles
aws configure list-profiles
# Add missing profile
aws configure --profile www.example.comIssue: Bucket in wrong region
Fix: Update .astrolock/astrolock.yaml with correct region:
aws:
region: "us-west-2" # Match your bucket's regionCost Optimization
Typical monthly cost for a small site (1GB, 10k visitors):
- S3 storage: ~$0.03
- S3 requests: ~$0.01
- CloudFront: ~$0.86
- Total: ~$0.90/month
Free tier benefits (first 12 months):
- 5GB S3 storage
- 20,000 GET requests
- 50GB data transfer out via CloudFront
Security Best Practices
- Use deployer credentials - Limited S3/CloudFront access only
- Rotate access keys - Every 90 days
- Enable CloudTrail - Audit all deployments
- Use HTTPS only - CloudFront enforces this automatically
- Separate environments - Different buckets for staging/production
Next Steps
Automate deployments with CI/CD.