# Can you intermingle data and resource on the same route53 hosted zone?

**URL:** <https://discuss.hashicorp.com/t/can-you-intermingle-data-and-resource-on-the-same-route53-hosted-zone/59205>\
**Category:** Terraform\
**Created:** [October 17, 2023, 7:26am UTC](https://discuss.hashicorp.com/t/can-you-intermingle-data-and-resource-on-the-same-route53-hosted-zone/59205 "2023-10-17T07:26:13Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![deantray](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/deantray/32/30782_2.png) [@deantray](https://discuss.hashicorp.com/u/deantray)\
**Post date:** [October 17, 2023, 7:26am UTC](https://discuss.hashicorp.com/t/can-you-intermingle-data-and-resource-on-the-same-route53-hosted-zone/59205/1 "2023-10-17T07:26:13Z")

</div>

I am reading some terraform code and this seems like a bad practice to me. I see this code

```auto
data "aws_route53_zone" "public_zone" {
  count = var.is_lb_public || var.is_private_nlb_with_public_cert_and_dns || var.is_public_dns ? 1 : 0

  name = var.public_route53_zone_name
  private_zone = false
}

```

and then elsewhere that zone is defined as a resource. Shouldn’t the above data block actually not exist and we should instead depend on where we actually define the hosted zone?

i wonder if this is why I run into an error on creating a new datacenter and have to sometimes manually create/delete hosted zones to get my full apply working as it errors sometimes on zone not exist (perhaps because data expects it to be there already and it is not there yet).

I found the other declaration elsewhere in the code to be

> resource “aws\_route53\_zone” “public\_zone” {  
> count = var.is\_public == true ? 1 : 0
> 
> name = var.zone\_name  
> comment = var.description  
> }

Related post [amazon ecs - Terraform: What's the point using Both Data Source and Resource on the same type? - Stack Overflow](https://stackoverflow.com/questions/54792048/terraform-whats-the-point-using-both-data-source-and-resource-on-the-same-type)

**I feel like we could be left with a race condition on first creation of datacenter where data reads before the resource creates???, true/false?**

---

<div class="post-metadata">

**Author:** ![apparentlymart](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/apparentlymart/32/702_2.png) [@apparentlymart](https://discuss.hashicorp.com/u/apparentlymart)\
**Post date:** [October 17, 2023, 6:57pm UTC](https://discuss.hashicorp.com/t/can-you-intermingle-data-and-resource-on-the-same-route53-hosted-zone/59205/2 "2023-10-17T18:57:23Z")

</div>

Hi @deantray,

Indeed, trying to treat the same object both as an external dependency (with `data`) and a managed object (with `resource`) in the same configuration is a relatively common cause of this sort of ordering problem.

Unless the configuration is written very carefully, it’s easy to accidentally write things so that Terraform cannot understand that the read of the object depends on the management of the same object elsewhere, and so it will fail during planning trying to read an object that doesn’t exist yet, or worse it will read a stale version of the object (from the previous apply) and then successfully use that stale information to plan other stuff.

Instead, I would recommend designing the module that currently contains `data "aws_route53_zone" "public_zone"` to accept an object-typed variable whose type constraint matches whatever subset of an `aws_route53_zone` managed resource object is needed by that module.

For example, if you only need the name, the zone ID, and the ARN (the three main “identifying attributes”) then you could write it like this:

```auto
variable "route53_zone" {
  type = object({
    name = string
    zone_id = string
    arn = string
  })
}

```

When calling the module, the caller can typically just assign the entire zone resource instance object, because it has compatible attributes:

```auto
module "example" {
  # ...

  route53_zone = aws_route53_zone.public_zone
}

```

Back inside the module with that `variable "route53_zone"` block, you can refer to the given object when declaring downstream objects like records:

```auto
resource "aws_route53_record" "example" {
  zone_id = var.route53_zone.zone_id
  # ...
}

```

This idea of passing whole objects between modules is one of the patterns described in the following article, which also has some other recommendations about how to split declarations across multiple composable modules:

> **[Module Composition | Terraform | HashiCorp Developer](https://developer.hashicorp.com/terraform/language/modules/develop/composition)**
>
> Module composition allows infrastructure to be described from modular
> building blocks.
