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

required field is not set #16582

Closed
ruanton29 opened this issue Nov 7, 2017 · 3 comments
Closed

required field is not set #16582

ruanton29 opened this issue Nov 7, 2017 · 3 comments

Comments

@ruanton29
Copy link

Hi
Creating module for elb and face issue with data provider
I have module elb:

resource "aws_elb" "this" {
  name = "${var.service_name}"
  listener = ["${var.listeners}"]
  health_check = "${var.health_check}"
  security_groups = ["${var.security_groups}"]
  subnets = ["${var.subnet}"]
  cross_zone_load_balancing = true
  idle_timeout = "${var.idle_timeout}"
  connection_draining = "${var.connection_draining}"
  connection_draining_timeout = "${var.connection_draining_timeout}"
  tags = "${var.tags}"
}

and have data like :

data "aws_acm_certificate" "internal" {
  domain   = "${var.certificates["internal"]}"
  statuses = ["ISSUED"]
}


module "elb" {
  source = "./modules/elb"
  service_name = "${var.service_name}"
  listeners = [
    {
      instance_port = "443"
      instance_protocol = "HTTP"
      lb_port = "433"
      lb_protocol = "HTTPS"
      ssl_certificate_id = "${data.aws_acm_certificate.internal.arn}"
    },
  ]
  security_groups = [
    "${data.state.vpc.security}"]
  subnet = [
    "${split(",",data.state.vpc.subnet)}"]
}

terraform -v
Terraform v0.10.8

Debug Output

Error: module.elb.aws_elb.this: "listener.0.instance_port": required field is not set
Error: module.elb.aws_elb.this: "listener.0.instance_protocol": required field is not set
Error: module.elb.aws_elb.this: "listener.0.lb_port": required field is not set
Error: module.elb.aws_elb.this: "listener.0.lb_protocol": required field is not set

But when i remove

ssl_certificate_id = "${data.aws_acm_certificate.internal.arn}"

It's work fine
I tried data null_resource, use data "aws_acm_certificate" as module and but there output but still have same error
Can someone tell me if it's possible to implement or not ?
Best regard
Anton

@apparentlymart
Copy link
Contributor

Hi @ruanton29! Sorry for this confusing behavior.

Assigning values to nested blocks is not supported, but appears to work in certain cases due to a number of coincidences in how Terraform represents values internally. To be more specific: it uses the Go map[string]interface{} values for a number of different purposes, and so in some cases it's possible to confuse Terraform into misinterpreting a map created for one purpose as one for another purpose, as you did here, but this will not work robustly due to different expectations about the contents of those maps in different scenarios.

So in fact, unfortunately, the bug here is that what you did ever worked at all, rather than that it failed once you added a data interpolation into the mix 😖. I expect it failed because by doing so this caused Terraform to see the whole list as <computed> during validation, but since it's not supposed to be possible to assign values to nested blocks there is no handling of <computed> there and so it fails in this strange way.

(Assigning to nested blocks is not supported because Terraform, as you can see here, wants to be able to validate the attribute names in the block and so it requires them to be enumerated physically in the configuration file. This is part of Terraform's goal of being predictable and explicit at plan time, rather than failing dynamically at some point during apply, wherever possible. This is somewhat analogous to the distinction between a struct/class and a map/dictionary in a statically-typed programming language.)

We are planning to properly support this use-case as part of our current series of configuration language improvements. This particular aspect is being discussed in #7034. Once that is implemented, it will be possible to express what you wanted to express here using the following syntax, which will then be robustly supported and tested:

# DESIGN SKETCH: not yet implemented and may change before release

resource "aws_elb" {
  # (other attributes and blocks)

  dynamic "listener" {
    foreach = "${var.listeners}"
    content {
      instance_port      = "${dynamic.foreach.instance_port}"
      instance_protocol  = "${dynamic.foreach.instance_protocol}"
      lb_port            = "${dynamic.foreach.lb_port}"
      lb_protocol        = "${dynamic.foreach.lb_protocol}"
      ssl_certificate_id = "${dynamic.foreach.ssl_certificate_id}"
    }
  }
}

The key difference with this new approach is that you still enumerate the contents of the block so that the attributes and nested block structure can be validated, and so it's only the values that can potentially be <computed>, which is then consistent with how Terraform behaves in the non-dynamic case.

Since this bug (at least, it's root cause) is already being discussed in #7034, I'm going to close this just to consolidate discussion in that issue.

I'm afraid at this time I don't have a great workaround for what you are trying to do here. Generally-speaking we don't recommend making modules that are just wrappers around existing resources that literally just pass through arguments like this, but I assume there's some other content in this module that wasn't relevant to the issue at hand that warrants this not just being a standalone aws_elb resource.

@ruanton29
Copy link
Author

@apparentlymart i understand, thx

@ghost
Copy link

ghost commented Apr 6, 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 Apr 6, 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