An internal application platform deployed on AWS EC2 using Terraform and Ansible, with strong emphasis on network isolation, zero-trust access, and policy-as-code enforcement across infrastructure and CI.
The platform runs a FastAPI backend and React frontend in Docker containers across multiple EC2 instances, fronted by an internal load balancer and accessible only through a WireGuard VPN.
Modern internal platforms must be secure by default, auditable, and fully automated.
This project demonstrates how to build a locked-down internal application platform on AWS, where:
- No application is publicly exposed
- Infrastructure changes are policy-validated
- CI pipelines use short-lived credentials
- Configuration management is reproducible and idempotent
It mirrors real-world enterprise patterns for internal tooling, admin platforms, and private services.
- Internal-only application access via WireGuard VPN
- Infrastructure provisioning using Terraform
- Configuration management with Ansible (roles & templates)
- Containerized workloads using Docker and Docker Compose
- Internal load balancing with Nginx
- Policy as Code enforcement for IaC and CI
- Secure CI using GitHub OIDC
Developer
↓
GitHub Actions (OIDC)
↓
Terraform + Policy Checks
↓
AWS Infrastructure (VPC, EC2, ALB, RDS)
↓
Ansible Configuration
↓
Dockerized Applications on EC2
Client
↓
WireGuard VPN
↓
Internal Application Load Balancer
↓
Nginx (Internal Routing)
↓
FastAPI / React Containers
↓
RDS (PostgreSQL)
- Applications are deployed behind an internal Application Load Balancer
- No public ingress to application EC2 instances
- Access is restricted to users connected via WireGuard VPN
- WireGuard runs on a dedicated EC2 instance
- FastAPI backend and React frontend run in Docker containers
- Two EC2 instances host application workloads
- Nginx acts as an internal reverse proxy and load balancer
- Hostname-based routing is used for services
Ansible is used to:
- Install Docker and Docker Compose on EC2 instances
- Deploy and manage application containers
- Configure Nginx with templated configs
- Run database migrations from EC2 instances
- Set up WireGuard server and generate client keys
- Enforce consistency using roles and templates
Ansible communicates with EC2 instances using AWS Systems Manager (SSM) instead of SSH. This allows configuration management without opening inbound management ports or distributing SSH keys.
Connections are authenticated using IAM roles attached to the EC2 instances.
- GitHub Actions uses OIDC to assume AWS IAM roles
- No long-lived AWS credentials stored in CI
- AWS Secrets Manager is used to securely fetch Terraform secrets
- Checkov for static Terraform/IaC scanning
- OPA to validate Terraform plan files before apply
- Prevents insecure or non-compliant infrastructure changes
- Semgrep for static application code analysis
- OWASP Dependency Check for vulnerable dependencies
- Trivy for container image vulnerability scanning after build
- No public application endpoints
- VPN-only access via WireGuard
- Internal ALB and private networking
EC2 instances are managed using AWS Systems Manager (SSM) rather than SSH.
- No SSH keys are generated or distributed
- Port 22 is not exposed on any EC2 instance
- Ansible connects to EC2 instances via SSM using IAM permissions
This significantly reduces the attack surface and eliminates credential sprawl associated with SSH-based access.
- Infrastructure provisioning via Terraform
- Policy validation gates before apply
- Container images built and scanned in CI
- Configuration applied via Ansible
- Secrets sourced dynamically using OIDC and AWS Secrets Manager
.
├── .github
│ ├── actions
│ └── workflows
├── ansible
│ └── roles
├── backend
│ ├── fastapi
│ └── postgres_db
├── frontend
│ └── react-recoil
├── policies
│ ├── checkov
│ └── opa
├── terraform
│ ├── aws_modules
│ └── env
├── docs
└── utils
.github/– CI workflows and reusable GitHub Actionsansible/– Roles and templates for EC2 configurationterraform/– AWS infrastructure modules and environmentspolicies/– Policy-as-code rules (Checkov & OPA)backend/– FastAPI application and database migrations filesfrontend/– React frontenddocs/– Architecture and security documentation
This project is not a one-click deployment.
It assumes familiarity with:
- AWS networking & IAM
- Terraform
- Ansible
- Docker
- VPN concepts
High-level steps:
- Provision AWS infrastructure using Terraform
- Validate plans using policy-as-code checks
- Configure EC2 instances using Ansible
- Deploy WireGuard and generate client configurations
- Deploy application containers and Nginx routing
- Access the platform via VPN connection
- No Kubernetes (intentionally EC2-focused)
- Observability stack not yet implemented
- Automated VPN client provisioning could be improved
This project demonstrates:
- Defense-in-depth cloud security
- Policy-driven infrastructure governance
- Realistic enterprise deployment patterns
- Strong separation of concerns between provisioning and configuration
Detailed architecture and security documentation is provided in the docs/ directory:
docs/architecture.md– System architecture, infrastructure components, and data flowsdocs/security.md– Security model, IAM design, policy-as-code enforcement, and threat mitigation