terraform add route53 record to multiple zones - terraform

I want to add the same route53 record into multiple zones, and I can't figure it out.
I'm trying this
resource "aws_route53_zone" "internal-common-domain" {
name = "${var.internal-common-domain}"
vpc_id = "${aws_vpc.VPC.id}"
}
resource "aws_route53_zone" "internal-office-domain" {
name = "${var.env}-${var.internal-common-domain}"
vpc_id = "${aws_vpc.VPC.id}"
}
resource "aws_route53_record" "middle-tier-lb" {
zone_id = "${aws_route53_zone.*.zone_id}"
name = "middle-tier-elb.${var.internal-common-domain}"
type = "CNAME"
ttl = "300"
records = ["${aws_alb.MiddleTierLoadBalancer.dns_name}"]
}
So rather than defining a record resource for each zone I want to add it to I just want to add this record to all the defined zones.
Note the splat in the record for zone_id, doesn't work, Can anyone tell me the most efficient way to do this in terraform ?

Related

How to get existing domain name on route53 by terraform

I want to make a record in the existing dns name on route53. How can I do this in terraform?
You can add DNS records to existing zones by using the "aws_route53_record"
resource "aws_route53_record" "www" {
zone_id = aws_route53_zone.primary.zone_id
name = "www.example.com"
type = "A"
ttl = "300"
records = [aws_eip.lb.public_ip]
}
official reference: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record

Terraform: creation of resources with nested loop

I have created a bunch of VPC endpoints in one AWS account and need to share them with other VPCs across different accounts. Break down of my terraform code is provided below.
Created the Route53 private hosted zones (Resource#1 for easy reference) as below
resource "aws_route53_zone" "private" {
for_each = local.vpc_endpoints
name = each.value.phz
vpc {
vpc_id = var.vpc_id
}
lifecycle {
ignore_changes = [vpc]
}
tags = {
Name = each.key
}
}
Created vpc association authorizations (Resource#2). The VPC ID, to which the endpoints are to be shared is passed as a variable as shown below.
resource "aws_route53_vpc_association_authorization" "example" {
for_each = local.vpc_endpoints
vpc_id = var.vpc
zone_id = aws_route53_zone.private[each.key].zone_id
}
Finally, I have created the VPC associations (Resource#3)
resource "aws_route53_zone_association" "target" {
for_each = aws_route53_vpc_association_authorization.example
provider = aws.target-account
vpc_id = aws_route53_vpc_association_authorization.example[each.key].vpc_id
zone_id = aws_route53_vpc_association_authorization.example[each.key].zone_id
}
Everything works fine for the first VPC (vpc-A). But now I need to share the same hosted zones (Resource#1) with a different VPC (vpc-B) and more VPCs in the future. This means I need to repeat the creation of "aws_route53_vpc_association_authorization" (Resource#2) for all new VPCs as well, ideally looping through a list of VPC IDs.
But I am unable to it as nested for_each loop is not supported. Tried other options like count + for_each etc., but nothing help.
Could you provide some guidance on how to achieve this?

Terraform: Multiple ACM certificates

I'm trying to write some TF that, given a single FQDN for a site, will generate an ACM certificate, create the R53 records for validation and run the validation in a single TF pass.
I'm not using subdomains, and I got it working for a single FQDN, but as is the nature with TF, I want to be able to add another FQDN to the variable in the future to have multiple certs.
When I run the below code I get the error:
Error: Error running plan: 1 error occurred:
* aws_acm_certificate_validation.cert: 2 errors occurred:
* aws_acm_certificate_validation.cert[0]: Resource 'aws_route53_record.cert_validation' does not have attribute 'fqdn' for variable 'aws_route53_record.cert_validation.*.fqdn'
* aws_acm_certificate_validation.cert[1]: Resource 'aws_route53_record.cert_validation' does not have attribute 'fqdn' for variable 'aws_route53_record.cert_validation.*.fqdn'
But I know that the R53 record does export the fqdn attribute.
acm.tf:
resource "aws_acm_certificate" "cert" {
count = "${length(var.certificate_fqdns)}"
domain_name = "${element(var.certificate_fqdns, count.index)}"
validation_method = "DNS"
tags = "${local.all_tags}"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "cert_validation" {
count = "${length(var.certificate_fqdns)}"
name = "${lookup(local.domain_validation_options[count.index], "resource_record_name")}"
type = "${lookup(local.domain_validation_options[count.index], "resource_record_type")}"
zone_id = "${data.aws_route53_zone.cert_fqdn_zone.*.id}"
records = ["${lookup(local.domain_validation_options[count.index], "resource_record_value")}"]
ttl = 60
}
resource "aws_acm_certificate_validation" "cert" {
count = "${length(var.certificate_fqdns)}"
certificate_arn = "${element(aws_acm_certificate.cert.*.arn, count.index)}"
validation_record_fqdns = ["${aws_route53_record.cert_validation.*.fqdn}"]
}
variables.tf:
variable "certificate_fqdns" {
description = "The FQDNs to be used to create ACM certificates."
type = "list"
default = []
}
locals {
domain_validation_options = "${flatten(aws_acm_certificate.cert.*.domain_validation_options)}"
}
data "aws_route53_zone" "cert_fqdn_zone" {
name = "${element(var.certificate_fqdns, count.index)}"
}
and my vars file contains an entry like this:
"certificate_fqdns": [
"example.com"
]
EDIT: Added the data lookup for the Route53 Zones, which only seems to return the zone for the first domain provided in the variable even when there are multiple, different domains. i.e. example1.com and example2.com it will use the same zone ID for both sets of R53 records which will obviously fail

Using "count" in aws_route53_record terrafrom resource

I'm starting to use (and learn) terraform, for now, I need to create multiple DO droplets and attach them to the aws route53 zone, what I'm trying to do:
My DO terraform file:
# Configure the DigitalOcean Provider
provider "digitalocean" {
token = var.do_token
}
# Create a new tag
resource "digitalocean_tag" "victor" {
name = "victor-fee1good22"
}
resource "digitalocean_droplet" "web" {
count = 2
image = var.do_config["image"]
name = "web-${count.index}"
region = var.do_config["region"]
size = var.do_config["size"]
ssh_keys = [var.public_ssh_key, var.pv_ssh_key]
tags = [digitalocean_tag.victor.name]
}
My route53 file:
provider "aws" {
version = "~> 2.0"
region = "us-east-1"
access_key = var.aws_a_key
secret_key = var.aws_s_key
}
data "aws_route53_zone" "selected" {
name = "devops.rebrain.srwx.net"
}
resource "aws_route53_record" "www" {
сount = length(digitalocean_droplet.web)
zone_id = data.aws_route53_zone.selected.zone_id
name = "web_${count.index}"
type = "A"
ttl = "300"
records = [digitalocean_droplet.web[count.index].ipv4_address]
}
But I always get The "count" object can be used only in "resource" and "data" blocks, and only
when the "count" argument is set. error, what did I wrong?
Thanks!
UPDATE:
I've resolved this one like — add сount = 2 instead of сount = length(digitalocean_droplet.web)
It works but would be better to have the dynamic variable instead of constant count. :)
you want to get number of services, that not yet created. Terraform couldn't do that.
As I think simplest way use common var with the number of droplets.
resource "digitalocean_droplet" "test" {
count = var.number_of_vps
image = "ubuntu-18-04-x64"
name = "test-1"
region = data.digitalocean_regions.available.regions[0].slug
size = "s-1vcpu-1gb"
}
resource "aws_route53_record" "test" {
count = var.number_of_vps
zone_id = data.aws_route53_zone.primary.zone_id
name = "${local.login}-${count.index}.${data.aws_route53_zone.primary.name}"
type = "A"
ttl = "300"
records = [digitalocean_droplet.test[count.index].ipv4_address]
}
This trick helped - https://github.com/hashicorp/terraform/issues/12570#issuecomment-291517239
resource "aws_route53_record" "dns" {
count = "${length(var.ips) > 0 ? length(var.domains) : 0}"
// ...
}

Pull subnet ID from existing resource

In Terraform, I want to build a Azure route table and assign it to an existing subnet. To do this, I need the subnet_id. Is there an easy way to pull this information into Terraform?
Below is the route table association resource I am using.
resource "azurerm_subnet_route_table_association" "test" {
subnet_id = "${data.azurerm_subnet.spoke.subnet_id}"
route_table_id = "${module.routetable.routetable_id}"
}
Assuming you already set up data.azurerm_subnet.spoke, it looks like your mistake is using subnet_id instead of just id.
resource "azurerm_subnet_route_table_association" "test" {
subnet_id = "${data.azurerm_subnet.spoke.id}"
route_table_id = "${module.routetable.routetable_id}"
}
The documentation shows which values are available under Attributes Reference.
If you haven't set up the data source, it should look something like this:
data "azurerm_subnet" "spoke" {
name = "<NAME>"
virtual_network_name = "<VIRTUAL_NETWORK_NAME>"
resource_group_name = "<RESOURCE_GROUP_NAME>"
}

Resources