How I reduced AWS provisioning time by 80% with CloudFormation

When our team at Haaga-Helia was tasked with deploying a production-ready Moodle LMS on AWS, we had two choices: click through the AWS console for every resource, or build it properly with Infrastructure as Code. We chose CloudFormation — and it changed how I think about cloud deployments entirely.

The problem with manual deployments

Clicking through the AWS console is fine for learning, but it doesn’t scale. If you need to rebuild the environment — for testing, disaster recovery, or a new region — you’re doing everything from memory. We had a multi-tier architecture with VPCs, public and private subnets, EC2 instances, RDS, a load balancer, and IAM roles. Manually recreating that would take hours and introduce human error every single time.

CloudFormation lets you define all of that in YAML templates. Run the template, the stack builds itself. Delete the stack, everything tears down cleanly. It’s reproducible, version-controlled, and reviewable by the whole team.

Our CloudFormation stack structure

We split our infrastructure across 10+ templates using nested stacks. This kept each template focused and manageable:

  • vpc.yaml — VPC, subnets, route tables, NAT Gateway, Internet Gateway
  • iam.yaml — roles and instance profiles with least-privilege policies
  • ec2.yaml — launch templates, security groups, EC2 instances
  • rds.yaml — MariaDB in a private subnet with automated backups
  • cloudwatch.yaml — alarms, dashboards, and log groups

The 80% time reduction — where it came from

Our first manual deployment of the full environment took around 4 hours. After building the CloudFormation templates, a full deployment took under 45 minutes — most of that waiting for resources to provision, not human input. That’s the 80% saving.

More importantly, our second, third, and fourth deployments also took 45 minutes. Consistency is the real win with IaC — you stop worrying about whether you forgot a security group rule or misconfigured a subnet.

Key lessons

The biggest lesson was to design your templates for deletion, not just creation. If a stack can’t be cleanly deleted, something is holding a dependency you haven’t modelled correctly. Test deletions early and often.

Also: use Parameters in CloudFormation to make templates reusable across environments. A single EnvironmentType parameter (dev/staging/prod) can change instance sizes, retention periods, and alarm thresholds across your whole stack without touching the template logic.

Infrastructure as Code isn’t just a DevOps best practice — it’s a way of thinking about infrastructure as something that should be as carefully designed as the application running on top of it.

Leave a Reply

Your email address will not be published. Required fields are marked *