When I first started working with Terraform, one of my biggest concerns was how to manage my infrastructure as code in a clean, automated, and secure way—without spending all my time running terraform apply manually or worrying about who has access to what. I researched and did some digging, I found different interesting options, but that’s when I also stumbled upon Spacelift.
Spacelift is basically a modern CI/CD platform built specifically for Infrastructure as Code. Think of it as a bridge between your version control system (like GitHub) and your cloud resources—helping you automate Terraform workflows, manage policies, and handle approvals, all in one place.
In this write-up, I want to share a quick story about how I used Spacelift to provision a VPC on AWS from a Terraform configuration sitting in my GitHub repo. I’ll walk you through what I did, why I did it this way, and some small lessons I picked up along the way. If you’re curious about how to get Terraform and Spacelift working together in the real world, I hope this helps you get started.
Before I jump into it, let me share with you my architectural diagram which i designed with Draw.io
.
Why I Picked Spacelift for This
Before this, I was managing my Terraform runs manually on my local machine. It worked, but it didn’t feel sustainable — especially when you think about team collaboration, state file security, and approvals for production changes.
Spacelift stood out to me because it plugs right into my GitHub repo, listens for changes, and takes care of running terraform plan and terraform apply in a safe, controlled way. Plus, it lets me see exactly what’s going to change before I hit “approve.” That extra visibility really helps when you’re touching cloud resources.
What I Wanted to Build
For this little experiment, I kept it simple: a custom VPC on AWS. I wanted to have my own network, subnets, internet gateway — the basics that any modern cloud setup needs. Nothing too fancy, but enough to see Spacelift and Terraform working together end to end.
How I Set It Up
Here’s the high-level flow:
Write the Terraform Code
I wrote a main.tf that defines my VPC, subnets, internet gateway, and route tables. I pushed this to a new GitHub repo.Connect GitHub to Spacelift
I created a new Spacelift stack, pointed it at my repo, and connected it to my AWS account using IAM credentials.Run and Approve
Spacelift detected my Terraform config, ran a plan, and showed me the changes. After reviewing, I gave it approval/confirmation and Spacelift applied the configuration to my AWS account.
That’s it — my VPC was live, provisioned automatically from my GitHub code.
Here is the Terraform Code which I Used
I kept my Terraform configuration as simple and clean as possible — just enough to spin up a VPC with a few subnets. Here’s what it looks like:
# main.tf
resource "aws_vpc" "my_vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "my-simple-vpc"
}
}
# Subnet 1
resource "aws_subnet" "subnet1" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "subnet-1"
}
}
# Subnet 2
resource "aws_subnet" "subnet2" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "10.0.2.0/24"
tags = {
Name = "subnet-2"
}
}
# Subnet 3
resource "aws_subnet" "subnet3" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "10.0.3.0/24"
tags = {
Name = "subnet-3"
}
}
And here’s my provider block, so Terraform knows which cloud and region to talk to:
# provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "6.0.0"
}
}
}
provider "aws" {
region = "eu-central-1"
}
What This Code Does (Quick Breakdown)
VPC: The first block creates a VPC with a /16 CIDR block (10.0.0.0/16). This means I have plenty of private IP space to carve out subnets later.
Subnets: I added three subnets, each with a /24 CIDR block inside that VPC. Each subnet has a simple name tag so it’s easier to recognize in the AWS console.
Provider: Finally, the provider config makes sure Terraform uses the AWS provider and targets the eu-central-1 region (Frankfurt, in my case).
All terraform codes can be derived from the official terraform registry site. Here is the registry link i used. AWS Terraform Registry
Small Tips I Picked Up
Version Pinning: I pinned the AWS provider version (6.0.0). It’s a good habit — this helps avoid surprises when a new provider version has breaking changes.
Tags: Adding clear tags saves you headaches later, especially when you have multiple VPCs or subnets.
State Management: Since Spacelift handles remote state for me, I didn’t have to mess around with setting up an S3 bucket and DynamoDB table for locking — Spacelift does this behind the scenes.
What’s Next?
After pushing this code to my GitHub repo, Spacelift automatically detected the changes, ran terraform plan, and let me preview what would happen. When I hit Approve, Spacelift ran terraform apply and my VPC popped up in AWS — no manual runs from my laptop.
Here is what my Github repo i used looks like.
And here is the link to the GitHub repo i worked with incase you want to access it. My GitHub Repo
Here is my AWS VPC empty, before Spacelift provisioned its resources.
Here is Spacelift running the Apply process for the Deployment cycle, right after the Init Phase, and Plan Phase.
Here is Spacelift once it was with the "Applying phase" and had finished its process cycle.
Here is my formerly empty AWS VPC page which was empty, Now having the provisioned/deployed resource(s).
To Deploy your code to your cloud provider, for example AWS. You need to have an Account, preferrable an IAM user with least required priviledges (for security practices).
You need to "create" and "generate" a security access credentials from your IAM user, and download the CSV file, within it you will have your credentials.
Two credentials needed for Spacelift to work with AWS are "Secret Key" & "Secret Access Key"
Once Generated, they will take this form within your .csv file you downloaded.
provider "aws" {
region = "us-west-2"
access_key = "sample-my-access-key" # Your Key
secret_key = "sample-my-secret-key" # Your Key
}
You need to input them into your Spacelifts Slacks to configure it and authorize/Authenticate it.
Here is a simple direction to follow:
Additionally, here is an extra story of when I broke my configuration by later returning at an different hour, forgetting to review my code from scratch again, and accidentally pushing an unfinished config code to my repo. (and this is how Spacelift Saved Me)
Right after getting the initial setup working, I decided to tweak something in my Terraform code. I made a quick change, pushed it to the GitHub repo… and boom — Spacelift flagged an error and deliberately allow it to fail.
Turns out, I had pushed an invalid configuration by mistake. But here’s the cool part:
Spacelift picked it up immediately, ran the terraform plan, and failed the run without applying anything. That moment was a good reminder of why I’m using this tool in the first place — it acts like a guardrail.
Instead of letting broken code touch my AWS environment, Spacelift stopped the pipeline, showed me exactly where the config was wrong, and kept my infrastructure safe. Once I fixed the mistake, committed the changes, and pushed again, everything went through cleanly.
Here’s a quick snapshot from that failed run (see below ⬇️). I left it in on purpose — because real DevOps isn’t perfect, and that’s okay. What matters is catching things early.
So i resolved it, and cleared the config issue. Hence, why you can see it successfully finished.
Wrapping up
Final Thoughts: What did i learn, right?
This small project may seem basic — just a VPC and some subnets — but for many out there who are just starting or wondering on how to start or where to start, it will serve as an solid intro to combining Terraform with Spacelift in a real-world workflow.
Personally, It showed me how powerful automation can be when paired with the right tools and a good version control setup.
Here’s what stood out the most:
🛡️ Safety First: Spacelift acted like a second pair of eyes. It caught my broken code and stopped it from being applied. That alone is worth the setup.
🧠 Git-Driven Infra: Everything I did was tracked in Git. No more guessing what changed or why — just clean commits and transparent change history.
🚀 Confidence Boost: Watching Spacelift plan and apply my infrastructure automatically made me feel more confident about scaling future projects.
I’m only just getting started with IaC automation, but this experiment gave me the motivation to go deeper.
I have also used Spacelift to provision resources on Azure, and now I am looking forward to GCP.
Here is Spacelift managing Azure Resources.
And here is Spacelift Lifecycle on the Azure Resource.
Then next, on my AWS repo, I’ll be looking into adding network ACLs, route tables, maybe even EC2 instances — all managed through the same Spacelift pipeline.
If you’re exploring Terraform and want a smoother CI/CD experience for your infrastructure, I genuinely recommend giving Spacelift a shot. It’s like Terraform on autopilot — but with controls.
I hope you enjoyed reading through, feel free to practice with Spacelift.
Thank you for reading.
Top comments (0)