Terraform Remote State with Spacelift

Spacelift Terraform Remote State

The Terraform state management features in Spacelift are extremely important to maintaining secure and reliable infrastructure deployments. Managing state yourself can be a security nightmare, lead to state corruption due to multiple engineers working simultaneously, and require difficult import operations related to infrastructure drift.

It’s honestly just one more thing to manage in a sea of responsibilities that startups and enterprises have on their plate. Unfortunately, one of the issues with managing state remotely can be accessing that state for ad-hoc troubleshooting and cross-stack data access.

Luckily, Spacelift has now rolled out the ability to access that remote state and manipulate it as needed! And what’s better, this feature can be toggled to ensure security when its access is not needed. Let’s take a look!

Using Remote State Access

Enabling Remote State Access

Enabling remote state access is as easy as flipping a simple toggle switch or configuring it within the Spacelift Terraform provider. To enable remote state access in the Spacelift UI, head to your stack, click on “Settings,” “Backend,” and toggle “External state access”:

spacelift terraform provider

Basic State Access

Once remote state access is enabled, you will be able to use the Terraform remote state data source to access the state. Here, I have configured the data source in a file to connect to my Saturnhead Spacelift account and access the “pool_eks_stack” stack. This stack deploys an AWS EKS cluster using a modified version of the AWS EKS Module written by Anton Babenko

data "terraform_remote_state" "pool-eks-stack-state" {
  backend = "remote"

  config = {
    hostname     = ""
    organization = "saturnhead"

    workspaces = {
      name = "pool-eks-stack"

output "cluster_name" {
  value = data.terraform_remote_state.pool-eks-stack-state.outputs

In this simple configuration, I can output all of the outputs configured in this module.

If I only want to see the cluster_name, I can do so as follows:

output "cluster_name" {
  value = data.terraform_remote_state.pool-eks-stack-state.outputs.cluster_name

Once I’ve configured these, I can run a terraform plan and see the output I asked for:

slderek@DEREKMBP remote-state % terraform plan
data.terraform_remote_state.pool-eks-stack-state: Reading...
data.terraform_remote_state.pool-eks-stack-state: Read complete after 3s

Changes to Outputs:
  + cluster_name = "spacelift-eks-nG5n3pMT"

That’s pretty cool, but the real power comes in when you can start running Terraform commands against your state for debugging or troubleshooting purposes. I’ll add a Terraform remote backend to my file:

terraform {
  backend "remote" {
    hostname     = "" 
    organization = "saturnhead"    

    workspaces {
      name = "pool-eks-stack" 

Once you run a terraform init with the configuration, you can run almost any command against the state that you wish. Of course, you’ll want to ensure you don’t make changes that will cause the code in your repository to become out of sync with the remote state. Once you have initialized the backend, you can run a terraform state list and see your deployed resources. 

Many useful Terraform commands can be used for troubleshooting and crafting your configuration files. Unfortunately, since the state is locked by Spacelift, you cannot run the Terraform Console against the remote state unless you pull it locally. I say “unfortunately” because you may wish to use it, but just remember that running commands that could possibly modify your remote state from the CLI is actually extremely disadvised. Hence, it’s probably best that this lock stays in place.

You can get around this with the terraform plan and terraform apply commands by adding a simple flag, e.g. terraform plan -lock=false. But this can defeat the purpose of using a managed IaC deployment utility completely, so I would avoid doing this unless it’s a last resort. With that disclaimer out of the way, let’s look at the safer way to run troubleshooting commands against your state by pulling the state locally. 

  1. Clone the configuration directory from git that contains the code that deployed the state: git clone <your repo>
  2. Pull the remote state to your local machine: terraform state pull > <repo-directory>/terraform.tfstate
  3. Change into the new directory: cd <repo-directory>
  4. Check to ensure the terraform.tfstate file is in the directory, and run a terraform state list to ensure everything works. 

After this, you can run any Terraform commands you need as if you were working with the configuration and the state locally without the risk of causing some serious state synchronization issues. 

As mentioned before, one of the most powerful tools is terraform console. If I wanted to test out the zipmap function to see if I could construct a map of AWS AZ names to their respective zone ID, I can use terraform console like so:

terraform console

As you can see, I have the data.aws_availability_zones.available data source specified in my configuration file, I run terraform console, I check to see what the data source returns, and then use the zipmap() function to map the names and ids together.

This is a simple example, but you can absolutely see how powerful this is when writing your Terraform configuration.

Key Points

Spacelift’s new remote state access feature is one of the most powerful features we’ve released to date. Along with the incredibly powerful resource view, Blueprints, Cloud Integrations, Drift Detection, OPA policy engine, and more, Spacelift is the most powerful IaC deployment platform available, so check it out and schedule a demo today to see how we can help!

Manage Terraform Better and Faster

If you are struggling with Terraform automation and management, check out Spacelift. It helps you manage Terraform state, build more complex workflows, and adds several must-have capabilities for end-to-end infrastructure management.

Start free trial