Intro
If you're a developer or "developer adjacent," you've probably heard about "self-service" infrastructure. As the infrastructure required to launch simple apps becomes more and more distributed and specialized, deploying these apps becomes more difficult for the ones that program them. Previously, you could just upload the new code to your html directory, and BAM! The new site is up! Now, these apps usually require multiple pieces of infrastructure to be set up to be delivered. This allows companies to deploy only the necessary infrastructure and only pay for it when needed. Unfortunately, this adds more overhead for the developer. To combat this, DevOps teams and their subset, "Platform Engineering", are working on abstracting this process from the developers to allow them to create this infrastructure themselves on the fly when needed, without the headaches. In this article, we'll cover different strategies to build a self-service platform that deploys a simple peered VPC in AWS without the developer making any complicated decisions. So let's kick this off!
The Terraform Code
As I mentioned before, this is not a series that will cover a sophisticated AWS SaaS deployment. We will keep the AWS code very simple and focus more on the pipeline and the self-service aspects than the deployed infrastructure. So we're going to stick to a simple VPC:
Main VPC Code
# ./shared_infra/main.tf
provider "aws" {
region = var.region
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main"
}
}
# ./shared_infra/variables.tf
# Set the appropriate default region here.
variable "region" {
type = "string"
default = "us-east-1"
}
# ./shared_infra/versions.tf
# specify different versions if appropriate.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.15.0"
}
random = {
source = "hashicorp/random"
version = "3.1.0"
}
}
}
Client VPC Code
# ./client_infra/main.tf
provider "aws" {
region = var.region
}
data "aws_vpc" "main" {
filter {
name = "tag:Name"
values = ["main"]
}
}
resource "aws_vpc" "client_vpc" {
cidr_block = var.vpc_cidr
tags = {
Name = "client_vpc"
}
}
resource "aws_vpc_peering_connection" "this" {
peer_vpc_id = aws_vpc.client_vpc.id
vpc_id = data.aws_vpc.main.id
auto_accept = true
tags = {
Name = "VPC Peering"
}
}
resource "aws_route" "requester" {
route_table_id = data.aws_vpc.main.main_route_table_id
destination_cidr_block = aws_vpc.client_vpc.cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}
resource "aws_route" "accepter" {
route_table_id = aws_vpc.client_vpc.main_route_table_id
destination_cidr_block = data.aws_vpc.main.cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}
# ./client_vpc/variables.tf
variable "region" {
type = string
default = "us-east-1"
}
variable "vpc_cidr" {
type = string
default = "10.1.0.0/16"
}
variable "client_name" {
type = string
default = "cool-client"
}
# ./client_infra/versions.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.15.0"
}
random = {
source = "hashicorp/random"
version = "3.1.0"
}
}
}
Deployment
This code is simple enough. And to deploy it, all you have to do is give the client VPC a unique name and terraform apply
each piece individually. Easy peasy, right? Of course it is, for the one who wrote it! If you have many developers, expecting this to be deployed correctly when they add clients is, unfortunately, most likely a pipe dream. How can we deploy this in a way that allows developers to deploy easily and securely? I'll cover the overall approaches we'll take here, then we'll deep dive into them as we continue the series.
The Managed Deployment Way
This will be the method with a lot of flexibility and a much simpler deployment process. Using Spacelift and its Blueprints feature, we'll be able to deploy a frontend for developers to use and a deployment pipeline that can deploy Terraform, Cloudformation, Pulumi, and more. We'll focus on Terraform here and build everything out, including the Spacelift resources using Terraform. This method will be incredibly flexible, but of course, it is not a free solution. To use the Blueprints feature, an enterprise account will be required. I'll show how to deploy everything before the Blueprints for those without an enterprise account, then add the Blueprints customization by the end.
Check out the next post in this series to see the managed way.
Top comments (0)