Building on
Puppet

http://www.rankpop.com/you-need-to-start-structuring-your-blog-posts-asap/
HTTP Load Balancer
from Pound to nginx
Server Density v2:

New version : new load balancer
nginx :
- WebSockets
- SPDY standard
keep :
- modules pulled from our Gihub repo by the
puppet master
- use of Puppet Console and Live Management
to trigger transient changes
Reinventing the wheel
(don't)

Writing our nginx module?
- add yet another one to the collection of
in-house developed modules
community reach?
- whether our problem had already been solved
- or a kick start where we could stand on
http://www.flickr.com/photos/conskeptical/
Going to the Forge
Going to the Forge
Integration
A) get the actual code into the master
puppet module install puppetlabs/nginx
(or)
git submodule add https://github.com/puppetlabs/puppetlabs­nginx.git 

B) run it on existing nodes
no parameterized classes on PE Console (2.8.x)
(or)
merge our site.pp (which is empty) and the console,
it being an ENC and all - (how-merging-works)
Integration
Our solution

class serverdensity­nginx
{
    class { 'nginx': }
    nginx::resource::upstream {
       'socky_rack':
          ensure => present,
          members => split( $lbTargetHostsSocky, ',' ),
    }
(...)
nginx 'on-the-fly' update

class serverdensity­nginx
{
    class { 'nginx': }
    nginx::resource::upstream {
       'socky_rack':
          ensure => present,
          members => split( $lbTargetHostsSocky, ',' ),
    }
(...)
nginx 'on-the-fly' update
nginx 'on-the-fly' update
nginx 'on-the-fly' update
nginx 'on-the-fly' update
Alternatives

Puppet Labs nginx module:
https://github.com/serverdensity/puppetlabs-nginx
forked James Fryman's module:
https://github.com/jfryman/puppet-nginx

pick the later? Puppet Labs last update - 30th June
2011.

https://github.com/serverdensity/puppetlabs-nginx
Extending Server Density
Server Density collects server data from an open
source agent deployed on each device
Create a device on Server Density UI
Copy the device ID (agent key)
The agent reads the device ID from a config file:
[Main]
sd_url: http://mydomain.serverdensity.com
agent_key: 8160b409de9d8a612ec8d964c5b26bf
(...)
Extending Server Density
Server Density v1:
Extending Server Density
Server Density v1:
'sd­agent': 
   ensure => installed,
file 
{ 
   'config.cfg':
      path    => '/etc/sd­agent/config.cfg',
      ensure  => file,
      require => Package['sd­agent'],
      content => template('sd­agent/config.erb'),
}
[Main]
sd_url: http://boxedice.serverdensity.com
agent_key: <%= sdAgentKey %>
(...)
Extending Server Density
Server Density v2:
Extending Server Density
Server Density v2 – in action:
Extending Server Density
Server Density v2 – in action:
Extending Server Density
Server Density v2 - implementation:
Manages the life cycle of Rackspace and Amazon
cloud instances
A custom fact will return the cloud instance agent key
or use Server Density API to create a device on the
fly and return the resulting agent key
https://github.com/serverdensity/puppet-serverdensity
Extending Server Density
Custom fact:
Facter.add(:agent_key, :timeout => 10) do
    if File::exist?('/etc/sd­agent­key')
        result = Facter::Util::Resolution.exec("cat /etc/sd­agent­key")
    elsif Facter.value('ec2_instance_id')
        uri = URI("http://ec2meta.serverdensity.com/latest/user­data")
        req = Net::HTTP::Get.new(uri.request_uri)
        res = Net::HTTP.start(uri.host, uri.port) {|http|
                http.request(req)
        }
        result = res.body.split(':').last if res.code == 200
    end
    setcode { result }
end
Extending Server Density
Custom function:
(...)
        agent_key = lookupvar("agent_key")
        # lookupvar returns undef if no value
        # test against nil just in case
        unless agent_key.nil? or agent_key == :undef
            notice ["Agent Key Provided via Facter: #{ agent_key }"]
            return agent_key
        End
(...) 
Extending Server Density
Custom function:
(...)
base_url = "https://api.serverdensity.io"
filter = {
  'type' => 'device',
  'hostname' => hostname,
}
filter_json = URI.escape(PSON.dump(filter))

uri = 
 URI("#{base_url}/inventory/devices?filter=#{filter_json}&token=#{token}")
req = Net::HTTP::Get.new(uri.request_uri)
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
res = https.start { |cx| cx.request(req) }
(...) 
Extending Server Density
Custom function:
(...)
device = PSON.parse(res.body)
if device['status'] == 2
notice ["Device not found, creating a new one"]
uri = URI("#{ base_url }devices/add?account=#{ sd_url }")
req = Net::HTTP::Post.new(uri.request_uri)
req.basic_auth sd_username, sd_password
params = {
  'name' => server_name,
  'hostName' => hostname,
  'notes' => 'Created automatically by puppet­serverdensity',
}
(...) 
Extending Server Density
Server Density v2:

Next: Publishing to the Forge
https://github.com/serverdensity/puppet-serverdensity
Pedro Pessoa
pessoa@serverdensity.com

http://serverdensity.com/puppetcamp/

Building On Puppet and Puppet Forge