doing a dns lookup inside your puppet manifest
Update 2017-10-06:
It’s 2017. Don’t use the code below, but use the excellent dalen/dnsquery module instead. Leaving the original post below for historical reasons.
I use dynamic DNS at my residence so that I can always log into my server remotely without having to know the IP.
I run denyhosts on the server hosting my website at Rackspace to attempt to contain brute-force ssh attacks. If you enter the wrong password N times, your IP gets banned and you can’t connect to my server anymore via ssh.
The problem is that I can often times legitimately mistype my password. I want to ensure that I don’t accidentally lock myself out of my Rackspace VM. Luckily, denyhosts provides a way for you to whitelist IPs so that they will never be locked out…the allowed-hosts
file.
Ok, but now my manifest needs to know what my dyndns name resolves to at manifest compilation time. To get around that, I added a function called dnsLookup. I put this in modules/custom/lib/puppet/parser/functions/dnsLookup.rb:
# dnsLookup.rb
# does a DNS lookup and returns an array of strings of the results
require 'resolv'
module Puppet::Parser::Functions
newfunction(:dnsLookup, :type => :rvalue) do |args|
result = []
result = Resolv.new.getaddresses(args[0])
return result
end
end
So, now in my manifest, I can put something like this:
class denyhosts {
# ...
$allowed_ips = ['127.0.0.1', dnsLookup('dyndnsname.example.com')]
file { "/var/lib/denyhosts/allowed-hosts":
ensure => present,
owner => root,
group => root,
mode => 0644,
content => template('denyhosts/allowed-hosts.erb'),
notify => Service["denyhosts"],
}
# ...
}
The allowed-hosts.erb template looks like this:
<% allowed_ips.each do |ip| -%>
<%= ip %>
<% end -%>
I haven’t tested this with a name that has multiple records, so you might need to tweak or tune this if that is your particular use case.