A complete infrastructure-as-code project demonstrating automated deployment of a static website to AWS S3 using Terraform, with CI/CD pipelines via GitHub Actions and remote state management in Terraform Cloud.
graph TB
GitHub[GitHub Repository] --> GitHubActions[GitHub Actions]
GitHubActions --> TerraformCloud[Terraform Cloud]
TerraformCloud --> AWS[AWS Infrastructure]
subgraph AWS [AWS Services]
S3[S3 Bucket]
CloudFront[CloudFront CDN]
ACM[ACM Certificate]
end
User[End User] --> CloudFront
CloudFront --> S3
AWS-S3-Static-Website/
├── .github/
│ └── workflows/
│ ├── deploy.yml # Deployment pipeline
│ └── destroy.yml # Destruction pipeline
├── modules/
│ └── s3-website/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
│ └── prod/
│ └── ...
├── website/
│ ├── index.html
│ ├── styles.css
│ └── script.js
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── backend.tf
└── README.md
- ✅ Infrastructure as Code - Complete Terraform configuration
- ✅ CI/CD Pipelines - GitHub Actions for automated deployments
- ✅ Remote State Management - Terraform Cloud for state storage
- ✅ Modular Design - Reusable Terraform modules
- ✅ Multi-environment - Dev/Prod environment support
- ✅ CloudFront CDN - Global content delivery
- ✅ HTTPS Encryption - SSL/TLS with ACM certificates
- ✅ Custom Domain - Route53 DNS configuration
- ✅ Cost Optimization - S3 + CloudFront cost-effective hosting
- Terraform - Infrastructure as Code
- AWS Services - S3, CloudFront, ACM, Route53, IAM
- GitHub Actions - CI/CD Pipelines
- Terraform Cloud - Remote State Management
- HTML/CSS/JS - Static Website Content
Before you begin, ensure you have:
- AWS Account with appropriate permissions
- Terraform Cloud Account for state management
- GitHub Account for repository and actions
- Domain Name (optional) for custom domain setup
git clone https://github.com/tasnimmizaoui/AWS-S3-Static-Website-.git
cd AWS-S3-Static-Website- Create Terraform Cloud account at app.terraform.io
- Create a new organization
- Generate an API token: Settings > Tokens > Create API Token
- Store token in GitHub Secrets as
TF_API_TOKEN
Create IAM user with required permissions:
# Minimum required policies:
- AmazonS3FullAccess
- CloudFrontFullAccess
- AmazonRoute53FullAccess
- AWSCertificateManagerFullAccess
- IAMReadOnlyAccessStore credentials in GitHub Secrets:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY
Navigate to: Repository Settings > Secrets > Actions
Add the following secrets:
TF_API_TOKEN- Terraform Cloud API tokenAWS_ACCESS_KEY_ID- AWS IAM access keyAWS_SECRET_ACCESS_KEY- AWS IAM secret key
Update backend.tf with your Terraform Cloud details:
terraform {
backend "remote" {
organization = "your-organization-name"
workspaces {
name = "aws-s3-website"
}
}
}- Navigate to Actions tab in your repository
- Select "Deploy Infrastructure" workflow
- Click "Run workflow"
- Select branch and environment
- Monitor the execution progress
Push to main branch triggers automatic deployment:
git add .
git commit -m "Deploy website updates"
git push origin mainWarning: This will delete all AWS resources!
- Navigate to Actions > Destroy Infrastructure
- Click "Run workflow"
- Confirm destruction (requires manual approval if configured)
- Module-based architecture for reusability
- Remote state management with Terraform Cloud
- Variable validation and type constraints
- Output values for cross-module communication
- Environment separation using workspaces or directories
- S3 static website hosting configuration
- CloudFront distribution for CDN and HTTPS
- Route53 DNS management with Terraform
- ACM certificate provisioning and validation
- IAM policies for least privilege access
- GitHub Actions workflows for automation
- Environment protection and approval processes
- Artifact management for plan files
- Secret management with GitHub Secrets
- Concurrency control to prevent conflicts
- Terraform validation and format checking
- Plan review process before apply
- Destruction safeguards with manual approval
- Logging and output for debugging
- State recovery procedures
| Metric | Value | Description |
|---|---|---|
| Deployment Time | ~5-7 minutes | Full infrastructure creation |
| Cost Estimate | < $1/month | S3 storage + CloudFront requests |
| Availability | 99.9% | Global CDN distribution |
| SSL Rating | A+ | TLS 1.2+ with modern ciphers |
- IAM Least Privilege - Minimal required permissions
- SSL Encryption - HTTPS only traffic
- S3 Bucket Policies - Block public access except through CloudFront
- GitHub Secrets - Secure credential storage
- Terraform Cloud - Secure state management
module "website" {
source = "./modules/s3-website"
domain_name = "yourdomain.com"
create_dns = true
create_cert = true
enable_cdn = true
}# environments/dev/terraform.tfvars
bucket_name = "dev-website-bucket"
domain_name = "dev.yourdomain.com"
environment = "development"- name: Upload Website Files
run: |
aws s3 sync ./website s3://${{ steps.terraform-output.outputs.bucket_name }} \
--delete \
--cache-control "max-age=31536000"-
"Required token could not be found"
- Solution: Ensure
TF_API_TOKENis set in GitHub Secrets
- Solution: Ensure
-
"No valid credential sources found"
- Solution: Check AWS credentials in GitHub Secrets
-
"Error: Failed to get existing workspaces"
- Solution: Create workspace manually in Terraform Cloud first
-
"S3 bucket name already exists"
- Solution: Use unique bucket names across AWS
# Check Terraform configuration
terraform validate
terraform fmt -check
# Plan without applying
terraform plan -out=tfplan
# Show current state
terraform show
# List resources
terraform state list- Terraform AWS Provider Documentation
- GitHub Actions Documentation
- Terraform Cloud Documentation
- AWS S3 Static Website Hosting
This project demonstrates modern infrastructure automation practices combining Terraform, AWS, and GitHub Actions. It provides a production-ready template for static website hosting with best practices for security, cost optimization, and maintainability.
⭐ If you found this project helpful, please give it a star on GitHub!