fog or: How I Learned to Stop Worrying and Love the Cloud
Upcoming SlideShare
Loading in...5
×
 

fog or: How I Learned to Stop Worrying and Love the Cloud

on

  • 6,918 views

Learn how to easily get started on cloud computing with fog. If you can control your infrastructure choices, you’ll make better choices in development and get what you need in production. You'll get ...

Learn how to easily get started on cloud computing with fog. If you can control your infrastructure choices, you’ll make better choices in development and get what you need in production. You'll get an overview of fog and concrete examples to give you a head start on your provisioning workflow.

Statistics

Views

Total Views
6,918
Views on SlideShare
6,917
Embed Views
1

Actions

Likes
10
Downloads
87
Comments
0

1 Embed 1

http://paper.li 1

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

fog or: How I Learned to Stop Worrying and Love the Cloud fog or: How I Learned to Stop Worrying and Love the Cloud Presentation Transcript

  • OR:fog HOW I LEARNED TO STOP WORRYING AND LOVE THE CLOUD
  • geemus (Wesley Beary)web: github.com/geemustwitter: @geemus
  • employer and sponsorweb: engineyard.comtwitter: @engineyard View slide
  • API driven on demand servicesCLOUD core: compute, dns, storage also: kvs, load balance, ... View slide
  • What?on demand - pay for only what you actually use
  • What?on demand - pay for only what you actually useflexible - add and remove resources in minutes (instead of weeks)
  • What?on demand - pay for only what you actually useflexible - add and remove resources in minutes (instead of weeks)repeatable - code, test, repeat
  • What?on demand - pay for only what you actually useflexible - add and remove resources in minutes (instead of weeks)repeatable - code, test, repeatresilient - build better systems with transient resources
  • But, but...
  • But, but...option overload - which provider should I use
  • But, but...option overload - which provider should I useintimidating - each service requires separate expertise
  • But, but...option overload - which provider should I useintimidating - each service requires separate expertisetools - vastly different API’s built on varying levels of quality
  • Ruby cloud computingweb: github.com/geemus/fogtwitter: @fog
  • Why?portable - AWS, Bluebox, Brightbox, Google, Rackspace, Slicehost, Terremark, ...powerful - compute, storage, collections, models, mocks, requests, ...established - 50k downloads, 860 followers, 100 forks, 40 contributors, me, ...Fog.mock! - faster, cheaper, simulated cloud behavior
  • Who?libraries - carrierwave, chef, deckard, gaff, gemcutter, ...products - DevStructure, Engine Yard, iSwifter, OpenFeint, RowFeeder, ...
  • What?That’s great and all but I don’t have a use case...
  • What?That’s great and all but I don’t have a use case...uptime - because who wants a busted web site?
  • Setup geymus ~ ⌘ gem install fog orgeymus ~ ⌘ sudo gem install fog
  • Get Connected7 # setup a connection to the service8 compute = Fog::Compute.new(credentials)
  • Get Connected1 credentials = {2   :provider           => Rackspace,3   :rackspace_api_key  => RACKSPACE_API_KEY,4   :rackspace_username => RACKSPACE_USERNAME5 }67 # setup a connection to the service8 compute = Fog::Compute.new(credentials)
  • Bootstrap7 # boot server and setup ssh keys8 server = compute.servers.bootstrap(server_attributes)
  • Bootstrap1 server_attributes = {2   :image_id         => 49,3   :private_key_path => PRIVATE_KEY_PATH,4   :public_key_path  => PUBLIC_KEY_PATH5 }67 # boot server and setup ssh keys8 server = compute.servers.bootstrap(server_attributes)
  • Servers?
  • Servers?1 compute.servers # list servers, same as #all
  • Servers?1 compute.servers # list servers, same as #all23 compute.servers.get(1234567890) # server by id
  • Servers?1 compute.servers # list servers, same as #all23 compute.servers.get(1234567890) # server by id45 compute.servers.reload # update to latest
  • Servers?1 compute.servers # list servers, same as #all23 compute.servers.get(1234567890) # server by id45 compute.servers.reload # update to latest67 compute.servers.new(attributes) # local model
  • Servers?1 compute.servers # list servers, same as #all23 compute.servers.get(1234567890) # server by id45 compute.servers.reload # update to latest67 compute.servers.new(attributes) # local model89 compute.servers.create(attributes) # remote model
  • bootstrap?
  • bootstrap?convenience method for servers
  • bootstrap? convenience method for serverscreate - creates a server matching attributeswait_for { ready? } - waits until server respondsssh - sets up ssh keys and disables password authentication
  • ping
  • ping1 # ping target 10 times2 ssh_results = server.ssh("ping -c 10 #{target}")
  • ping1 # ping target 10 times2 ssh_results = server.ssh("ping -c 10 #{target}")3 stdout = ssh_results.first.stdout
  • ping1 # ping target 10 times2 ssh_results = server.ssh("ping -c 10 #{target}")3 stdout = ssh_results.first.stdout45 # parse result, last line is summary6 # round-trip min/avg/max/stddev = A.A/B.B/C.C/D.D ms
  • ping1 # ping target 10 times2 ssh_results = server.ssh("ping -c 10 #{target}")3 stdout = ssh_results.first.stdout45 # parse result, last line is summary6 # round-trip min/avg/max/stddev = A.A/B.B/C.C/D.D ms7 stats = stdout.split("/n").last.split( )[-2]8 min, avg, max, stddev = stats.split(/)
  • ping1 # ping target 10 times2 ssh_results = server.ssh("ping -c 10 #{target}")3 stdout = ssh_results.first.stdout45 # parse result, last line is summary6 # round-trip min/avg/max/stddev = A.A/B.B/C.C/D.D ms7 stats = stdout.split("/n").last.split( )[-2]8 min, avg, max, stddev = stats.split(/) NOTE: most complex code was string parsing!?!
  • cleanup
  • cleanup 1 # shutdown the server 2 server.destroy
  • cleanup 1 # shutdown the server 2 server.destroy 3 4 # return the data as a hash 5 { 6   :min    => min, 7   :avg    => avg, 8   :max    => max, 9   :stddev => stddev10 }
  • geopinging v1 1 # specify a different provider 2 credentials = { 3   :provider => AWS, 4   :aws_access_key_id => AWS_ACCESS_KEY_ID, 5   :aws_secret_access_key => AWS_SECRET_ACCESS_KEY 6 } 7 8 server_attributes = { 9   :image_id         => ami-1a837773,10   :private_key_path => PRIVATE_KEY_PATH,11   :public_key_path  => PUBLIC_KEY_PATH,12   :username         => ubuntu13 }
  • geopinging v21 # specify a different aws region2 # [ap-southeast-1, eu-west-1, us-west-1]3 credentials.merge!({4   :region => eu-west-15 })
  • geopinging v...portable - AWS, Bluebox, Brightbox, Rackspace, Slicehost, Terremark, ...
  • geopinging v...portable - AWS, Bluebox, Brightbox, Rackspace, Slicehost, Terremark, ... lather, rinse, repeat
  • How?That is awesome, but how did you know...
  • exploringgeymus ~ ⌘ fog  To run as default, add the following to ~/.fog:default:  :aws_access_key_id:     INTENTIONALLY_LEFT_BLANK  :aws_secret_access_key: INTENTIONALLY_LEFT_BLANK  :public_key_path:       INTENTIONALLY_LEFT_BLANK  :private_key_path:      INTENTIONALLY_LEFT_BLANK  :rackspace_api_key:     INTENTIONALLY_LEFT_BLANK  :rackspace_username:    INTENTIONALLY_LEFT_BLANK ...
  • sign posts
  • sign postsgeymus ~ ⌘ fog Welcome to fog interactive! :default credentials provide AWS and Rackspace
  • sign postsgeymus ~ ⌘ fog Welcome to fog interactive! :default credentials provide AWS and Rackspace>> providers[AWS, Rackspace]
  • sign postsgeymus ~ ⌘ fog Welcome to fog interactive! :default credentials provide AWS and Rackspace>> providers[AWS, Rackspace]>> Rackspace.collections[:directories, :files, :flavors, :images, :servers]
  • sign postsgeymus ~ ⌘ fog Welcome to fog interactive! :default credentials provide AWS and Rackspace>> providers[AWS, Rackspace]>> Rackspace.collections[:directories, :files, :flavors, :images, :servers]>> Rackspace[:compute]#<Fog::Rackspace::Compute ...>
  • sign postsgeymus ~ ⌘ fog Welcome to fog interactive! :default credentials provide AWS and Rackspace>> providers[AWS, Rackspace]>> Rackspace.collections[:directories, :files, :flavors, :images, :servers]>> Rackspace[:compute]#<Fog::Rackspace::Compute ...>>> Rackspace[:compute].requests
  • sign postsgeymus ~ ⌘ fog Welcome to fog interactive! :default credentials provide AWS and Rackspace>> providers[AWS, Rackspace]>> Rackspace.collections[:directories, :files, :flavors, :images, :servers]>> Rackspace[:compute]#<Fog::Rackspace::Compute ...>>> Rackspace[:compute].requests[:confirm_resized_server, ..., :update_server]
  • requests?
  • requests?>> Rackspace[:compute].list_servers
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = {
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []},
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []},@headers = {
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []},@headers = { "X-PURGE-KEY"=>"/______/servers",
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []},@headers = { "X-PURGE-KEY"=>"/______/servers", ...,
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []},@headers = { "X-PURGE-KEY"=>"/______/servers", ..., "Connection"=>"keep-alive"
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []},@headers = { "X-PURGE-KEY"=>"/______/servers", ..., "Connection"=>"keep-alive"},
  • requests?>> Rackspace[:compute].list_servers#<Excon::Response:0x________@body = { "servers" => []},@headers = { "X-PURGE-KEY"=>"/______/servers", ..., "Connection"=>"keep-alive"},@status=200>
  • sanity check
  • sanity check>> Rackspace.servers.select {|server| server.ready?} <Fog::Rackspace::Compute::Servers filters={} [] >
  • sanity check>> Rackspace.servers.select {|server| server.ready?} <Fog::Rackspace::Compute::Servers filters={} [] >>> AWS.servers.select {|server| server.ready?} <Fog::AWS::Compute::Servers [] >
  • sanity check>> Rackspace.servers.select {|server| server.ready?} <Fog::Rackspace::Compute::Servers filters={} [] >>> AWS.servers.select {|server| server.ready?} <Fog::AWS::Compute::Servers [] >>> exit
  • finding images
  • finding images>> Rackspace.images.table([:id, :name]) +---------+------------------------------------------+
  • finding images>> Rackspace.images.table([:id, :name]) +---------+------------------------------------------+ | id | name | +---------+------------------------------------------+ | 49 | Ubuntu 10.04 LTS (lucid) | +---------+------------------------------------------+ ...
  • finding images>> Rackspace.images.table([:id, :name]) +---------+------------------------------------------+ | id | name | +---------+------------------------------------------+ | 49 | Ubuntu 10.04 LTS (lucid) | +---------+------------------------------------------+ ...>> AWS.images # I use alestic.com listing
  • finding images>> Rackspace.images.table([:id, :name]) +---------+------------------------------------------+ | id | name | +---------+------------------------------------------+ | 49 | Ubuntu 10.04 LTS (lucid) | +---------+------------------------------------------+ ...>> AWS.images # I use alestic.com listing...
  • exploring...
  • exploring... It takes forever!
  • exploring... It takes forever! It’s so expensive!
  • exploring... It takes forever! It’s so expensive!A warm welcome for Fog.mock!
  • Mocks!geymus ~ ⌘ FOG_MOCK=true fog or require ‘fog’ Fog.mock!
  • simulation
  • simulationMost functions just work!
  • simulation Most functions just work!Unimplemented mocks? Errors keep you on track.
  • simulation Most functions just work! Unimplemented mocks? Errors keep you on track.Tests run against both, so it is either consistent or a bug.
  • Back to Business I have a bunch of data now what?
  • Back to Business I have a bunch of data now what? storage - aggregating cloud data
  • Get Connected7 # setup a connection to the service8 storage = Fog::Storage.new(credentials)
  • Get Connected1 credentials = {2   :provider => AWS,3   :aws_access_key_id => AWS_ACCESS_KEY_ID,4   :aws_secret_access_key => AWS_SECRET_ACCESS_KEY5 }67 # setup a connection to the service8 storage = Fog::Storage.new(credentials)
  • directories1 # create a directory2 directory = storage.directories.create(3   :key    => directory_name,4   :public => true5 )
  • files
  • files1 # store the file2 file = directory.files.create(3   :body   => File.open(path),4   :key    => name,5   :public => true6 )
  • files1 # store the file2 file = directory.files.create(3   :body   => File.open(path),4   :key    => name,5   :public => true6 )78 # return the public url for the file9 file.public_url
  • geostorage 1 # specify a different provider 2 credentials = { 3   :provider           => Rackspace, 4   :rackspace_api_key  => RACKSPACE_API_KEY, 5   :rackspace_username => RACKSPACE_USERNAME 6 }
  • cleanup
  • cleanupgeymus ~ ⌘ fog...
  • cleanupgeymus ~ ⌘ fog...>> directory = AWS.directories.get(DIRECTORY_NAME)...
  • cleanupgeymus ~ ⌘ fog...>> directory = AWS.directories.get(DIRECTORY_NAME)...>> directory.files.each {|file| file.destroy}...
  • cleanupgeymus ~ ⌘ fog...>> directory = AWS.directories.get(DIRECTORY_NAME)...>> directory.files.each {|file| file.destroy}...>> directory.destroy...
  • cleanupgeymus ~ ⌘ fog...>> directory = AWS.directories.get(DIRECTORY_NAME)...>> directory.files.each {|file| file.destroy}...>> directory.destroy...>> exit
  • Phase 3: ProfitI’ve got the data, but how do I freemium?
  • Phase 3: ProfitI’ve got the data, but how do I freemium? dns - make your cloud (premium) accessible
  • Get Connected7 # setup a connection to the service8 dns = Fog::DNS.new(credentials)
  • Get Connected1 credentials = {2   :provider  => Zerigo,3   :zerigo_email => AWS_ACCESS_KEY_ID,4   :zerigo_token => AWS_SECRET_ACCESS_KEY5 }67 # setup a connection to the service8 dns = Fog::DNS.new(credentials)
  • zones1 # create a zone2 zone = dns.zone.create(3   :domain => domain_name,4   :email  => "admin@#{domain_name}"5 )
  • records1 # create a record2 record = zones.records.create(3   :ip   => 1.2.3.4,4   :name => "#{customer_name}.#{domain_name}",5   :type => A6 )
  • cleanupgeymus ~ ⌘ fog...>> zone = Zerigo.zones.get(ZONE_ID)...>> zone.records.each {|record| record.destroy}...>> zone.destroy...>> exit
  • Roadmapcompute - consolidating and refining the shared api
  • Roadmapcompute - consolidating and refining the shared apicompletion - fill in remaining requests and mocks for core services
  • Roadmapcompute - consolidating and refining the shared apicompletion - fill in remaining requests and mocks for core serviceserrors - more consistent error raising and handling
  • Roadmapcompute - consolidating and refining the shared apicompletion - fill in remaining requests and mocks for core serviceserrors - more consistent error raising and handlingdocumentation - blog posts, examples, fog.io
  • Thanks!
  • Thanks! Questions? (see also: README) examples - http://gist.github.com/729992 slides - http://slidesha.re/hR8sP9 repo - http://github.com/geemus/fog bugs - http://github.com/geemus/fog/issues irc - irc://irc.freenode.net/ruby-fogmailing list - http://groups.google.com/group/ruby-fog twitter - @fog and @geemus