Typically cloud servers have both an internal and external ip address.
But with VPC’s(virtual private clouds) many companies are deciding to have a few hosts proxy ports 22, 80 & 443 and the other hosts have internal ip’s only.
In both scenarios having an DNS for internal hostname’s is important but in the case of VPC its critical.
One was of doing this is to simply create a DNS entry for each interface.
ie.
hostname.foo.com hostname.internal.foo.com
But it doesn’t make sense having an name/ip of an internal server available on a public DNS server.
What you can do instead is have chef set the hostnames, populate those names/ips in the /etc/hosts files and convince your OS to use that file when performing lookups.
Setting the hostname.
I usually go with purpose.abreviated_company_name
rails01.gyk
This is done in chef with this a recipe like this:
execute "set_hostname" do command "/bin/hostname -F /etc/hostname" user "root" action :nothing end template /etc/hostname do source "hostname.erb" notifies :run, execute[set_hostname] end
And a template like this:
<%= node['hostname']%>.gyk
Ok now we have chef setting the correct hostname but hold on, after a while or a reboot (on EC2 at least) the name goes away.
This is because of this obscure setting in /etc/cloud/cloud.cfg”
# This will cause the set+update hostname module to not operate (if true) preserve_hostname: false If this is set to true then it will not wipe out the hostname you set.
I fixed this with my old friend sed.
execute "preserve_hostname" do command "sed -i 's/preserve_hostname\:\ false/preserve_hostname\:\ true/' /etc/cloud/cloud.cfg" not_if "grep 'preserve_hostname: true' /etc/cloud/cloud.cfg" user "root" end
Okay so now we have a hostname that sticks, next step…
Populating /etc/hosts will all internal hosts.
To do this I used the hostsfile cookbook (https://github.com/customink-webops/hostsfile)
Basically I search chef for all hosts in my environment and write the hostname and ip to the file.
addresses = search(:node, "chef_environment:#{node.chef_environment}") addresses.each do |dd| if dd.has_key?("ipaddress") hostsfile_entry dd.ipaddress do hostname dd.hostname + “.gyk" action :create unique true end end end
Get the OS to use the /etc/hosts file for lookups.
Back in the day all I have to do to get /etc/hosts to work was set this in the nsswitch.conf
hosts: files dns
At this point without the following step pings and telnet requests to the hosts will work but loopups(nsloopup, host, dig etc.,..) won’t
Yeah super confusing, I won’t go into the science of it but the basic reason is the commands use different libraries when performing lookups.
However after reading and changing a lot of files with out any success I fixed the problem by installing the dnsmasq package.
Not sure what else this package does but I know it allows your /etc/hosts file to actually be useful.
Now you have a fully automated population of internal hostnames…no DNS entries needed!