i am in process to set up a number of stateless nodes.

Each node is provided with the same OS image file. It fetches the hostname from the DHCP/DNS server during boot time.

Next step is to acquire the server configuration ... I am planning to use puppet for this part ....

BUT at this point the node does not have the correct certificate as it is a generic OS image. The first time a node is seen on the network this works fine because i can use autosign.conf to enable the cert to be signed and verfied

What do i need to do to solve the case where the node has already been seen on the network so the puppet master has a certificate for it... However the server certificate will NOT match to the newly created certificate on the node.

I tried inserting

allow_duplicate_certs = true

into puppet.conf

BUT it does not seem to work. Am i looking at the right settings? IS there a better/propper way to solve this?

  • 2
    So..you are also destroying these nodes? And then recreating them with the same names? – Michael Hampton Dec 10 '13 at 23:43
  • Yes. That is effectively what i am doing. After first boot it is registering with puppet master and i can then give it a configuration, etc. Then on reboot it is destroyed. Along with the certificate the client holds. I would then like to be able to get the configuration back (via Puppet) automatically on boot. I was thinking this could be achieved by the system creating its new certificate on boot and then the puppet master auto-accepting this on boot as a new cert for the existing node name. And then automatically pulling the config down. – Ben Dec 18 '13 at 10:00

The normal way to handle things like this (especially in EC2-like environments) is to use UUIDs for the client certificates instead of hostnames. I found a reasonable guide to the process on Puppetize Me's "Using UUIDs for agent certnames", but the gist of the process is this:

  1. Install uuidgen
  2. Run uuidgen to get a UUID.
  3. Edit puppet.conf and add certname = <UUID> to the [agent] section.
  4. Continue your Puppet deployment process as normal.

This process can be scripted without too much difficulty.

| improve this answer | |
  • 1
    Good idea, but then how do you identify and get rid of old certificates which are no longer used? – Michael Hampton Dec 26 '13 at 18:43
  • Well, you can just not worry about them, since an unused certificate doesn't really consume a lot of resources. Alternately, you can use the client reports (via Puppet Dashboard, if you're using it) to see who hasn't checked in for a while and use that information to clean up those nodes and their certificates. I've also seen mention of people having VM instances trigger a puppet node clean on the master when the instances shut down. – asciiphil Dec 26 '13 at 20:35

I use the EC2 internal hostnames as the hostname(ie ip-X-X-X-X), and also as the certificate name.

And I use the Foreman to create EC2 instances. And with the foreman hooks plugin, I make sure that if a certificate with the same "ip-X-X-X-X" name exists on the master, it is deleted before the instance is created.

Before deleting, I also rename the host in foreman to "ip-X-X-X-X-", from whatever friendly name I gave it.

This also means I do not see friendly names in the host list, but I am ok with that since I use hostgroups, and can use the "column" plugin to see the comment field in foreman, where I keep friendly info.

Not an ideal situation, but works for me so far.

| improve this answer | |

This might not be an ideal solution but this is what I was doing before moving to saltstack:

When rolling out a new EC2 box (I am using fabric to achieve this, this is all done on the puppetmaster):

1) On PuppetMaster(certificate and machine host name was already known; naming convention):

local('sudo puppetca -c {}' .format(cert_name));

local('sudo puppetca -g {}' .format(cert_name));

This would take care of the old certificate problem you mentioned.

After this copy over the following files to the new rolled out box using scp:

1) /var/lib/puppet/ssl/ca/signed/signed-cert_name.pem

2) /var/lib/puppet/ssl/private_keys/private-cert_name.pem

3) /var/lib/puppet/ssl/certs/ca.pem

Fabric Code for the above said:

local("sudo cp /var/lib/puppet/ssl/ca/signed/{}.pem /tmp/signed-{}.pem" .format(cert_name,cert_name))
local("sudo chown ubuntu:ubuntu /tmp/signed-{}.pem" .format(cert_name))
local("sudo cp /var/lib/puppet/ssl/private_keys/{}.pem /tmp/private-{}.pem" .format(cert_name,cert_name))
local("sudo chown ubuntu:ubuntu /tmp/private-{}.pem" .format(cert_name))
local("sudo cp /var/lib/puppet/ssl/certs/ca.pem /tmp/ca.pem")   
local("sudo chown ubuntu:ubuntu /tmp/ca.pem")
put("/tmp/signed-{}.pem" .format(cert_name),  "/home/ubuntu/signed-{}.pem" .format(cert_name))
put("/tmp/private-{}.pem" .format(cert_name) , "/home/ubuntu/private-{}.pem" .format(cert_name))
put("/tmp/ca.pem" , "/home/ubuntu/ca.pem")

Now on the new box run the following(I had a simple bash script doing this and fqdn was a param passed):

sudo chown root:root /home/ubuntu/ca.pem /home/ubuntu/signed-$fqdn.pem /home/ubuntu/private-$fqdn.pem
sudo chmod 600 /home/ubuntu/private-$fqdn.pem
sudo mkdir -p /var/lib/puppet/ssl/certs/ /var/lib/puppet/ssl/ca/signed/ /var/lib/puppet/ssl/private_keys/
sudo mv /home/ubuntu/ca.pem /var/lib/puppet/ssl/certs/ca.pem
sudo mv /home/ubuntu/signed-$fqdn.pem /var/lib/puppet/ssl/ca/signed/$fqdn.pem
sudo mv /home/ubuntu/private-$fqdn.pem /var/lib/puppet/ssl/private_keys/$fqdn.pem

I hope this was a little helpful.

note:local, and put are Fabric operations

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.