Skip to content

Instantly share code, notes, and snippets.

@botchagalupe
Created July 11, 2011 19:51
Show Gist options
  • Save botchagalupe/1076652 to your computer and use it in GitHub Desktop.
Save botchagalupe/1076652 to your computer and use it in GitHub Desktop.
Devops Workshop Students Notes

Setup a Three Server HAPROXY/APACHE2 Setup

Ubuntu Image used in class

images: 
 
Student Workstation - ami-2e7e8747 
Student lab servers - ami-0ada1e63

Notes: Use 

knife bootstrap <IP Address of the class assigned EC2 instance> --sudo -x ubuntu -Pdto_100

Part 1 (Setup)

Register for an Opscode Platform Account

Check Chef Version

$ chef-client -v
Chef: 0.10.2

Copy the keys and knife configuration you downloaded earlier into this directory:

cp USERNAME.pem ~/chef-repo/.chef
cp ORGANIZATION-validator.pem ~/chef-repo/.chef
cp knife.rb ~/chef-repo/.chef

Run the following command to confirm knife is working with the Hosted Chef API.

cd ~/chef-repo
knife client list
[
  "ORGANIZATION-validator"   
]

Part 2 (Web Server)

Create a new cookbook called demo

Create a Demo Cookbook

cd ~/chef-repo/cookbooks

knife cookbook create demo

Download the apache2 cookbook

We are going to use the "apache2" cookbook in our new demo cookbook so we need to download it.

knife cookbook site download apache2

tar -xvf apache2-0.99.4.tar.gz 

Update the Metadata in the demo cookbook (in ../cookbooks/demo/meta.rb )

We need to associate a dependency between this new "demo" cookbooks and the "apache2" cookbook we are going to reference.

vi ~/chef-repo/cookbooks/demo/metadata.rb

Add the following code

depends "apache2"

Update the the default.rb recipe in the ~/chef-repo/cookbooks/demo/recipes directory__

vi ~/chef-repo/cookbooks/demo/recipes/default.rb

Add the following code

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/

vi ~/chef-repo/cookbooks/demo/templates/default/index.html.erb

Add the following code

<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 cookbooks -a

knife cookbook upload -a

knife cookbook list

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

vi ~/chef-repo/roles/webserver.rb

Add the following code

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 ~/chef-repo/roles/webserver.rb 

knife role show webserver

Launch and bootstrap two web servers

knife bootstrap <IP Address of your second server>" -r "role[webserver]" --sudo -x ubuntu -Pdto_100

Check the the status of the instance

knife status

knife node list

curl <the public IP of the webserver instance>

Part 2 (Create a Load Balancer)

Demo Part Two (Launch an Happroxy Server and integrate with two web servers)

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 download -d haproxy

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

vi ~/chef-repo/cookbooks/haproxy/recipes/weblb.rb

Add the following code

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.weblb.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.__

vi ~/chef-repo/cookbooks/haproxy/templates/default/haproxy.cfg.weblb.erb

Add the following code

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

vi ~/chef-repo/roles/lb.rb

Add the following code

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

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

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

knife role from file ~/chef-repo/roles/lb.rb 

Show the newly loaded role__

knife role show lb

Launch and bootstrap the LB (haproxy) servers

knife bootstrap <IP Address of your second server>" "role[lb]" --sudo -x ubuntu -P<passwd>    

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

Adding more servers...

Launch and bootstrap another web server

knife bootstrap <IP Address of your third server>" -r "role[webserver]" --sudo -x ubuntu -Pdto_100

Check the the status of the instance

knife status

knife node list

curl <the public IP of the webserver instance>

Rerun the chef-client on the LB to pick up the new servers

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment