Terraspace is a Terraform framework. It provides an organized structure, conventions over configurations, keeps your code DRY, and adds convenient tooling. It makes it easier and more fun to work with Terraform.

Quick Start

Here are commands to get started with Terraspace quickly.

gem install terraspace
terraspace new project infra --plugin aws --examples
cd infra
terraspace up demo
terraspace down demo

The commands above will provision some test infrastructure resources and destroy it. The example resource is a s3 bucket. For more docs:

How Terraspace Works

Here’s a high-level explanation of how Terraspace works. It’s pretty straightforward.

Terraspace works by building files in the app and config/terraform folders to a .terraspace-cache folder. Then it merely calls out to terraform within that folder.

In fact, you can use Terraspace to build the files first, cd into the .terraspace-cache folder, and run Terraform directly. Example:

terraspace build demo
cd .terraspace-cache/us-west-2/dev/stacks/demo
terraform init
terraform apply

Once you’re in the .terraspace-cache folder, it’s regular terraform at that point.

Terraspace automates it with:

terraspace up demo

Project Structure

The Terraspace project structure looks something like this:

├── app
│   ├── modules
│   │   └── example
│   └── stacks
│       └── demo
│           └── tfvars
├── config
│   ├── app.rb
│   ├── env
│   │   ├── dev.rb
│   │   └── prod.rb
│   └── terraform
│       ├── backend.tf
│       └── provider.tf
└── Terrafile

Here’s an description of the folders and files:

Name Description
app/modules Reusable modules or library code. Use terraspace new module to generate a module.
app/stacks Business specific modules. Use terraspace new stack to generate a stack. It is often useful to start here and then abstract generic logic to the app/modules folder.
app/stacks/demo/tfvars Within each stack folder, you can have a tfvars folder and define different variables. You can use tfvars layering to use the same code to create different environments.
config/app.rb Terraspace project-level settings. Configure things like the logger and test framework.
config/terraform Common code that gets built with the deployed stack. It can be dynamically controlled to keep your code DRY.
Terrafile The Terrafile is where you define additional terraform modules to be loaded by terraform bundle.

More details on the Project Structure Docs.

Modules and Stacks

Terraspace will look for files in the app/modules and app/stacks folders. Both folders contain Terraform modules. Terraspace introduces the stack concept for organizational purposes.

Folder Description
app/modules Where reusable library code or “functions” go.
app/stacks What should be deployed. These modules contains more business-specific logic.

If you’ve worked with Terraform OSS, you can think of a stack a separate terraform project folder with a separate state file. If you’ve work with Terraform Cloud before, you can think of a stack as a separate Cloud Workspace.

We’re generalizing a bit here as the Terraspace state management is configurable.

State File Management

Terraspace tells Terraform how to manage the state file in config/terraform/backend.tf. Terraspace generates this backend.tf as part of the terraspace up command. For example:

config/terraform/backend.tf

terraform {
  backend "s3" {
    bucket         = "<%= expansion('terraform-state-:ACCOUNT-:REGION-:ENV') %>"
    key            = "<%= expansion(':TYPE_DIR/:APP/:ROLE/:MOD_NAME/:ENV/:EXTRA/:REGION/terraform.tfstate') %>"
    region         = "<%= expansion(':REGION') %>"
    encrypt        = true
    dynamodb_table = "terraform_locks"
  }
}

When you run:

terraspace up demo

Terraspace creates a backend.tf file for the built demo stack.

.terraspace-cache/us-west-2/dev/stacks/demo/backend.tf

It will look something like this:

terraform {
  backend "s3" {
    bucket         = "terraform-state-111111111111-us-west-2-dev"
    key            = "stacks/dev/demo/us-west-2/terraform.tfstate"
    region         = "us-west-2"
    encrypt        = true
    dynamodb_table = "terraform_locks"
  }
}

Additionally, Terraspace automates the creation of the backend storage bucket. Though it depends on the Cloud Provider, Terraspace generally enables security-related and backup features such as:

  • encryption
  • ssl
  • kms key
  • versioning
  • lifecycle policies

Tfvars and Layering

Terraspace empowers you to reuse the same infrastructure code to create different environments like dev and prod. This is achieved with Tfvars and Layering.

Let’s say you have an EC2 instance, and you want to deploy it to both a dev and prod account with slightly different settings. Here’s how you can achieve it with tfvar files.

app/stacks/instance/tfvars/base.tfvars - base or common tfvars
app/stacks/instance/tfvars/dev.tfvars  - dev specific tfvars + base
app/stacks/instance/tfvars/prod.tfvars - prod specific tfvars + base

You can use TS_ENV to control which env-specific tfvars file to layer on top of base.tfvars. Example:

TS_ENV=dev  terraspace up instance # uses base.tfvars and dev.tfvars
TS_ENV=prod terraspace up instance # uses base.tfvars and prod.tfvars

This simple example is the tip of the iceburg of Terraspace’s layering power. With Terraspace Layering you can use the same code to deploy to different accounts and regions. See Terraspace Full Layering Docs.

Deploy All or Multiple Stacks

Terraspace also allows you to deploy all stacks with a single command:

terraspace all up

Terraspace calculates the dependency graph and ensures they are deployed in the correct order. Here’s a dependency graph example:

Related Blog Post: Terraspace All: Deploying Multiple Stacks at Once

Much More

Terraspace offers much more. Here’s a list of some features.

  • Config Structure: A common config/terraform structure that gets built with the deployed module. It can be dynamically controlled to keep your code DRY.
  • Generators: Built-in generators to quickly create modules. Focus on code instead of boilerplate structure.
  • Tfvars & Layering: Use the same code with different tfvars to create multiple environments. Terraspace conventionally loads tfvars from the tfvars folder. Rich layering support allows you to build different environments like dev and prod with the same code. Examples are in Full Layering.
  • Deploy Multiple Stacks: The ability to deploy multiple stacks with a single command. Terraspace calculates the dependency graph and deploys stacks in the right order. You can also target specific stacks and deploy subgraphs.
  • Terrafile: Terraspace makes it easy to use Terraform modules sourced from your own git repositories, other git repositories, or the Terraform Registry. The git repos can be private or public. This is an incredibly powerful feature of Terraspace because it opens up a world of modules for you to use. Use any module from anywhere.
  • Configurable CLI: Configurable CLI Hooks and CLI Args allow you to adjust the underlying terraform command.
  • Testing: A testing framework that allows you to create test harnesses, deploy real-resources, and have higher confidence that your code works.
  • Terraform Cloud and Terraform Enterprise Support: TFC and TFE are both supported. Terraspace adds conveniences to make working with Terraform Cloud Workspaces easier.
  • Cloud Providers supported: aws, azure, google.

Summary

Though Terraform provides us the essentials to help build infrastructure-as-code, it leaves much for us to figure out. Terraspace is a framework to help. It provides an organized structure, conventions, and convenient tooling to help you get things done. Terraspace makes working with Terraform easier and more fun. To learn more check out the official docs at terraspace.cloud.

You may also be interested in: