Immutable Servers with Puppet and Packer

Document created by soujanya on Aug 10, 2017
Version 1Show Document
  • View in full screen mode

Puppet and Packer Immutable Server
it's far encouraged that server improvements or changes on servers ought to never be executed whilst the servers are stay. What you should is which you need to create new servers having the upgrades, and then forestall the usage of the antique servers. The advantage is that you'll experience immutability as you program on the infrastructure stage, and you'll no longer be suffering from the configuration flow.
Nodes
Our infrastructure undertaking might be made of nodes.yalm with a purpose to be used for definition of the node names and the AWS security corporations which they belong to. This is simple, as it is used in a couple of different gear together with the vagrant. The code need to be as shown below:

Immutable Servers With Puppet And Packer

elasticsearch: group: logging zookeeper: group: zookeeper redis: group: redis size: m2.2xlarge

 

Rakefile
we can use the report “nodes.yaml” collectively with rake for production of packer templates for constructing out new AMIs. be aware that maximum packer templates generally have similar or associated capabilities, so that you can manage them as a unit, and this feature will make certain this. The code for that is given beneath:
Immutable Servers With Puppet And Packer

require ‘erb’ require ‘yaml’ namespace :packer do task :generate do current_dir = File.dirname(__FILE__) nodes = YAML.load_file( “#{current_dir}/nodes.yml”) nodes.each_key do |node_name| include ERB::Util template = File.read(“#{current_dir}/packs/template.json.erb”) erb = ERB.new(template) File.open(“#{current_dir}/packs/#{node_name}.json”, “w”) do |f| f.write(erb.result(binding)) end end end end

What we've accomplished is that we have used it collectively with a easy erb template if you want to inject the nodename into it. this is proven under:

Immutable Servers With Puppet And Packer

{ “builders”: [{ “type”: “amazon-ebs”, “region”: “us-east-1”, “source_ami”: “ami-10314d79”, “instance_type”: “t1.micro”, “ssh_username”: “ubuntu”, “ami_name”: “<%= node_name %> {{.CreateTime}}”, “security_group_id”: “packer” }], “provisioners”: [{ “type”: “shell”, “script”: “packs/install_puppet.sh” }, { “type”: “shell”, “inline”: [ “sudo apt-get upgrade -y”, “sudo sed -i /etc/puppet/puppet.conf -e ”s/nodename/<%= node_name %>-$(hostname)/””, “sudo puppet agent –test || true” ] }]

 

With the above code, a packer template can be generated for every node, and this may perform the following duties:
set up puppet.
An AMI might be created in us-east-1
Execute Puppet as soon as for configuration of the gadget.
the security group may be adjusted to EC2.
The Puppet agent must no longer be enabled, in order that we will keep away from polling of updates. as soon as Puppet has finished, we can then do away with it from the server to keep away from it being baked in by AMI.
The Script
With packer, the user can specify the shell documents and the shell commands which might be to be run. in terms of bootstrapping, this option is the pleasant, but it is right for the type of configuration control wanted in Puppet. Our packer templates will work by calling a shell script, and this will make sure that we do now not use the antique model of ruby Linux distros. The server name of the Puppet grasp may also be targeted as part of the set up manner. The code is given beneath:

 

Immutable Servers With Puppet And Packer

sleep 20, wget http://apt.puppetlabs.com/puppetlabs-release-raring.deb sudo dpkg -i puppetlabs-release-precise.deb sudo apt-get update sudo apt-get remove ruby1.8 -y sudo apt-get install ruby1.9.3 puppet -y sudo su -c ‘echo “””[main] logdir=/var/log/puppet vardir=/var/lib/puppet ssldir=/var/lib/puppet/ssl rundir=/var/run/puppet factpath=$vardir/lib/facter templatedir=$confdir/templates [agent] server = ip-10-xxx-xx-xx.ec2.internal report = true certname=nodename””” >> /etc/puppet/puppet.conf’

 

When you execute the above command, the server will be created, configured, imaged, and sooner or later terminated. be aware that for every AMI which you create, a price can be incurred. The cost for a single AMI is probably small, however when you have more than one of these, then this will be very costly. this is why the antique pics need to be wiped clean up. that is a totally easy challenge which may be completed as shown underneath:

Immutable Servers With Puppet And Packer

import os import boto from fabric.api import task class Images(object): def __init__(sf, **kw): sf.con = boto.connect_ec2(**kw) def get_ami_for_name(sf, name): (keys, AMIs) = sf.get_amis_sorted_by_date(name) return AMIs[0] def get_amis_sorted_by_date(sf, name): amis = sf.conn.get_all_images(filters={‘name’: ‘{}*’.format(name)}) AMIs = {} for ami in amis: (name, creation_date) = ami.name.split(‘ ‘) AMIs[creation_date] = ami # removing the old images! keys = AMIs.keys() keys.sort() keys.reverse() return (keys, AMIs) def remove_old_images(sf, name): (keys, AMIs) = sf.get_amis_sorted_by_date(name) while len(keys) > 1: key = keys.pop() print(“deregistering {}”.format(key)) AMIs[key].deregister(delete_snapshot=True) @task def cleanup_old_amis(name): ”’ Usage: cleanup_old_amis:name={{ami-name}} ”’ images = Images( aws_access_key_id=os.environ[‘AWS_ACCESS_KEY_ID’], aws_secret_access_key=os.environ[‘AWS_SECRET_ACCESS_KEY’] ) images.remove_old_images(name)

Attachments

    Outcomes