Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in Terraform 0.12.0: This object has no argument, nested block, or exported attribute #21442

Closed
ameyaptk opened this issue May 24, 2019 · 7 comments

Comments

@ameyaptk
Copy link

Terraform Version

0.12.0

Issue

Hi, when I run terraform plan on one of the config files, I get the following error

Error: Unsupported attribute

  on main.tf line 16, in module "project_01":
  16:   folder_id = "${data.terraform_remote_state.folders.folder_shared_id}"

This object has no argument, nested block, or exported attribute named
"folder_shared_id".

make: *** [plan] Error 1

Here is the main.tf file

data "terraform_remote_state" "folders" {
  backend = "local"
  config = {
    path = "../../folders/terraform.tfstate"
  }
}
...
<extraneous-code>
...
module "project_01" {
  source = "<path-to-module>"

  project_name = "network"
  folder_id = "${data.terraform_remote_state.folders.folder_shared_id}"
}

However, that attribute is present in the terraform.tfstate file


$ cat terraform.tfstate
{
  "version": 4,
  "terraform_version": "0.12.0",
  "serial": 9,
  "lineage": "76c68f13-3a49-4db0-2a95-84ef9610cefa",
  "outputs": {
    "folder_test1_id": {
      "value": "folders/***",
      "type": "string"
    },
    "folder_test2_id": {
      "value": "folders/****",
      "type": "string"
    },
    "folder_shared_id": {
      "value": "folders/****",
      "type": "string"
    }

This used to work in Terraform 0.11.13 but broke in Terraform 0.12.0. Any ideas why this is happening?

@ameyaptk
Copy link
Author

terraform 0.12upgrade fixed the config file by fixing the first class expressions and the error disappeared. First class expressions- https://www.hashicorp.com/blog/terraform-0-12-preview-first-class-expressions

@apparentlymart
Copy link
Member

Hi @ameyaptk!

I'm glad the upgrade tool fixed it. I just wanted to note what it changed that made this work:

In Terraform 0.12, the outputs from terraform_remote_state are collected together in an attribute called outputs, rather than being exposed directly on the terraform_remote_state object, as described in the upgrade guide section Remote state references.

Specifically, the upgrade tool would rewrite the following line:

   folder_id = "${data.terraform_remote_state.folders.folder_shared_id}"

As well as using the first-class expression syntax, it also added .outputs into this reference, to create the following:

   folder_id = data.terraform_remote_state.folders.outputs.folder_shared_id

The purpose of grouping them all together into one attribute like this is so that you can, where appropriate, use the entire collection together as a value.

@dirsigler
Copy link

Thank you very much @apparentlymart
I had the same problem and your explanation helped me fixing a big chunk of it.
It seems tho that the documentation is lacking the new configuration of TF 0.12.

Currently I have a problem created by the terraform_remote_state.

I have one folder where I create my GCP VPC

resource "google_compute_network" "default" {
  provider                = google-beta
  project                 = var.project
  name                    = "${var.name}-net"
  auto_create_subnetworks = "false"
}

resource "google_compute_subnetwork" "subnet_vpc" {
  provider                 = google-beta
  project                  = var.project
  name                     = "${var.name}-subnet-vpc"
  network                  = google_compute_network.default.self_link
  region                   = var.project_region
  ip_cidr_range            = var.cidr
  private_ip_google_access = true

  secondary_ip_range {
    range_name    = "${var.name}-secondary-cidr"
    ip_cidr_range = var.subnet["secondary_cidr"]
  }
}

with the output

output "link" {
  value = "${google_compute_network.default.self_link}"
}

and a folder for my cloudsql with following code:

data "terraform_remote_state" "vpc" {
    backend = "gcs"
    config = {
        bucket  = "tfstate-test-eu"
        prefix  = "test/vpc"
  }
}

resource "google_compute_global_address" "cloudsql_ip_address" {
  provider      = google-beta
  project       = var.project
  name          = "${var.name}-sql-iip"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = "${data.terraform_remote_state.vpc.outputs.link}"
}

resource "google_service_networking_connection" "cloudsql_vpc_connection" {
  provider                = google-beta
  network                 = "${data.terraform_remote_state.vpc.outputs.link}"
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.cloudsql_ip_address.name]
}

both folders save the tfstate in the same bucket but with a different prefix:

vpc:

terraform {
  backend "gcs" {
    bucket  = "tfstate-test-eu"
    prefix  = "test/vpc"
  }
}

cloudsql:

terraform {
  backend "gcs" {
    bucket  = "tfstate-test-eu"
    prefix  = "test/sql"
  }
}

now everytime I want to apply my terraform plan for the cloudsql, to add that ip-address to my vpc, my terraform wants to destroy the vpc but add the ip-address

  # google_compute_global_address.cloudsql_ip_address will be created
  + resource "google_compute_global_address" "cloudsql_ip_address" {
      + address            = (known after apply)
      + address_type       = "INTERNAL"
      + creation_timestamp = (known after apply)
      + id                 = (known after apply)
      + label_fingerprint  = (known after apply)
      + name               = "tf-test-sql-iip"
      + network            = "https://www.googleapis.com/compute/v1/projects/example/global/networks/tf-test-net"
      + prefix_length      = 16
      + project            = "example"
      + purpose            = "VPC_PEERING"
      + self_link          = (known after apply)
    }

  # google_compute_network.default will be destroyed
  - resource "google_compute_network" "default" {
      - auto_create_subnetworks         = false -> null
      - delete_default_routes_on_create = false -> null
      - id                              = "tf-test-net" -> null
      - name                            = "tf-test-net" -> null
      - project                         = "example" -> null
      - routing_mode                    = "REGIONAL" -> null
      - self_link                       = "https://www.googleapis.com/compute/v1/projects/example/global/networks/tf-test-net" -> null
    }

is this a problem with my terraform plan / design or something related to a bug ?
My expected behavior would be, that Terraform checks the remote backend and finds my vpc_self_link, which he uses to add the cloudsql ip-address into that vpc.

Plan: 1 to add, 0 to change, 1 to destroy.

@apparentlymart
Copy link
Member

Hi @relgisri,

That problem doesn't seem related to this issue. It looks like somehow those two configurations are being applied against the same state, and so the second operation is planning to destroy the objects created by the first.

Please note that we use GitHub issues for tracking bugs and enhancements rather than for questions. While we may be able to help with certain simple problems here it's better to use the community forum, where there are more people ready to help. The GitHub issues here are generally monitored only by our few core maintainers.

@basilmusa
Copy link

Thanks @apparentlymart. This ".outputs" hint fixed everything. I really wish error messages from terraform could suggest something like, "Did you forget to reference the .outputs. array?" or some other intelligent error messages. I wasted 2 hours trying to understand what's wrong with it.

@ozbillwang
Copy link

Thanks @basilmusa , got same issue, I can confirm this fix as well.

With terraform 0.12+, we have to add extra outputs to reference variables, for example:

data.terraform_remote_state.vpc.outputs.link

@ghost
Copy link

ghost commented Jul 24, 2019

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@hashicorp hashicorp locked and limited conversation to collaborators Jul 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants