Terraform-provider-aws: Feature request: Route 53 Resolver endpoint resource

Created on 22 Nov 2018  ยท  21Comments  ยท  Source: hashicorp/terraform-provider-aws

Add a Route 53 Resolver endpoint resource.
Related:

new-resource servicroute53resolver

Most helpful comment

Any update of this? We need this too. :)

All 21 comments

Suggested syntax:

resource "aws_route53_resolver_endpoint" "foo" {
  direction = "INBOUND"
  name      = "terraform-testacc-r53-resolver-foofoo"

  security_group_ids = [
    "${aws_security_group.sg1.id}",
    "${aws_security_group.sg2.id}",
  ]

  ip_address {
    subnet_id = "${aws_subnet.sn1.id}"
  }

  ip_address {
    subnet_id = "${aws_subnet.sn3.id}"
    ip        = "10.0.64.4"
  }

  tags {
    Env = "Prod"
  }
}

+1

I would also like to see the resources related to other pieces of the R53 Resolver functionality added, such as rule creation and VPC assignment to said rules for outgoing forwarders.

I agree, the way I've worked around this was adding local exec that invoked the aws cli commands for the resolver endpoints and rules.

+1

@jankarltommy would you please share more information about how you run aws-cli in local exec?

EDIT: Added output logic for ID

@JadyLiu

Here is what I cooked up to create the resolver endpoint through Terraform:

############################
#Vars
#############################
variable "creator-request-id" {
  type = "string"
  description = "A unique string that identifies the request"
  default = "terraform-created"
}


variable "direction" {
  type = "string"
  description = "The direction for the endpoint, possible values are: INBOUND or OUTBOUND"
}

variable "subnet-ids" {
  type = "list"
  description = "the subnet"
}

variable "security-groups" {
  type = "list"
  description = "The security groups associated with the provided subnets"
}

variable "ip-addresses" {
  type = "list"
  description = "The list of IP address to associate for the subnet - if non-dynamic is desired"
}

variable "endpoint-name" {
  type = "string"
  description = "A friendly name that lets you easily find a configuration in the Resolver dashboard in the Route 53 console"
}

variable "profile" {
  type = "string"
  description = "The AWS CLI profile to use"
}

variable "tags" {
  type = "string"
  description = "A list of the tag keys and values that you want to associate with the endpoint."
  // Syntax Key=string,Value=string ...
  // Example Key=owner,Value=John Doe,Key=terraform_managed,Value=true
}
############################
# Resources
############################
data "template_file" "log_name" {
  template = "${path.module}/output.log"
}

data "template_file" "endpoint-id" {
  template = "${path.module}/id.log"
}

data "local_file" "createEndpoint" {
  filename = "${data.template_file.log_name.rendered}"
  depends_on = ["null_resource.createEndpoint"]
}

data "local_file" "readId" {
  filename = "${data.template_file.endpoint-id.rendered}"
  depends_on = ["null_resource.getId"]
}

resource "null_resource" "createEndpoint" {
  provisioner "local-exec" {
    command = "aws route53resolver create-resolver-endpoint --creator-request-id ${var.creator-request-id} --security-group-ids ${local.security-groups} --direction ${var.direction} --ip-addresses ${local.ip-list} --name ${var.endpoint-name} --tags ${var.tags} --profile ${var.profile} > ${data.template_file.log_name.rendered}"
  }
}

resource "null_resource" "getId" {
  provisioner "local-exec" {
    command = "aws route53resolver list-resolver-endpoints --profile ${var.profile} --output text --query ResolverEndpoints[?Name=='${var.endpoint-name}'].Id  > ${data.template_file.endpoint-id.rendered}"
  }
  depends_on = ["null_resource.createEndpoint"]
}


data "template_file" "ips" {
  count = "${length(var.subnet-ids)}"
  template = "SubnetId=${var.subnet-ids[count.index]},Ip=${var.ip-addresses[count.index]} "
}

data "template_file" "security-groups" {
  count = "${length(var.security-groups)}"
  template = "${var.security-groups[count.index]} "
}

locals {
  ip-list = "${join(" ",data.template_file.ips.*.rendered)}"
  security-groups = "${join(" ",data.template_file.security-groups.*.rendered)}"
}
############################
# Outputs
############################
output "file" {
  value = "${data.template_file.log_name.rendered}"
}

output "log" {
  value = "${data.local_file.createEndpoint.content}"
}

output "id" {
  value = "${trimspace(data.local_file.readId.content)}"
}

This will allow you create the endpoints, I did something very similar for the other cli commands. The catch here is that you need to make sure your aws access & secret keys are set along with a ~/.aws/config file. This is why there is a variable for the profile. In my pipeline I do the following:

- export AWS_ACCESS_KEY_ID=$TERRAFORM_ACCESS_KEY
- export AWS_SECRET_ACCESS_KEY=$TERRAFORM_SECRET_KEY
- export AWS_DEFAULT_REGION="us-east-1"
- export TF_IN_AUTOMATION=true
- export AWS_CONFIG_FILE=$AWS_CONFIG_FILE

- curl -s --request GET   //LOCATION WHERE MY CONFIG FILE IS

The other catch is that the endpoint id is not something that is available after executing the command, rather the entire output as a whole is stored. I suppose the resolverId could be grepped through another local exec that reads the local_file and stores it into another file, which we then output again. I'm not a big fan of this solution but it's a temporary solution until we have a route53resolver. Hope this helps!

Any update of this? We need this too. :)

Any updates? getting off BIND/DNS servers and looking to implement this across 200+ aws accounts.

So very interested in this

Really looking forward to this (+ all R53 Resolver related resources)

+1

This resource has been merged and will release with version 2.1.0 of the Terraform AWS Provider.

This has been released in version 2.1.0 of the AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

Hi @ewbankkit , Thank you so much for adding the aws_route53_resolver_endpoint in v2.1.0.
I tried using the aws_route53_resolver_endpoint but it errors out saying that that it requires 2 IP addresses even though I have provided it. Even if I don't add the IP addresses as those are optional, it errors out. Any pointers regarding this? Also When will the 2.3.x version be released with outbound rule association?
Thanks!

resource "aws_route53_resolver_endpoint" "route53_resolver_in" {
  name      = "Inbound_EP"
  direction = "INBOUND"

  security_group_ids = [
    "${aws_security_group.kubernetes_control.id}"
  ]

  ip_address {
    subnet_id = "${aws_subnet.kubernetes_control_sub.id}"
    ip = "10.43.60.21"
  }

  ip_address {
    subnet_id = "${aws_subnet.kubernetes_control_sub.id}"
    ip = "10.43.50.21"
  }

  tags {
    Owner = "${var.owner}"
    Name = "Inbound_endpoint"
  }
}

ERROR: * aws_route53_resolver_endpoint.route53_resolver_in: error creating Route53 Resolver endpoint: InvalidRequestException: [RSLVR-00400] Resolver endpoint need to have at least 2 IP addresses. status code: 400, request id: 29c6f1e0-9d36-4ed3-8a42-b0d5932bebe4

@pjain17 can you try two unique subnet_ids?
Also aws provided 2.2.0 already supports rules and rule associations.

I have a question though. Why is there a mandate to use 2 IP addresses/subnets? Why can't we just select one and create a resolver? By using AWS UI console, it allows to create resolver with one subnet/ip

@pjain17 See https://github.com/terraform-providers/terraform-provider-aws/issues/7950#issuecomment-473439150 as to why we are currently using just subnet_id (and not including ip) to define uniqueness for the ip_address attribute.

@an-sush There was a discussion around this during the review of the PR, see https://github.com/terraform-providers/terraform-provider-aws/pull/6574#pullrequestreview-208664306. Even though the API says that the minimum number of IPs is 1 we found that an error returned with less than 2.
I'll check via the console.

@pjain17 thanks for reporting the issue, and @an-sush @ewbankkit thanks for helping out. Commenting on closed issues makes it difficult to track the thread. Would you mind opening a new issue or adding your comments to the already open issue #7950, as they are all related.

@an-sush In the us-west-2 Console I see the text

To improve reliability, Resolver requires that you specify two IP addresses for DNS queries. We recommend that you specify IP addresses in two different Availability Zones. After you add the first two IP addresses, you can optionally add more in the same or different Availability Zones.

I know this issue is closed, but we just ran into the same issue as @pjain17 with aws_route53_resolver_endpoint failing to create the IP endpoints, and we found a solution.

Here's the TF debug output that was indicating the problem:

2019-08-27T14:56:52.073-0400 [DEBUG] plugin.terraform-provider-aws_v2.25.0_x4: 2019/08/27 14:56:52 [INFO] Route 53 Resolver endpoint <redacted> status message: 2 IP address(es) failed to be created. Please remove them from the ResolverEndpoint.

Unfortunately, this is fairly cryptic and generally unhelpful in locating the problem.

We had the permissions for our Terraform role locked down to only what we needed, adding each permission as Terraform indicated through errors. We couldn't figure this problem out however, until we found this doc:
https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/r53-api-permissions-ref.html#required-permissions-resolver
All the permissions listed, including the ec2 perms, need to be added for aws_route53_resolver_endpoint to work. Terraform wasn't showing errors for the ec2 perms, only the route53resolver perms (if we didn't have them added to our role). Once we added the listed perms to our role, everything worked without problems.

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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

Was this page helpful?
0 / 5 - 0 ratings