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

terraform lists - depends_on doesn't work #17156

Closed
AndriiOmelianenko opened this issue Jan 22, 2018 · 7 comments
Closed

terraform lists - depends_on doesn't work #17156

AndriiOmelianenko opened this issue Jan 22, 2018 · 7 comments
Milestone

Comments

@AndriiOmelianenko
Copy link

Terraform Version

Terraform v0.11.2
+ provider.aws v1.3.1

Terraform Configuration Files

resource "aws_route53_zone" "domains" {
  name = "${element(var.aws_domains, count.index)}"
  count = "${length(var.aws_domains)}"
}

resource "aws_route53_record" "base-nss" {
  name = "${element(var.aws_domains, count.index)}"
  count = "${length(var.aws_domains)}"
  type = "NS"
  zone_id = "${data.aws_route53_zone.base.id}"
  ttl = 30

  records = [
    "${aws_route53_zone.domains.*.name_servers.0[count.index]}",
    "${aws_route53_zone.domains.*.name_servers.1[count.index]}",
    "${aws_route53_zone.domains.*.name_servers.2[count.index]}",
    "${aws_route53_zone.domains.*.name_servers.3[count.index]}",
  ]
  depends_on = ["aws_route53_zone.domains"]
}

tfvars file, I have add zone to be created

aws_domains = ["test1.example.com"]

Expected Behavior

I am trying to create list of domains zones by reading terraform variable, which contains list of expected domains. Terraform should create domain zone and add NS records set to another domain zone.

Actual Behavior

Seems it's trying to set up base-nss first, even though I have set depends_on = ["aws_route53_zone.domains"]

Error: Error running plan: 1 error(s) occurred:

* aws_route53_record.base-nss: 1 error(s) occurred:

* aws_route53_record.base-nss: Resource 'aws_route53_zone.domains' does not have attribute 'name_servers.0' for variable 'aws_route53_zone.domains.*.name_servers.0'

Steps to Reproduce

Additional Context

References

@AndriiOmelianenko AndriiOmelianenko changed the title terraform lists - index 1 out of range for list terraform lists - depends_on doesn't work Jan 22, 2018
@jbardin
Copy link
Member

jbardin commented Jan 22, 2018

Hi @AndriiOmelianenko,

The depends_on attribute isn't needed here (it doesn't do anything at all in this case), because you're already referencing aws_route53_zone.domains in the config.

What I'm not sure about is what you're trying to do with the ...name_servers.0[count.index] portion of the interpolation. If you explain the output you expect to see, I think we can find the right configuration to get you there.

@AndriiOmelianenko
Copy link
Author

Hi @jbardin,
basically I'm trying to create subdomains (as reference), but for list of subdomains (specified in tfvars file).

"${aws_route53_zone.domains.*.name_servers.0[count.index]}" gives me first name server of first subdomain in a list (as my list only contains one subdomain at the moment).

the main problem is, that if I run terraform apply -target=route53_zone.domains - it will create subdomain successfully, and then I run just terraform apply - it successfully creates NS records also.

so the config is kind of working, but I can't make it work in single terraform apply, as it tries to create aws_route53_record.base-nss first.

@jbardin
Copy link
Member

jbardin commented Jan 22, 2018

I think I see what you want, it's just that the interpolation you've supplied isn't going to work. It's not that terraform is trying to create aws_route53_record.base-nss first, it's just that the interpolation can't resolve the attributes how you want.

We're undergoing a revamp of the configuration language right now, in which we will be able to make improvements to the interpolation language as well. Until then, it often helps to break up the interpolation into intermediate values. For example, I think the following portion of the config will get you the values you're looking for:

locals {
  name_servers = "${aws_route53_zone.domains.*.name_servers}"
}

resource "aws_route53_record" "base-nss" {
  name = "${element(var.aws_domains, count.index)}"
  count = "${length(var.aws_domains)}"
  type = "NS"
  zone_id = "${aws_route53_zone.base.id}"
  ttl = 30

  records = [
    "${element(local.name_servers[count.index], 0)}",
    "${element(local.name_servers[count.index], 1)}",
    "${element(local.name_servers[count.index], 2)}",
    "${element(local.name_servers[count.index], 3)}",
  ]
  depends_on = ["aws_route53_zone.domains"]
}

@AndriiOmelianenko
Copy link
Author

@jbardin thanks for your help, now it is working as expected, creating domain and record set successfully.

When going through scenario, where I create 2 domain zones, and then add third one to the list - It's also tries to update previously created record sets, but as long as they are not changed, I think it's ok.

  ~ aws_route53_record.base-nss[0]
      records.#:        "" => <computed>

  ~ aws_route53_record.base-nss[1]
      records.#:        "" => <computed>

  + aws_route53_record.base-nss[2]
      id:               <computed>
      fqdn:             <computed>
      name:             "test3.example.com"
      records.#:        <computed>
      ttl:              "30"
      type:             "NS"
      zone_id:          "DSFSDFSD"

@gswallow
Copy link

gswallow commented Feb 7, 2018

Is the issue that the aws_route53_zone resource doesn't support depends_on at all? I took your code example (#17156 (comment)) and used it to declare a txt record that depends on the things I want to ensure that our route53 zones are created correctly but it seems like a terrible hack:

resource "aws_route53_record" "txt" {
  name = "creator"
  type = "TXT"
  zone_id = "${aws_route53_zone.public.id}"
  ttl = 300

  records = [
    "Created by terraform"
  ]
  depends_on = [
    "aws_route53_zone.public",
    "aws_route53_query_log.public",
    "aws_cloudwatch_log_group.public"
  ]
}

@apparentlymart
Copy link
Contributor

Hi all! Sorry for the long silence here.

I just tried the following configuration with the v0.12.0-alpha1 prerelease build:

provider "aws" {
  region = "us-west-2"
}

variable "aws_domains" {
  default = [
    "exampl.com",
    "exampl.net",
    "exampl.org",
  ]
}

resource "aws_route53_zone" "domains" {
  name  = "${element(var.aws_domains, count.index)}"
  count = "${length(var.aws_domains)}"
}

resource "aws_route53_record" "base-nss" {
  name    = "${element(var.aws_domains, count.index)}"
  count   = "${length(var.aws_domains)}"
  type    = "NS"
  zone_id = "blahblahplaceholder"
  ttl     = 30

  records = [
    "${aws_route53_zone.domains.*.name_servers.0[count.index]}",
    "${aws_route53_zone.domains.*.name_servers.1[count.index]}",
    "${aws_route53_zone.domains.*.name_servers.2[count.index]}",
    "${aws_route53_zone.domains.*.name_servers.3[count.index]}",
  ]
}

I adapted this from the one in the initial comment on this issue. It isn't possible for it to be fully created since I don't have a real zone for those NS records to go into, but it's enough to verify that things are now working as expected.

After the first apply I created the three zones and got the errors I expected about blahblahplaceholder not being a valid zone id. Then I ran terraform plan again to see how those complex reference expressions were being resolved:

  # aws_route53_record.base-nss[0] will be created
  + resource "aws_route53_record" "base-nss" {
      + allow_overwrite = true
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = "exampl.com"
      + records         = [
          + "ns-1466.awsdns-55.org",
          + "ns-74.awsdns-09.com",
          + "ns-881.awsdns-46.net",
          + "ns-1868.awsdns-41.co.uk",
        ]
      + ttl             = 30
      + type            = "NS"
      + zone_id         = "blahblahplaceholder"
    }

This confirms that the expression is now being resolved as expected. However, the new configuration language implementation also allows this to be written in a more readable way:

resource "aws_route53_record" "base-nss" {
  name    = var.aws_domains[count.index]
  count   = length(var.aws_domains)
  type    = "NS"
  zone_id = "blahblahplaceholder"
  ttl     = 30

  records = aws_route53_zone.domains[count.index].name_servers
}

This produces the same plan:

  # aws_route53_record.base-nss[0] will be created
  + resource "aws_route53_record" "base-nss" {
      + allow_overwrite = true
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = "exampl.com"
      + records         = [
          + "ns-1466.awsdns-55.org",
          + "ns-74.awsdns-09.com",
          + "ns-881.awsdns-46.net",
          + "ns-1868.awsdns-41.co.uk",
        ]
      + ttl             = 30
      + type            = "NS"
      + zone_id         = "blahblahplaceholder"
    }

This fix is in the master branch ready to be included in the forthcoming v0.12.0 final release, so I'm going to close this out. Thanks for reporting this, and thanks for your patience while we got all of this fixed up.

@ghost
Copy link

ghost commented Mar 31, 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 31, 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

4 participants