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

Resource missing errors propagating over validation errors during plan #18129

Closed
bflad opened this issue May 25, 2018 · 5 comments
Closed

Resource missing errors propagating over validation errors during plan #18129

bflad opened this issue May 25, 2018 · 5 comments
Milestone

Comments

@bflad
Copy link
Contributor

bflad commented May 25, 2018

Seemingly, when a validation error occurs in a resource (due to a failing ValidateFunc), terraform plan returns missing resource errors over returning the original validation error that caused the issue even though the underlying EvalValidateResource notices the error.

Terraform Version

terraform -v
Terraform v0.11.7
+ provider.aws v1.20.0
+ provider.null v1.0.0

Terraform Configuration Files

terraform {
  required_version = "0.11.7"
}

provider "aws" {
  region  = "us-east-1"
  version = "1.20.0"
}

resource "null_resource" "upstream" {
  triggers = {
    name = "invalid name"
  }
}

# aws_iam_role is an example resource that has a ValidateFunc
resource "aws_iam_role" "test" {
  assume_role_policy = "{}"
  # Hardcoding this correctly returns the validation error
  # name = "invalid name"
  name               = "${null_resource.upstream.triggers.name}"
}

resource "null_resource" "downstream" {
  triggers = {
    name = "${aws_iam_role.test.name}"
  }
}

Debug Output

https://gist.github.com/bflad/62edb26125e13dbac68d0a556523f1fd

Expected Behavior

Error: aws_iam_role.test: "name" must match [\w+=,.@-]

Actual Behavior

2018/05/25 14:48:50 [ERROR] root: eval: *terraform.EvalValidateResource, err: Warnings: []. Errors: ["name" must match [\w+=,.@-]]
2018/05/25 14:48:50 [ERROR] root: eval: *terraform.EvalSequence, err: Warnings: []. Errors: ["name" must match [\w+=,.@-]]
...
2018/05/25 14:48:50 [ERROR] root: eval: *terraform.EvalInterpolate, err: Resource 'aws_iam_role.test' not found for variable 'aws_iam_role.test.name'
2018/05/25 14:48:50 [ERROR] root: eval: *terraform.EvalSequence, err: Resource 'aws_iam_role.test' not found for variable 'aws_iam_role.test.name'

Which is output as:

* null_resource.downstream: 1 error(s) occurred:

* null_resource.downstream: Resource 'aws_iam_role.test' not found for variable 'aws_iam_role.test.name'

Steps to Reproduce

  1. terraform init
  2. terraform plan
@bflad
Copy link
Contributor Author

bflad commented Sep 19, 2018

It seems this issue also goes beyond just ValidateFunc errors not being reported. Here's a fresh example.

Given this example configuration:

# Invalid configuration - do not use this in a real environment

terraform {
  required_version = "0.11.8"
}

provider "aws" {
  version = "1.36.0"
}

resource "null_resource" "test" {}

resource "aws_launch_template" "test" {
  iam_instance_profile = ["${null_resource.test.id}"]
}

output "test" {
  value = "${aws_launch_template.test.id}"
}

And this resource schema:

"iam_instance_profile": {
	Type:     schema.TypeList,
	Optional: true,
	MaxItems: 1,
	Elem: &schema.Resource{
		Schema: map[string]*schema.Schema{
			// ...
		},
	},
},

On Terraform 0.11.8, it seems to output a configuration validation error correctly along with the Resource X not found error, but only when both the aws_launch_template resource and its reference are being created at the same time. On first terraform apply:

2 error(s) occurred:

* output.test: Resource 'aws_launch_template.test' not found for variable 'aws_launch_template.test.id'
* aws_launch_template.test: iam_instance_profile.0: expected object, got string

On the second terraform apply it just reports the unhelpful error (from the debug logs we are able to see that the validation error should have been reported):

2018/09/19 11:05:55 [ERROR] root: eval: *terraform.EvalValidateResource, err: Warnings: []. Errors: [iam_instance_profile.0: expected object, got string]
2018/09/19 11:05:55 [ERROR] root: eval: *terraform.EvalSequence, err: Warnings: []. Errors: [iam_instance_profile.0: expected object, got string]
2018/09/19 11:05:55 [TRACE] [walkPlan] Exiting eval tree: aws_launch_template.test

2018/09/19 11:05:55 [DEBUG] plugin: waiting for all plugin processes to complete...
Error: Error running plan: 1 error(s) occurred:

* output.test: Resource 'aws_launch_template.test' not found for variable 'aws_launch_template.test.id'

@apparentlymart
Copy link
Contributor

I tried the following modified version of the first example in v0.12.0-alpha2:

provider "aws" {
  region = "us-east-1"
}

resource "null_resource" "upstream" {
  triggers = {
    name = "invalid name"
  }
}

# aws_iam_role is an example resource that has a ValidateFunc
resource "aws_iam_role" "test" {
  assume_role_policy = "{}"
  # Hardcoding this correctly returns the validation error
  # name = "invalid name"
  name = "${null_resource.upstream.triggers.name}"
}

resource "null_resource" "downstream" {
  triggers = {
    name = "${aws_iam_role.test.name}"
  }
}

The incorrect message about aws_iam_role.test not being set is gone (:tada:) but it looks like the validation error is still not showing up:

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_iam_role.test will be created
  + resource "aws_iam_role" "test" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + max_session_duration  = 3600
      + name                  = "invalid name"
      + path                  = "/"
      + unique_id             = (known after apply)
    }

  # null_resource.downstream will be created
  + resource "null_resource" "downstream" {
      + id       = (known after apply)
      + triggers = {
          + "name" = "invalid name"
        }
    }

  # null_resource.upstream will be created
  + resource "null_resource" "upstream" {
      + id       = (known after apply)
      + triggers = {
          + "name" = "invalid name"
        }
    }

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

The local validation didn't run during terraform apply either, so the error ended up reported from the remote API instead:

Error: Error creating IAM Role invalid name: ValidationError: The specified value for roleName is invalid. It must contain only alphanumeric characters and/or the following: +=,.@_-
	status code: 400, request id: 30854322-dcae-11e8-b38b-47a25fcbf39e

  on resource-validation-masked.tf line 17:
  17: }

Amusingly though, when I ran terraform destroy it did catch the validation error in the provider:

Error: "name" must match [\w+=,.@-]

  on resource-validation-masked.tf line 17:
  17: }

This over-zealous validation during destroy is likely just another instance of #19216, not directly related to this issue.

It looks like there's still a validation-related bug here for us to take care of before v0.12.0 final, so I'm going to mark this with the v0.12.0 milestone.


For the second example in the later comment, I did at least get a reasonable error message out of it:

Error: Unsupported attribute

  on resource-validation-masked.tf line 28, in resource "aws_launch_template" "test":
  28:   iam_instance_profile = ["${null_resource.test.id}"]

An attribute named "iam_instance_profile" is not expected here. Did you mean
to define a block of type "iam_instance_profile"?

However, this particular problem is now caught be Terraform Core (by referring to the schema) rather than by the provider itself, so it makes sense that this one would work even if Terraform does not properly pass through the results of the provider's own validation: this error is detected and returned before ValidateResourceConfig is even called on the provider.

@apparentlymart
Copy link
Contributor

apparentlymart commented Dec 17, 2018

I just re-tested this on v0.12.0-alpha4 and verified that it is now fixed:

$ terraform apply

Error: "name" must match [\w+=,.@-]

  on resource-validation-masked.tf line 12, in resource "aws_iam_role" "test":
  12: resource "aws_iam_role" "test" {

The error message form is still a little strange because the providers and provider SDK could do with some more work to improve these, but that work will happen asynchronously from v0.12.0 development since these error messages are not coming from the main core executable and can thus be updated at any time.

Thanks for reporting this, @bflad!

@ghost
Copy link

ghost commented Mar 30, 2020

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.

@ghost ghost locked and limited conversation to collaborators Mar 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants