1
votes

I'm currently using Terraform to standup infrastructure in AWS, as part of the instantiation of each compute instance, it calls out to the AWS meta service and EC2 API to set its hostname.

Any instances that are placed in the private subnet of my VPC will not have access to the internet until I have configure a squid proxy instance (will likely be handled by Ansible).

To allow all instances in my VPC to talk to the EC2 API I have configured a VPC Endpoint. Unfortunately there is no such endpoint to talk to Route53. This means that I'm unable to set the private DNS records for each instance as it gets created.

I'm unsure how to manage the setup of DNS entries for each of these hosts. The private subnet will eventually talk to the internet via a reverse proxy (squid proxy) but I would like to avoid making the reverse proxy a dependency for the initial setup.

My only thought is to use a "Configuration" instance that lives in the public subnet, each instance in the private subnet can report its hostname to the "Configuration" instance, which can then call out to the Route53 API.

It may be worth noting that the hostnames for some of these instances will be dynamic and therefore can't be set by Terraform.

3
Where are you running the TF script from (control host)? If the control host can access R53 endpoint and if you know the zoneid, create the internal DNS from the control host. The control host has to have access to EC2 endpoint, otherwise it cannot launch instances. - helloV
It's currently running from my local machine - mcp005

3 Answers

2
votes

You may be going about that in a little more complicated method. Terraform (TF) can use the data from any resource you use in the other resources.

resource "aws_instance" "foo" {}
resource "aws_route53_zone" "example_private" {}

can be referenced by a route call

resource "aws_route53_record" "foo" {
  zone_id = "${aws_route53_zone.example_private.zone_id}"
  name    = "foo"
  type    = "A"
  ttl     = 300
  record  = [ "${aws_instance.foo.private_ip}" ]
}

This will create a record in the example_private domain using the private IP address of instance foo. Also your private instances will talk internally to AWS. There is no requirement for it to have internet access out to the public internet.

1
votes

If I understand your issue correctly you want to have the EC2 instances you create with Terraform to register in R53?

Depending on where you are running TF from can't you create a Route53 record at the same time as you stand up the instance? I would not have thought that you would need internet access to call out to the AWS API for this but could be wrong.

If you run the TF from a bastion in the public subnet would that solve the issue?

0
votes

The best bet is to achieve it through Instance role or API Key and Userdata. Using this procedure, you can do anything you want - like trigger Jenkins, updating any AWS information. As it will be a template from terraform, you can customize a lot more with its variables.

Please let me know how it goes.

 #!/bin/bash
export http_proxy=X.X.X.X:3128
export https_proxy=X.X.X.X:3128

# Configure API Keys here if you don't have instance role.

# Gathering information about the instance
AZ=`curl http://169.254.169.254/latest/meta-data/placement/availability-zone`
REGION="`echo \"$AZ\" | sed 's/[a-z]$//'`"
INSTANCEID=`curl http://169.254.169.254/latest/meta-data/instance-id`

# NAME=`curl http://169.254.169.254/latest/meta-data/local-hostname`
NAME = test.example.com

# Setting the hostname of the instance
aws ec2 create-tags --region $REGION --resources $INSTANCEID --tags Key=Name,Value=$NAME