2

My setup is the following: i have a VPC consisting of 3 subnets: public, private with NAT and isolated. I have an elastic beanstalk (single instance) environment running in the private subnet with Nat and it works.

What i want to achieve: have a private hosted zone with a record pointing to my private EB env.

What i'm struggling with: the environment DNS of my EB env points to its public ip (which is not reachable since its in a private subnet and thats good). But to create a DNS record pointing to my private EB env i need a private endpoint of my env, right? How do i get a URL like the public one for my env (e.g. myapp.eu-central-1.elasticbeanstalk.com) but resolving to my private ip, not the public one?

1
  • Still haven't figured out how to get a private DNS for my single instance EB env but solved it by hardcoding the instances internal IP into my DNS record. However this is suboptimal since the ip changes when i redeploy the env. As i understand this is not a problem when using a private load balanced (multi instance) eb env in a private subnet. Commented Jan 5, 2022 at 11:21

2 Answers 2

3

We had the same issue and ended up going the same route you mentioned in your comment -- hardcoding the private ipv4 in a route53 record.

However we were able to automate the process, mostly:

Add EB ENVs to target Route 53 Record

Find the Hosted Zone ID for the domain you'll be updating. Will be listed in the Hosted Zones section of Route 53 and look like Z1GP4MFDYUK339

Choose a Record Name that you'll want to update within that zone. Will be like subdomain.example.com

In your Elastic Beanstalk Environment properties add the following:

  • HOSTED_ZONE --> Hosted Zone ID
  • APP_DOMAIN --> Record Name

Create .ebextensions command to update record on deploy

In your app's project (root) directory create the following file

.ebextensions/99_dns.config 

The contents of 99_dns.config:

commands: 01_update_r53: command: | IP=$(curl --silent http://169.254.169.254/latest/meta-data/local-ipv4) APP_DOMAIN=$(/opt/elasticbeanstalk/bin/get-config environment -k APP_DOMAIN) HOSTED_ZONE=$(/opt/elasticbeanstalk/bin/get-config environment -k HOSTED_ZONE) echo "{\"Comment\":\"Update IP\",\"Changes\":[{\"Action\": \"UPSERT\",\"ResourceRecordSet\":{\"Name\":\""$APP_DOMAIN".\",\"Type\":\"A\",\"TTL\":60,\"ResourceRecords\":[{\"Value\":\""$IP"\"}]}}]}" > awsr53.json aws route53 change-resource-record-sets \ --hosted-zone-id "$HOSTED_ZONE" \ --change-batch file://awsr53.json 

When your application is deployed it will:

  • query for its local (private) IP address
  • get the APP_DOMAIN and HOSTED_ZONE values you set from ENVs
  • use the aws cli to create/update the record at HOSTED_ZONE@RECORD to be an A record with a value of the private address
0

The answer of Matt was very useful to me, it worked. But I had to make some changes:

commands: 01_update_r53: command: | IMDSTOKEN=$(curl --silent -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") IP=$(curl --silent -H "X-aws-ec2-metadata-token: $IMDSTOKEN" http://169.254.169.254/latest/meta-data/local-ipv4) AWS_R53_APP_DOMAIN=$(/opt/elasticbeanstalk/bin/get-config environment -k AWS_R53_APP_DOMAIN) AWS_R53_HOSTED_ZONE=$(/opt/elasticbeanstalk/bin/get-config environment -k AWS_R53_HOSTED_ZONE) echo "{\"Comment\":\"Update IP\",\"Changes\":[{\"Action\": \"UPSERT\",\"ResourceRecordSet\":{\"Name\":\""$AWS_R53_APP_DOMAIN".\",\"Type\":\"A\",\"TTL\":60,\"ResourceRecords\":[{\"Value\":\""$IP"\"}]}}]}" > awsr53.json aws route53 change-resource-record-sets --hosted-zone-id "$AWS_R53_HOSTED_ZONE" --change-batch file://awsr53.json 

This needs to assign to the service role used by the instance permissions to perform an upsert on Route53. I suggests to perform the script mentioned before via SSH first to debug

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.