How to deploy an EC2 instance integerated with Route53. The solution can be extended to deploy custom artefacts via user-data script.
I have been using AWS services at my workplace and on my side projects for several years. While the AWS console provides a quick way to jumpstart, it does not entirely integrate with the typical software development lifecycle.
At my workplace, we have been using Terraform to provision the infrastructure, but for a side project or working on a proof of concept, I am usually looking for a quicker solution without much overhead. AWS provides a fully functional command line toolset that is easy to configure and integerates well with AWS APIs.
In this post, I will share my workflow to provision an EC2 instance with a user-data script integrated with a Route53 DNS name. Depending on the mapping criteria, one can use a CNAME (EC2 public DNS) or an A (EC2 IPv4 address) record for the set up.
The following is a list of pre-requisites for this set up:
The following script functions can be executed in the order to replicate this setup.
The first step is to create an EC2 instance. Once the instance is created successfully, we wait for it to be started so that we can query the INSTANCE_ID
. The --user-data
flag is used to specify the script we can use to set up the actual deployment candidate on the machine.
# REGION : AWS region where the instance is to be launched
# AMI_ID : Image identifier
# KEY_NAME : Key-pair to be used for accessing machine
# $1 : User-Data script
function createInstanceWithUserData(){
# Create EC2 instance in default subnet
# of default vpc in the given region
echo "launching instance with user data from: " $1
INSTANCE_ID=$(aws ec2 run-instances \
--count 1 \
--region ${REGION} \
--instance-type ${INSTANCE_TYPE} \
--image-id ${AMI_ID} \
--security-group-ids ${SECURITY_GROUP_ID} \
--key-name ${KEY_NAME} \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${TAG_NAME}}]" \
--user-data file://$1 \
--output text --query 'Instances[0].InstanceId')
# Wait for the instance to be running
echo "waiting for the instance launch to complete"
echo "EC2 instance created successfully!"
aws ec2 wait instance-running --region $REGION --instance-ids $INSTANCE_ID
}
The next step is to query the newly generated instance based on the region and instance_id we received in the last step. On a high level, we are looking for the following details:
# INSTANCE_ID: Unique identifier for the newly created instance
# This is logged on console in the createInstanceWithUserData
# function.
function fetchIpAddress(){
# Get public IP address of the instance
echo "fetching ip-address: "
PUBLIC_IP=$(aws ec2 describe-instances \
--region ${REGION} \
--instance-ids ${INSTANCE_ID} \
--query 'Reservations[0].Instances[0].PublicIpAddress' \
--output text)
PUBLIC_DNS=$(aws ec2 describe-instances \
--region ${REGION} \
--instance-ids ${INSTANCE_ID} \
--query 'Reservations[0].Instances[0].PublicDnsName' \
--output text)
# the output is /hostedzone/xxxxxxxxxx
# so remove first 12 characters
ZONE=$(aws route53 list-hosted-zones-by-name \
--dns-name xxxxxxxxx.org \
--query "HostedZones[].Id" \
--output text | cut -c 13-)
echo "Instance ID: ${INSTANCE_ID}"
echo "Public IP: ${PUBLIC_IP}"
echo "Public DNS: ${PUBLIC_DNS}"
echo "ZONE: ${ZONE}"
}
The final step is to create a new record in the hosted zone. The record can be a CNAME or an A record.
# PREFIX : subdomain for xxxxx.org
# PUBLIC_DNS : autogenerated dns name from fetchIpAddress
# function
function registerDNS(){
echo "Registering DNS with route53 entry"
aws route53 change-resource-record-sets \
--hosted-zone-id ${ZONE} \
--change-batch '
{
"Comment": "record set created via cli for xxxxxxxxx.org and ec2",
"Changes": [{
"Action" : "CREATE",
"ResourceRecordSet" : {
"Name" : "'"$PREFIX"'.xxxx.org",
"Type" : "CNAME",
"TTL" : 120,
"ResourceRecords" : [{
"Value" : "'"$PUBLIC_DNS"'"
}]
}
}]
}
'
}
The above functions can be combined and executed as a single script to quickly set up an EC2 machine mapped to a domain name. On similar lines, we can write a cleanup script to clear the same once we finish the POC. Please drop me an email if you need the cleanup script; I’ll be happy to share the details.
That is all for this post. If you want to share any feedback, please drop me an email, or contact me on any social platforms. I’ll try to respond at the earliest. Also, please consider subscribing feed for regular updates.
Be notified of new posts. Subscribe to the RSS feed.