hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io
Other
43.16k stars 9.58k forks source link

Allow using Terraform backend blocks like a data source #24866

Open dancmeyers opened 4 years ago

dancmeyers commented 4 years ago

Current Terraform Version

0.12.24

Use-cases

I want to be able to access Terraform remote state for other Terraform workspaces within my current workspace, without having to duplicate as workspace variables the parts of the backend configuration that are shared between them. This duplication just feels unnecessary.

For example we store remote state in GCS, with a bucket per environment, with an auto-generated (and thus somewhat random rather than memorable) name. Across our environments the structure within these buckets is the same, so I always know that the prefix for the project containing the shared VPC is projects/vpc, and the StackDriver workspace is projects/monitoring. Those can be hard-coded. The bit I don't know is the name of the bucket itself.

Attempted Solutions

The current 'solution' is simple, have a variable that duplicates the backend config:

variable "tfstate_bucket" {
  description = "The name of the Google Cloud Storage bucket which holds Terraform state"
  type        = string
  default     = "infra-dev-56c7_core"
}

terraform {
  backend "gcs" {
    bucket = "infra-dev-56c7_core"
    prefix = "projects/baker"
  }
}

data "terraform_remote_state" "monitoring" {
  backend = "gcs"
  config = {
    bucket = var.tfstate_bucket
    prefix = "projects/monitoring"
  }
}

data "google_monitoring_notification_channel" "slack" {
  project      = data.terraform_remote_state.monitoring.outputs.monitoring_project
  display_name = "DevOps Slack Channel"
}

Proposal

It would be great if I could reference attributes of the terraform block (specifically, in my case, the backend config) like a data source. The above HCL would then become something like:

terraform {
  backend "gcs" {
    bucket = "infra-dev-56c7_core"
    prefix = "projects/baker"
  }
}

data "terraform_remote_state" "monitoring" {
  backend = "gcs"
  config = {
    bucket = terraform.backend["gcs"].bucket
    prefix = "projects/monitoring"
  }
}

data "google_monitoring_notification_channel" "slack" {
  project      = data.terraform_remote_state.monitoring.outputs.monitoring_project
  display_name = "DevOps Slack Channel"
}

It's only a minor thing, but would just neaten everything up a bit. The alternative would be to allow variables to be used within the backend definition:

variable "tfstate_bucket" {
  description = "The name of the Google Cloud Storage bucket which holds Terraform state"
  type        = string
  default     = "infra-dev-56c7_core"
}

terraform {
  backend "gcs" {
    bucket = var.tfstate_bucket
    prefix = "projects/baker"
  }
}

data "terraform_remote_state" "monitoring" {
  backend = "gcs"
  config = {
    bucket = var.tfstate_bucket
    prefix = "projects/monitoring"
  }
}

data "google_monitoring_notification_channel" "slack" {
  project      = data.terraform_remote_state.monitoring.outputs.monitoring_project
  display_name = "DevOps Slack Channel"
}

This would have the added benefit of allowing us to use the same backend configuration in all our environments, because it would only be the variable that changed rather than the hard-coded entry, which would in turn allow us to more easily use the same HCL for each environment by using Terraform workspaces despite the backend being a different location for each env.

References

None that I am aware of

akhilesh0 commented 4 years ago

+1

philomory commented 3 years ago

This would be super helpful for us also, for a slightly different reason. I'd really like to be able to tag resources with the name of the Terraform Cloud workspace they are managed by, so that someone who sees that resource in e.g. the console always knows exactly what Terraform workspace is responsible for it. Obviously, I could accomplish that by just copy-pasting the name of the workspace everywhere, but obviously that's not an ideal solution.