Mayank Dixit | DevOps & Cloud Engineer

Automating Cloud Infrastructure, CI/CD, and DevSecOps.

View the Project on GitHub mayank0131/infrawithmayank

Travel Realm - Multi-Layer AWS Infrastructure

Private project  ·  AWS Multi-Account · Terraform · GitHub Actions CI/CD


The problem

Travel Realm needed to run multiple isolated environments - development, staging, production - across separate AWS accounts, with a deployment pipeline that developers could trigger without needing AWS console access or stored credentials. Standing up a new environment was a days-long manual process with no consistency guarantees between accounts.


What was built

A three-layer Terraform system where each layer has a single responsibility: governance, provisioning, and delivery. Any layer can be run independently. A new environment is a Terraform apply - not a checklist.


Layer 1 - Governance

Responsibility: Everything in the management account that other layers depend on.

Why this matters: Without this layer, every new account would require manual IAM setup, manual DNS entries, and credential rotation. With it, the governance model is defined once in code and applied consistently.

Governance and CI/CD architecture

Three-layer model: management account governs child accounts via Terraform, GitHub Actions deploys via OIDC.


Layer 2 - Environment provisioning

Responsibility: The full infrastructure stack inside each child account.

Why this matters: Every environment is identical by construction. There is no configuration drift between staging and production because both are produced by the same Terraform modules with different parameter files.

Runtime architecture CloudFront multi-origin distribution, ECS Fargate, RDS, ElastiCache, and supporting services inside the VPC.


Layer 3 - CI/CD delivery

Responsibility: Getting application changes from a Git push into the running environment.

Three independent pipeline tracks, all authenticating to AWS via OIDC:

Frontend - Vite build, S3 upload, CloudFront cache invalidation. Runs on push to the relevant branch; PR builds produce a plan only.

Backend - Docker image built and pushed to ECR, ECS service updated to pull the new image. Zero-downtime deployments via ECS rolling update strategy.

Database - Optional SQL bootstrap via CodeBuild. Triggered manually or as part of environment initialisation, not on every push.

Why this matters: Developers deploy by merging a pull request. No one needs AWS console access, no credentials are stored in GitHub, and every deployment follows the same path through the same checks.


Key design decisions

Decision Rationale
OIDC authentication throughout Eliminates credential rotation and the risk of leaked access keys
Three separate Terraform layers Each layer can be applied independently without touching the others
ACM in us-east-1 CloudFront requires certificates in us-east-1 regardless of deployment region - provisioned explicitly to avoid silent failures
CloudFront multi-origin Single distribution, single SSL cert, centralised cache invalidation for two separate S3 static sites
Parameterised environments New environments require a parameter file change, not a code change

Outcome

Environment provisioning reduced from days to hours. Developers deploy without AWS console access. No stored credentials in any pipeline. Staging and production are provably identical in configuration.

The client can add a new environment by copying a parameter file and running terraform apply. The governance layer does not need to be touched.


Stack: AWS Organizations · Terraform · ECS Fargate · RDS PostgreSQL · ElastiCache · CloudFront · ACM · WAF · S3 · GitHub Actions · IAM Identity Center · Secrets Manager · CloudWatch · Keycloak · Node.js · Vite


← Back to projects