1 Introduction
When we automate an EC2 instance provision with CloudFormation, we can assign a name tag to the EC2 instance. Naturally, we would like to have the OS hostname match the name tag, but surprisingly, this is not the default AWS behavior and need some efforts to automate it.
2 The challenges
2.1 Hostname is derived from dynamic IP address
When we provision a new Amazon Linux EC2 instance on AWS, the default hostname is derived from the IP address that is dynamically assigned to the instance at startup.
For example, your hostname might look like this
ip-12-34-56-78
|
Very likely, this name is not desirable and need to be changed, but how?
Amazon has instruction on how to make the change manually, but it involve a reboot, something is not nice if we want to use script to automate this task.
2.2 Using on-premises AD service
On the other hand, changing the hostname is part of the story, we also need to update the DNS record.
If you are using Active Directory and extend the on-premises AD service to the AWS like the following picture, you would like to know how to automatic the DNS update too.
3 2 The solution
3.1 Enable DNS dynamic update
We need to enable dynamic update on the DNS service provided by the AD server.
The following enable dynamic updates using the Windows interface
- Open DNS Manager.
- In the console tree, right-click the applicable zone, and then click Properties.
- On the General tab, verify that the zone type is either Primary or Active Directory-integrated.
- In Dynamic Updates, click Nonsecure and secure.
In my example script, it only works with the “Nonsecure and secure” setting only. In case you need more security, you could set up Secure Dynamic Update, check out the details on this Microsoft document and modify the script accordingly.
3.2 Automate all the updates with a python script
I had written a script in Python to automate the task to update the hostname and DNS record based on the name tag assigned to the EC2 instance.
In details, this script perform the following:
- Get the instance name from EC2 metadata, which is the EC2 name tag
- Get the instance IP address from EC2 metadata
- Update the /etc/sysconfig/network file with the name FQDN name
- Update the /etc/hosts with the IP and FQDN
- Set the hostname
- Update the DNS record on AD
Following is the python script, you can include it in your bootstrap step script during the EC2 provision or in your Chef/Puppet/Ansible configuration steps.
.
#!/usr/bin/python
import boto3
import requests
import json
import re
import os
import subprocess
import StringIO
## Change the domain name to your need
DOMAIN='cloud.operative.com'
## replace content in a file
def replace(file, pattern, subst):
# Read contents from file as a single string
file_handle = open(file, 'r')
file_string = file_handle.read()
file_handle.close()
# Use RE package to allow for replacement (also allowing for (multiline) REGEX)
file_string = (re.sub(pattern, subst, file_string))
# Write contents to file.
# Using mode 'w' truncates the file.
file_handle = open(file, 'w')
file_handle.write(file_string)
file_handle.close()
## get the name tag of the ec2 instance
def get_instance_name():
## get the ec2 instance id and region
r = requests.get('http://169.254.169.254/latest/dynamic/instance-identity/document/')
r_arr=json.loads(r.text)
region = r_arr['region']
instance_id = r_arr['instanceId']
## get EC2 information
ec2 = boto3.resource('ec2', region_name=region)
ec2instance = ec2.Instance(instance_id)
instancename = ''
for tags in ec2instance.tags:
if tags["Key"] == 'Name':
instancename = tags["Value"]
return instancename
def get_ip_addr():
r = requests.get("http://169.254.169.254/latest/meta-data/local-ipv4")
return r.text
def grep(file,pattern):
for line in open(file).readlines():
if re.match(pattern, line):
return line
return ""
def append(file,data):
f = open(file, 'a')
f.write(data)
f.close()
def update_dns(hostname):
cmd='nslookup ' + hostname
args = cmd.split()
process = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
exit_code = process.wait()
print "return code = " , exit_code
if exit_code == 0:
print "DNS record already existed"
cmd = """
else:
## update dns record
print "Update DNS record"
cmd = """
nsupdate << EOF
zone $ZONE
update delete $fqdn
update add $fqdn 86400 A $ip_addr
show
send
EOF
"""
os.system(cmd)
##### Main Program #####
instance_name = get_instance_name()
ip_addr = get_ip_addr()
fqdn = instance_name + '.' + DOMAIN
host_line = 'HOSTNAME=' + instance_name + '.' + DOMAIN
## Update /etc/sysconfig/network file
print "update /etc/sysconfig/network with " + host_line
replace("/etc/sysconfig/network", 'HOSTNAME=.*', host_line )
## Update /etc/hosts file
ret = grep("/etc/hosts", ip_addr)
ip_w_fqdn = ip_addr + " " + fqdn + " " + instance_name
if ret == "":
print "add fqdn info to /etc/hosts"
append("/etc/hosts", ip_w_fqdn + "\n")
else:
print "Replace line in /etc/hosts with '" + ip_w_fqdn + "'"
replace("/etc/hosts", ip_addr + '.*' , ip_w_fqdn)
## Run hostname command
cmd='hostname ' + instance_name
os.system(cmd)
## Update DNS record
update_dns(fqdn)
|
3.3 Additional tip
If your shop only allow one DNS server for dynamic update and it is not the one defined in /etc/resolv.conf, you can modify the script and add the server option for nsupdate like the following
…..
…..
nsupdate << EOF
server <your dns server allow dynamic update>
zone $ZONE
update delete $fqdn
update add $fqdn 86400 A $ip_addr
show
send
EOF
"""
….
….
|
Good article on AWS EC2, information provided in this blog post is Useful for me and Other AWS Candidates a lot, Thanks for sharing.
ReplyDeleteBest Regards,
AWS Online Training
AWS Training
Amazon Web Services Online Training in Hyderabad
AWS Online Training in Hyderabad
AWS Certification Online Training
AWS Training Online
AWS Certification Training
AWS Training and Certification
Learn AWS
Amazon Web Services Training
AWS Training in Hyderabad
Amazon Web Services Training in hyderabad
Amazon Web Services Training in india
AWS Training Institute in Hyderabad
CourseIng
devops academy the capacity to pull in front of the opposition." But what is DevOps?..
ReplyDeleteNice blog thanks for updating for more information AWS Online Course Hyderabad
ReplyDeleteThank you for your information.it is very nice article.
ReplyDeleteDigital Marketing Training in Pune