Skip to content

Instantly share code, notes, and snippets.

@kirk
Forked from botchagalupe/gist:675444
Created December 11, 2010 17:05
Show Gist options
  • Save kirk/737470 to your computer and use it in GitHub Desktop.
Save kirk/737470 to your computer and use it in GitHub Desktop.

Setup a Three Server HAPROXY/APACHE2 Setup

Demo Part One (Launch an Apache Server)

Start the demo by launching three EC2 instances then tell the audience that this will take about 3 minutes. Also explain that we not only starting the instances we are also bootstrapping it with the Chef client (Easy Peasy)...

./setupDemo.sh 

Sample Script

cat setupDemo.sh 

nohup knife ec2 server create -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/web1.out &

nohup knife ec2 server create -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/web2.out &

nohup knife rackspace server create --server-name johns-test21 --image 49 --flavor 2 >/tmp/web3.out &

nohup knife ec2 server create -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/lb.out &

While the instance is launched let's do some cooking

Create a new cookbook called demo

knife cookbook create demo

Update the Metadata (in cookbooks/meta.rb )

depends "apache2"

Update the the default.rb recipe in the ../cookbooks/demo/recipes directory__

#
# Cookbook Name:: demo
# Recipe:: default
#
# Copyright 2010, Opscode, Inc..
#
# All rights reserved - Do Not Redistribute
#

include_recipe "apache2"

template "/var/www/index.html" do
  source "index.html.erb"
  owner "root"
  group "root"
  mode "0644"
end

Create the default web page Template file__ in /templates/default/

<html>
        <head>
                <title>Welcome to <%= node[:hostname]%></title>
        </head>
        <body>
                Chef rocks...you have reached:
                <ul>
                        <li><b>FQDN</b>: <%= node[:fqdn] %></li>              
                        <li><b>IP Address</b>: <%= node[:ipaddress] %></li>
                        <li><b>Platform</b>: <%= node[:platform] %></li>
                        <li><b>Plaform Version</b>: <%= node[:platform_version] %></li>
                        <li><b>Run List</b>: <%= node.run_list %></li>
                </ul>
        </body>
</html>

Upload the new Webserver cookbook__

knife cookbook upload demo

knife cookbook list

Create a new webserver.rb role file in ../chef-repo/roles__

name "webserver"
description "simple web app"
run_list(
  "recipe[demo]"
)

Load the new webserver.rb role up to the Chef server__

knife role from file webserver.rb 

knife role show webserver

Check the the status of the instance

knife ec2 server list 

Add the webserver role to the node and run the chef client

knife node run_list add <web1> "role[webserver]" 

knife node run_list add <web2> "role[webserver]"

knife node run_list add <web3> "role[webserver]"

Not tested yet...

knife exec -E 'nodes.transform(:all) {|n| n.run_list << "role[tester]" }'

Run the EC2 Servers chef-clients

knife ssh "role:webserver" "sudo chef-client" -x ubuntu -a ec2.public_hostname

knife ssh "role:webserver" "sudo chef-client" -x root -P <get password> -a rackspace.public_ip

List your running instances and launch the web page using the following commands.__

knife ec2 server list

curl <the public IP of the webserver instance>

Demo Part Two (Launch an Happroxy Server and integrate the two)

Download and Modify Haproxy Cookbook

Search for a copy of the haproxy cookbook by issuing the following commands.__

 knife cookbook site search haproxy

 knife cookbook site show haproxy

Download a copy of the haproxy cookbook.__

 knife cookbook site vendor -d haproxy

Update the the default.rb recipe in the ../cookbooks/haproxy/recipes directory__

package "haproxy" do
  action :install
end

template "/etc/default/haproxy" do
  source "haproxy-default.erb"
  owner "root"
  group "root"
  mode 0644
end

service "haproxy" do
  supports :restart => true, :status => true, :reload => true
  action [:enable, :start]
end

pool_members = search(:node, "role:#{node[:haproxy][:pool_role]}") 

template "/etc/haproxy/haproxy.cfg" do
  source "haproxy.cfg.erb"
  owner "root"
  group "root"
  mode 0644
  variables :pool_members => pool_members
  notifies :restart, resources(:service => "haproxy")
end

Modify the the erb template for the haproxy cookbook.__

global
        log 127.0.0.1   local0
        log 127.0.0.1   local1 notice
        #log loghost    local0 info
        maxconn 4096
        #debug
        #quiet
        user haproxy
        group haproxy

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        redispatch
        maxconn 2000
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000

# Set up application listeners here.
listen application 0.0.0.0:80
      balance roundrobin

      <% @pool_members.each do |member| %>
      <% server_ip = member.has_key?("ec2") ? member.ec2.public_ipv4 : member.ipaddress %>
      server <%= member.hostname %> <%= server_ip %>:80 weight 1 maxconn 1 check
      <% end %>

listen admin 0.0.0.0:22002
      mode http
      stats uri /

In this example we are using the public IP address of the web servers. If the haproxy server and all of the web servers are on Amazon's cloud it is more efficient to use the private IP addresses. The following code is an example of using the the private IP addresses.

# Set up application listeners here.
listen application 0.0.0.0:80
      balance roundrobin

      <% @pool_members.each do |member| %>
      server <%= member.hostname %> <%= member.ipaddress %>:80 weight 1 maxconn 1 check 
      <% end %>

Upload the updated haproxy__

knife cookbook upload haproxy

Create a LB role__

create a lb role

$EDITOR roles/lb.rb 

name "lb"
description "load balancer"
override_attributes(
  :haproxy => {:pool_role => "webserver"}
)
run_list(
  "recipe[haproxy]"
)

Explain the relationship between the :ppol_role attribute and the search in the recipe.

Load the new lb.rb role up to the Chef server__

knife role from file lb.rb 

Show the newly loaded role__

knife role show lb

Add the lb role to the node and run the chef client

knife node run_list add <node1> "role[lb]" 

knife ssh "role:lb" "sudo chef-client" -x ubuntu -a ec2.public_hostname

List your running instances and launch the web page using the following commands.__

knife status --run-list

knife status "role:lb" --run-list

curl <the public IP of the lb instance>

Note: The IP address displayed from the page should match the IP address of your webserver instance.

Also display the haproxy admin interface.

curl <the public IP of the lb instance>:22002

Now fire up three more webserver instances the (easy way)

./webserverDemo.sh 

Sample Script

cat webserverDemo.sh 

 nohup knife ec2 server create "role[webserver]" -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/web1.out &
nohup knife ec2 server create "role[webserver]" -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/web2.out &

Run the chef clint on the lb once the new servers are done...

knife ssh "role:lb" "sudo chef-client" -x ubuntu -a ec2.public_hostname

List your running instances and launch the web page using the following commands.__

knife status --run-list

knife status "role:lb" --run-list

curl <the public IP of the lb instance>

Note: The IP address displayed from the page should match the IP address of your webserver instance.

Also display the haproxy admin interface.

curl <the public IP of the lb instance>:22002

Last but not least do it the easy way...

Cleanup *dangereous - make sure only your instances are running on ec2_

for i in `knife ec2 server list | grep running | grep tse-demo | awk '{print $1}'`
do
  knife client delete $i -y
  knife node delete $i -y
  knife ec2 server delete $i -y
done

One line command

for i in `knife ec2 server list | grep running | grep tse-demo | awk '{print $1}'`; do knife client delete $i -y; knife node delete $i -y; knife ec2 server delete $i -y; done

Sample Script

./lbDemo.sh

cat lbDemo.sh 

nohup knife ec2 server create "role[webserver]" -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/web1.out &
nohup knife ec2 server create "role[webserver]" -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/web2.out &
nohup knife ec2 server create "role[lb]" -f t1.micro -i ami-4a0df923 -G default,tse-demo -S botchagalupe -x ubuntu -I ~/.ssh/id_rsa  -y >/tmp/lb.out &

Refresh the LB Chef Client

knife ssh "role:lb" "sudo chef-client" -x ubuntu -a ec2.public_hostname
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment