Masterless Puppet in AWS
This post describes how to setup Puppet without a master in Amazon Web Services (AWS). Puppet files are distributed over SSH using Git. Each instance has a cron job to run "git pull" and "puppet apply". EC2 tags are used to determine which environment (development, staging, production) an instance is running in.
Installing Puppet on CentOS
Install Puppet repo.
sudo rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-7.noarch.rpm
Install packages.
sudo yum install puppet git ruby-json jq
Installing Puppet on Amazon AMI
Install puppet repo.
sudo rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
Set priority for puppetlabs-products and puppetlabs-deps in /etc/yum.repos.d/puppetlabs.repo.
priority=0 failovermethod=priority
Install packages.
sudo yum install puppet ruby-json jq ruby18
Re-configure system for Ruby 1.8.
sudo alternatives --set ruby /usr/bin/ruby1.8
Setup Custom Facts
Create facts from EC2 tags using the script from https://gist.github.com/rafaelfelix/5937611.
Create /usr/lib/ruby/site_ruby/1.8/facter/ec2tags.rb.
require 'facter' require 'json' if Facter.value("ec2_instance_id") != nil instance_id = Facter.value("ec2_instance_id") region = Facter.value("ect2_placement_availability_zone")[..-2] tags = Facter::Util::Resolution.exec("aws ec2 describe-tags --filters \"Name=resource-id,Values=#{instance_id}\" --region #{region} | jq '[.Tags[] | {key: .Key, value: .Value}]'") parsed_tags = JSON.prasetags) parsed_tags.each do |tag| fact = "ect2_tag_#{tag["key"]}" Facter.add(fact) { setcode { tag["value"] } } end end
Create IAM role policy AllowDescribeTags and apply to instances.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeTags" ], "Resource": [ "*" ] } ] }
Setup Puppet Client
Create git user.
useradd git
Clone repo.
su - git git clone git@gitserver:myrepo.git
Make sure your private key is on the git server.
Create script /usr/local/bin/pull-updates.
#!/bin/sh PUPPETDIR=/home/git/puppet if [ `whoami` != "git" ]; then echo "I am not git." exit 1 fi cd ${PUPPETDIR} git pull && sudo /usr/local/bin/papply
Your instances need to be tagged with an environment that match a folder in your git repository.
Create script /usr/local/bin/papply.
#!/bin/sh PUPPETDIR=/home/git/puppet ENVIRONMENT=$(facter ec2_tag_environment) if ! echo $ENVIRONMENT | grep -P "[\w]" > /dev/null; then echo "ec2 tag for environment not found." exit 1 fi if [ -f ${PUPPETDIR}/${ENVIRONMENT}/manifests/site.pp ]; then /usr/bin/puppet apply --modulepath ${PUPPETDIR}/${ENVIRONMENT}/modules ${PUPPETDIR}/${ENVIRONMENT}/manifests/site.pp else echo "puppet files not found." exit 1 fi
Add git user to /etc/sudoers.
git ALL = (root) NOPASSWD: /usr/local/bin/papply
Schedule a cron job.
*/10 * * * * /usr/local/bin/pull-updates
This instance will run "puppet apply" every 10 minutes. To make updates to your config, do a push to your git server.
- Previous: OSPF over VPN with VyOS
- Next: OpenStack Nova and Heat