dev@portfolio:~
back to projects
>_

AWS Cloud Infrastructure

A production-inspired AWS environment for running a containerized web application securely and consistently.

• Personal Project • GitHub repository ↗

Project Status
● In Progress
Type
Infrastructure
Duration
3+ months

What I built

A complete AWS environment designed to host and deploy a web application securely, while keeping its public, application, and data layers separate.

Core infrastructure
AWS Terraform
Delivery & automation
Docker GitHub Actions
Application
Vue Flask MySQL

>_This stack automates the journey from source code to a secure, running cloud environment.

Why I built it

To understand how a complete cloud environment works, not just how to create individual AWS resources.

Result

A working web application environment that can be created automatically, tested, and removed when it is no longer needed.

My role

I designed the architecture and implemented the infrastructure, security boundaries, application packaging, and deployment workflows.

Users can access the website, but they cannot connect directly to the servers or database behind it. Each request follows a controlled path through the application.

  1. 01

    Public entry point

    Users reach the application through a secure public endpoint.

    Cloudflare → public ALB

  2. 02

    Web tier

    The frontend is served by private application servers that can scale automatically.

    Public ALB → Nginx

  3. 03

    Application tier

    API requests are handled separately from the frontend for better isolation.

    Nginx → internal ALB → Flask/Gunicorn

  4. 04

    Data tier

    Application data is stored in an isolated managed database with no public access.

    Flask/Gunicorn → RDS MySQL

Architecture Diagram

Architecture outcomes

  • Only one public entry pointReduces attack surface and simplifies security.
  • App servers remain privateNo direct internet access to application servers.
  • Database has no public accessData stays protected in private subnets.
  • Components scale independentlyEach tier can scale based on demand.

The main design choices that make the environment secure, maintainable and repeatable.

6Key decisions
3 Goals achievedSecurity • Maintainability • Repeatability
01

Private compute tiers

Web and application instances have no direct public entry path.

Why it matters:

Incoming requests must pass through the load-balancing boundaries instead of reaching EC2 directly.

02

Separate load balancers

The public and application-facing traffic paths remain distinct.

Why it matters:

A public ALB handles browser traffic while an internal ALB exposes the API only to the web tier, keeping routing and health checks explicit.

03

Modular Terraform

Infrastructure concerns have separate, reviewable responsibilities.

Why it matters:

Networking, security groups, load balancers, compute, RDS, DNS and CI/CD IAM can change without one tightly coupled configuration.

04

Keyless CI/CD authentication

GitHub Actions uses short-lived AWS sessions instead of stored keys.

Why it matters:

OIDC and operation-specific roles reduce the reach of each workflow and remove long-lived secrets.

05

Runtime configuration

Release metadata and database credentials remain outside application images.

Why it matters:

Image versions and non-secret database metadata live in SSM Parameter Store; the RDS password stays in its AWS-managed secret.

06

Image-based replacement

Instance Refresh rolls the selected container release through each tier.

Why it matters:

New instances retrieve the intended image tag during startup and must pass load-balancer health checks.

Infrastructure changes and application releases use separate automated workflows. GitHub Actions connects to AWS through OpenID Connect (OIDC), using short-lived access and distinct approval gates for each operation.

  1. 01

    Validate

    Test the Flask backend and build the Vue frontend.

  2. 02

    Build

    Build immutable backend and frontend Docker images tagged with the Git commit SHA.

  3. 03

    Publish

    Push both application images to Amazon ECR.

  4. 04

    Migrate

    Run the database migration before the new image tags become active.

  5. 05

    Refresh

    Update SSM image parameters, then refresh the application tier before the web tier.

Technical release details
  • Replacement instances retrieve their image tags from SSM Parameter Store during startup.
  • The workflow waits for each Instance Refresh to complete and for replacement capacity to pass target-group health checks.
  • Infrastructure deployment remains a separate Terraform workflow; apply is manually gated.
  • The current flow does not claim automatic rollback.

Every layer accepts traffic only from the layer immediately before it. AWS security groups enforce this path without exposing the application servers or database directly to the internet.

Access path

  1. Internet
    80 / 443
  2. Public ALBPublic entry point
    web service port
  3. Web tierNginx containers
    internal traffic
  4. Internal ALBPrivate routing
    backend port
  5. Application tierFlask / Gunicorn API
    3306
  6. RDS MySQLPrivate database

Security highlights

No public SSH

Instances are managed through AWS Systems Manager.

There is no public SSH path or inbound SSH rule.

Runtime secrets

Database credentials remain in the AWS-managed RDS secret.

The backend role retrieves only the required metadata and secret at runtime.

Short-lived CI identity

GitHub Actions authenticates to AWS through OIDC.

Planning, infrastructure changes and application deployment use separate IAM roles.

Estimated monthly total
$192.40
Region
eu-central-1
Model
Monthly development environment
Method
Cloudcraft estimate

This estimate models the main resources in the architecture, including four burstable EC2 instances, two Application Load Balancers, two NAT gateways, an ECR repository and a Multi-AZ RDS MySQL database.

Networking is the largest projected cost category, mainly due to NAT gateways and load balancers. The environment is intended to be provisioned temporarily rather than left running continuously.

Directional estimate only. Actual cost depends on runtime, traffic, storage, data transfer, logging and current AWS pricing.

Networking

66.6%
$128.06

per month

Compute

18.2%
$35.04

per month

Database

15.2%
$29.20

per month

Containers

0.1%
$0.10

per month

Production-inspired architecture — prioritizes availability and isolation over minimum cost.

Detailed Cloudcraft estimate

Resource-level breakdown derived from the original monthly projection.

Monthly total
$192.40 / mo
Networking
$128.06 / mo
66.6%
Compute
$35.04 / mo
18.2%
Database
$29.20 / mo
15.2%
Containers
$0.10 / mo
0.1%
ServiceDescriptionMonthly cost% of total
Networking2 NAT gateways, 2 Application Load Balancers$128.0666.6%
Compute (EC2)4 × burstable instances$35.0418.2%
Database (RDS)RDS MySQL (Multi-AZ)$29.2015.2%
Containers (ECR)ECR repository storage$0.100.1%

These are deliberate compromises that keep this portfolio demo simple and cost-effective while acknowledging what would change in a longer-lived or production-grade setup.

01

Disposable database defaults

Reason
Allow the complete demo to be destroyed without retaining chargeable resources.
Current consequence
Deletion protection and final snapshots are disabled by default.
For a longer-lived environment
Enable deletion protection, retain final snapshots, increase backup retention and test restoration.
02

NAT gateways over VPC endpoints

Reason
Keep initial networking simpler while private instances reach required AWS services.
Current consequence
NAT gateways provide ECR, SSM and CloudWatch access but create recurring networking cost.
For a longer-lived environment
Evaluate endpoints for SSM, ECR, CloudWatch Logs and S3.
03

Reduced observability

Reason
Keep a temporary portfolio environment cheaper.
Current consequence
ALB access logs, VPC Flow Logs and advanced database observability are not enabled by default.
For a longer-lived environment
Centralize logs and add retention, alarms, dashboards and an investigation strategy.
04

Internal HTTP

Reason
Keep the internal encryption boundary simpler for this temporary environment.
Current consequence
TLS terminates at the public ALB and traffic behind it uses HTTP inside private subnets.
For a production-oriented environment
Reassess internal encryption rather than treating private networking as automatic trust.
Additional implementation constraint

The ACM certificate, ECR repository, GitHub OIDC provider and some CloudWatch configuration must exist before deployment. Keeping them outside the main stack narrows its focus, but means the environment is not yet reproducible through one command.

Private does not mean disconnected

I learned to design outbound access for ECR, SSM, CloudWatch and other AWS APIs alongside routing, IAM and instance bootstrapping.

Infrastructure state has a different lifecycle

Bootstrapping the backend separately clarified why control-plane resources should outlive short-lived workload resources.

CI/CD identity should match the operation

Separate OIDC roles made least privilege more concrete than one shared automation role with planning, apply and deployment access.

Health checks are deployment logic

Starting an instance is not a completed rollout; replacement capacity must start its containers and pass target-group health checks.

  1. 01

    Add configurable VPC endpoints

    Reduce NAT dependency for SSM, ECR, CloudWatch Logs and S3 while keeping AWS service traffic on the AWS network.

  2. 02

    Strengthen observability

    Enable VPC Flow Logs and ALB access logs, then add CloudWatch dashboards and alarms for the existing infrastructure and application signals.

  3. 03

    Introduce environment profiles

    Add development, staging and production configurations with appropriate deletion protection, backups, retention, scaling and approval defaults.

  4. 04

    Automate runtime prerequisites

    Bootstrap the remaining CloudWatch agent parameters and setup dependencies consistently to remove manual first-deployment steps.

Detailed views of topology, routing, runtime configuration and delivery.