This project demonstrates a full Infrastructure-as-Code (IaC) setup using Terraform and GitHub Actions for deploying a simple AWS architecture:
- Backend (Bootstrap): Sets up Terraform state storage and OIDC IAM role for GitHub Actions.
- Main Terraform: Deploys ECS Fargate cluster, ECR repository, and IAM roles.
- CI/CD Integration: Fully automated workflows using GitHub Actions and secure OIDC authentication.
┌─────────────────────────┐
│ Local Scripts │
│------------------------│
│ exporter.sh (.env) │
│ bootstrap.sh │
│ ansible/secrets.yml │
│ push.sh │
└─────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ GitHub Actions CI/CD │
│------------------------│
│ bootstrap.yml │
│ main-terraform.yml │
└─────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ AWS Backend │
│------------------------│
│ S3 Bucket (Terraform) │
│ DynamoDB Table (Lock) │
│ OIDC IAM Role │
│ OIDC Provider (GitHub) │
└─────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ Main Terraform Infra │
│------------------------│
│ ECS Fargate Cluster │
│ ECR Repository │
│ ECS Task IAM Roles │
└─────────────────────────┘
Flow:
- Local scripts load environment, bootstrap AWS backend, and upload secrets.
- Push triggers GitHub Actions workflows.
- Workflows assume OIDC IAM role to deploy main Terraform infrastructure.
The project is organized into three distinct layers:
- Creates S3 bucket and DynamoDB table for Terraform state.
- Provides persistent storage for infrastructure state.
- Configures GitHub OIDC provider and IAM role.
- Enables GitHub Actions to authenticate with AWS without permanent credentials.
- Deploys AWS resources: ECS cluster, ECR repository, ECS task IAM role.
- Uses the bootstrap backend for state management.
- Fully configurable via Terraform variables.
Two GitHub Actions workflows automate deployment:
- Triggered manually.
- Initializes Terraform bootstrap directory.
- Creates backend resources (S3 bucket, DynamoDB table).
- Uses OIDC role for secure AWS access.
- Triggered on pull requests and pushes to
main. - Performs Terraform
init,plan, andapply. - Applies only on main branch; plans run on PRs for review.
- Uses the bootstrap backend and OIDC role.
- No hard-coded AWS credentials; uses OIDC for token-based access.
- Secrets stored in AWS Secrets Manager via Ansible.
- Idempotent and safe to run multiple times.
| Script | Purpose |
|---|---|
bootstrap.sh |
Initializes and applies Terraform OIDC setup; updates GitHub workflow with the bootstrap role ARN automatically. |
ansible/secrets.yml |
Reads .env and uploads sensitive variables to AWS Secrets Manager (Terraform, AWS credentials, app secrets). |
exporter.sh |
Exports .env variables into local environment for use by other scripts. |
push.sh |
Orchestrates the workflow: loads environment, uploads secrets via Ansible, pushes code to GitHub to trigger CI/CD. |
# Load environment variables
source ./exporter.sh
# Bootstrap AWS backend & OIDC
./bootstrap.sh
# Upload secrets to AWS
ansible-playbook ansible/secrets.yml
# Push to GitHub to trigger CI/CD
./push.sh
## Terraform Project Structure
terraform/
├── backend.tf # S3/DynamoDB backend for Terraform
├── main.tf # ECS cluster, ECR repo, IAM roles
├── variables.tf # Variables for main Terraform
├── outputs.tf # Terraform outputs
├── provider.tf # AWS provider configuration
├── bootstrap/
│ └── main.tf # Backend bootstrap (S3 + DynamoDB)
└── oidc-setup/
├── github-oidc-role.tf # IAM role for GitHub Actions OIDC
├── bootstrap-permissions.tf # Policy attachment for bootstrap role
├── oidc-provider.tf # OIDC provider
└── outputs.tf # Outputs bootstrap role ARN
Extensibility
Additional resources (e.g., RDS, S3 buckets, load balancers) can be added without breaking the backend.
IAM roles are modular; additional roles can be created for ECS tasks, Lambda, or other AWS services.
CI/CD workflow supports future scaling and complex deployments.
#### (NOTE): This infrastructure is a foundation prepared for Dockerized apps to run.