Skip to content

Commit

Permalink
Adding support for Private DNS. Ensuring we only use official Amazon …
Browse files Browse the repository at this point in the history
…tools.

1) This commit removes quite a lot of code and cleans up a lot. Now we only use
official Amazon toolsets, and the code is much cleaner and easier to read.

2) This commit also adds support for private hosted zones - For use in a VPC.
When a private DNS is specified, we will create an A record with the instances
internal IPV4 address. If it is not specified, we will create a CNAME record
with the instances public hostname as before.

Squashed commit of the following:

commit 805691ec4794bde4fc9524732ca52af50474589c
Author: TJ Biddle <[email protected]>
Date:   Tue Dec 2 13:13:35 2014 -0500

    Adding README.

commit a6fe8f7a2f4ce33572ecbf232b606e22c5547cca
Author: TJ Biddle <[email protected]>
Date:   Tue Dec 2 12:55:29 2014 -0500

    Adding support for private DNS

commit 4d78898a6ff1f9cfd67e72c0977314462208dc17
Author: TJ Biddle <[email protected]>
Date:   Tue Dec 2 11:22:10 2014 -0500

    Work in progress.
  • Loading branch information
TJ Biddle committed Dec 2, 2014
1 parent 8c8495e commit a67997a
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 202 deletions.
2 changes: 1 addition & 1 deletion Modulefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name 'tjbiddle-dynamicroute53'
version '0.0.1'
version '1.0.0'
source 'UNKNOWN'
author 'tjbiddle'
license 'MIT'
Expand Down
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Dynamic Route53 Puppet Module adds the ability for an Amazon EC2 instance to add itself to Route53 DNS when it boots, as well as remove itself when it is shut down.

It's DNS name is defined by the 'Name' tag set on the instance.

It has the ability to both work with private DNS as well as public - simply by adjusting the `private_dns` parameter in the class.

When `private_dns` is specified it will add an A record with it's internal IP as the value, if it is not specified it will default to public DNS and will add it's public hostname as a CNAME record.

The package installs official Amazon packages only: `cloud-utils` system package provided by Amazon, as well as `awscli` pip Python package also provided by Amazon.

The script currently does not have any fault tollerance - so ensure all variables are defined properly both in the class as well in Amazon.

The following IAM policies should be created - we recommend creating a separate user for security reasons:

Ability to describe tags:

{
"Statement": [
{
"Sid": "Stmt1358183399710",
"Action": [
"ec2:DescribeTags"
],
"Effect": "Allow",
"Resource": [
"*"
]
}
]
}

Ability to edit your Route53 Hosted Zone
*Be sure to replace YOUR_HOSTED_ZONE_ID_HERE with your Hosted Zone ID*

{
"Statement":[
{
"Action":[
"route53:ChangeResourceRecordSets",
"route53:GetHostedZone",
"route53:ListResourceRecordSets"
],
"Effect":"Allow",
"Resource":[
"arn:aws:route53:::hostedzone/YOUR_HOSTED_ZONE_ID_HERE"
]
},
{
"Action":[
"route53:ListHostedZones"
],
"Effect":"Allow",
"Resource":[
"*"
]
}
]
}

6 changes: 0 additions & 6 deletions files/aws.sh

This file was deleted.

2 changes: 0 additions & 2 deletions files/java.sh

This file was deleted.

5 changes: 0 additions & 5 deletions files/oracle-java7.preseed

This file was deleted.

83 changes: 0 additions & 83 deletions manifests/ec2tools.pp

This file was deleted.

37 changes: 35 additions & 2 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,44 @@
$region = undef,
$aws_access_id = undef,
$aws_secret_key = undef,
$hosted_zone_id = undef,
$private_dns = false,
$ttl = '300'
) {

include dynamicroute53::packages
file { '/root/.aws/':
ensure => directory,
owner => root,
group => root,
mode => 755
}

class {'dynamicroute53::ec2tools':} -> class {'dynamicroute53::service':}
file { '/root/.aws/credentials':
ensure => present,
owner => root,
group => root,
mode => 600,
content => template('dynamicroute53/credentials.erb'),
require => [
File['/root/.aws/'],
Package['awscli'],
Package['cloud-utils']
]
}

file { '/root/.aws/config':
ensure => present,
owner => root,
group => root,
mode => 600,
content => template('dynamicroute53/config.erb'),
require => [
File['/root/.aws/'],
Package['awscli'],
Package['cloud-utils']
]
}

class {'dynamicroute53::packages':} -> class {'dynamicroute53::service':}

}
48 changes: 6 additions & 42 deletions manifests/packages.pp
Original file line number Diff line number Diff line change
@@ -1,55 +1,19 @@
class dynamicroute53::packages {

apt::ppa { 'ppa:webupd8team/java': }

package { 'openjdk-6-jdk':
ensure => purged
}

package { 'openjdk-6-jre':
ensure => purged
}
package { 'openjdk-7-jdk':
ensure => purged
}
package { 'openjdk-7-jre':
ensure => purged
}

file { '/var/local/oracle-java7.preseed':
ensure => present,
source => 'puppet:///modules/dynamicroute53/oracle-java7.preseed'
}

# !!! By installing this package - you agree to Oracle's license.
package { 'oracle-java7-installer':
ensure => installed,
responsefile => '/var/local/oracle-java7.preseed',
require => [
Apt::Ppa['ppa:webupd8team/java'],
Package['openjdk-6-jdk'],
Package['openjdk-6-jre'],
Package['openjdk-7-jdk'],
Package['openjdk-7-jre']
]
}

if ! defined(Package['python-pip']) {
package { 'python-pip':
ensure => installed,
}
}

package { 'cli53':
ensure => installed,
require => Package['python-pip'],
provider => pip,
package { 'awscli':
ensure => installed,
require => Package['python-pip'],
provider => pip,
}

if ! defined(Package['unzip']) {
package { 'unzip':
ensure => installed,
}
package { 'cloud-utils':
ensure => installed
}

}
7 changes: 3 additions & 4 deletions manifests/service.pp
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
content => template('dynamicroute53/update-dns-route53.erb'),
owner => root,
group => root,
mode => 754,
require => Package['oracle-java7-installer']
mode => 754
}

file { '/usr/sbin/delete-dns-route53':
ensure => present,
content => template('dynamicroute53/delete-dns-route53.erb'),
owner => root,
group => root,
mode => 754,
require => Package['oracle-java7-installer']
mode => 754
}

file { '/etc/init.d/updatednsroute53':
Expand All @@ -27,6 +25,7 @@
require => [
File['/usr/sbin/update-dns-route53'],
File['/usr/sbin/delete-dns-route53'],
File['/root/.aws/credentials']
]
}

Expand Down
16 changes: 3 additions & 13 deletions templates/config.erb
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
# Set access and secret key of a user that
#only has access to the following AWS objects/privileges:
#"ec2:DescribeTags"
#"route53:ChangeResourceRecordSets",
#"route53:GetHostedZone",
#"route53:ListResourceRecordSets"
#"route53:ListHostedZones"

AWS_ACCESS_KEY_ID="<%= scope.lookupvar('dynamicroute53::aws_access_id') %>"
AWS_SECRET_ACCESS_KEY="<%= scope.lookupvar('dynamicroute53::aws_secret_key') %>"
ZONE="<%= scope.lookupvar('dynamicroute53::domain') %>"
TTL="<%= scope.lookupvar('dynamicroute53::ttl') %>"

[default]
output = text
region = <%= scope.lookupvar('dynamicroute53::region') %>
3 changes: 3 additions & 0 deletions templates/credentials.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[default]
aws_access_key_id = <%= scope.lookupvar('dynamicroute53::aws_access_id') %>
aws_secret_access_key = <%= scope.lookupvar('dynamicroute53::aws_secret_key') %>
45 changes: 30 additions & 15 deletions templates/delete-dns-route53.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,38 @@

# Make sure only root can run our script
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
echo "This script must be run as root" 1>&2
exit 1
fi

# Load configuration
. /etc/route53/config
. /etc/profile.d/java.sh
. /etc/profile.d/aws.sh
# Get our Instance ID, local IP, and EC2 Public Hostname using cloud-utils ec2metadata
INSTANCE_ID=$(/usr/bin/ec2metadata --instance-id)
IPV4_ADDRESS=$(/usr/bin/ec2metadata --local-ipv4)
PUBLIC_HOSTNAME=$(/usr/bin/ec2metadata --public-hostname)

# Export access key ID and secret for our tools
export AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY
# Set required variables for Route53 API Call
HOSTED_ZONE_ID=<%= scope.lookupvar('dynamicroute53::hosted_zone_id') %>
DOMAIN=<%= scope.lookupvar('dynamicroute53::domain') %>
TTL=<%= scope.lookupvar('dynamicroute53::ttl') %>

HOSTNAME=$(/opt/aws/bin/ec2-describe-tags -O $AWS_ACCESS_KEY_ID -W $AWS_SECRET_ACCESS_KEY --region "<%= scope.lookupvar('dynamicroute53::region') %>" \
--filter "resource-type=instance" \
--filter "resource-id=$(/opt/aws/ec2-metadata -i | cut -d ' ' -f2)" \
--filter "key=Name" | cut -f5)
# Get our desired hostname from the "Name" tag on our instance
HOSTNAME=$(/usr/local/bin/aws ec2 describe-tags \
--filters "Name=resource-type,Values=instance" \
"Name=resource-id,Values=${INSTANCE_ID}" \
"Name=key,Values=Name" \
| awk '{print $5}')

# Delete the hostname from DNS on shutdown
/usr/local/bin/cli53 rrdelete "$ZONE" "$HOSTNAME"
# Begin changes
##############################################################

<% if scope.lookupvar('dynamicroute53::private_dns') %>
# Set an A record with the local IP

/usr/local/bin/aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "{\"Comment\": \"string\",\"Changes\": [{\"Action\": \"DELETE\",\"ResourceRecordSet\": {\"Name\": \"${HOSTNAME}.${DOMAIN}\",\"Type\": \"A\",\"TTL\": ${TTL},\"ResourceRecords\": [{\"Value\": \"${IPV4_ADDRESS}\"}]}}]}"
<% else %>
# Set a CNAME record with the public hostname

/usr/local/bin/aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "{\"Comment\": \"string\",\"Changes\": [{\"Action\": \"DELETE\",\"ResourceRecordSet\": {\"Name\": \"${HOSTNAME}.${DOMAIN}\",\"Type\": \"CNAME\",\"TTL\": ${TTL},\"ResourceRecords\": [{\"Value\": \"${PUBLIC_HOSTNAME}\"}]}}]}"
<% end %>
Loading

0 comments on commit a67997a

Please sign in to comment.