Multiple Cloud Provider Thoughts
While Terraspace can support multiple Cloud Providers within one single project, the code can get complex. So it is generally not recommended to mixed multiple Cloud Provider resources in a single Terraspace project, particularly if you’re using the TFC VCS-Workflow and multiple regions. First, we’ll provide some context and then discuss some of the reasons.
Where Terraspace Builds
When Terraspace builds a project, it will build it in the terraspace-cache
folder. It looks something like this:
$ terraspace build demo
Building .terraspace-cache/us-west-2/dev/stacks/demo
Notice that the region is included in the path.
Terraform Cloud
One of the reason region is included in the path is for Terraform Cloud. With TFC, the Workspace “Terraform Working Directory” setting needs to be unique for the VCS-Driven Workflow. The code needs to be checked into version control under a unique path.
Essentially, it boils down to how TFC works. We must make sure that the “Terraform Working Directory” is designed for a different workspace. If we are not using TFC VCS-Driven workflow, these limits do not apply. For example, the TFC CLI-Driven workflow works just fine.
Other Backend Types
Let’s say you’re not using TFC and are using another backend like s3 instead. With other Backend types, it’s not a VCS-Driven workflow. So Terraspace will build the folder and be able to apply just fine also.
Multiple Cloud Providers Build Path
Now let’s talk about Terraspace with multiple Cloud Providers in one project. Say, a single Terraspace project provisions both AWS and Google resources. Let’s say the vm stack provisions a Google VM and the instance stack provisions an AWS Instance. AWS and Google regions are unique. So their build paths would look something like this:
.terraspace-cache/us-west-2/dev/stacks/instance
.terraspace-cache/us-central1/dev/stacks/vm
So for the TFC VCS-Workflow, we’re ok in terms of unique build paths. For other workflows like Terraform OSS and the TFC CLI-workflow it also works just fine.
Multiple Cloud Providers Backends
The backend.tf uses an expansion
helper that auto-detects the provider plugin installed. When 2 providers are installed, the auto-detection returns only one provider’s backend using this precedence: s3, azurerm, gcs.
Just using one s3 backend for both Cloud Provider resources is probably the most straightforward approach. Though, it does feel a little dirty to mix up the state of multiple clouds.
If you wanted to use different backends from different cloud providers in a single Terraspace project, there’s some extra setup. The expansion
method needs to be passed a backend
option. Additionally, we’ll need to use some conditional logic to set the different backends on a per stack basis. Here’s an example:
config/terraform/backend.tf
<% if ENV["GCS_BACKEND"] %>
terraform {
backend "gcs" {
bucket = "<%= expansion('terraform-state-:PROJECT-:REGION-:ENV', backend: "gcs") %>"
prefix = "<%= expansion(':PROJECT/:TYPE_DIR/:APP/:ROLE/:MOD_NAME/:ENV/:EXTRA/:REGION', backend: "gcs") %>" # variable notation expanded by terraspace IE: us-central1/dev/modules/vm
}
}
<% else %>
terraform {
backend "s3" {
bucket = "<%= expansion('terraform-state-:ACCOUNT-:REGION-:ENV', backend: "s3") %>"
key = "<%= expansion(':PROJECT/:TYPE_DIR/:APP/:ROLE/:MOD_NAME/:ENV/:EXTRA/:REGION/terraform.tfstate', backend: "s3") %>"
region = "<%= expansion(':REGION', backend: "s3") %>"
encrypt = true
dynamodb_table = "terraform_locks"
}
}
<% end %>
terraspace up demo # aws
GCS_BACKEND=1 terraspace up demo2 # google
You can probably use a Config Hook to set the GCS_BACKEND env variable based on module name, so you don’t have to remember it. It starts to get pretty complex though.
Recommendation
While it is possible to use a single Terraspace project to provision resources from multiple cloud providers, it is cleaner to have multiple terraspace projects. For example, a terraspace project for AWS and one for Google. Terraform resource interfaces are not cloud-agnostic anyway. Terraform supports multiple cloud providers, but the Cloud provider interfaces are different. So the current recommendation is to use separate Terraspace projects.