Browse Source

Amazon multi-host support & amazon network setup script

Hamilton Turner 11 years ago
parent
commit
20c7ba331c

+ 121 - 21
toolset/deployment/vagrant-multi/Vagrantfile

@@ -11,44 +11,113 @@ Vagrant.configure("2") do |config|
     end
     end
   end
   end
 
 
+  # Add some default host entries
+  config.vm.provision :shell do |sh|
+    sh.inline = "
+      echo 127.0.0.1 `hostname` >> /etc/hosts
+      echo 172.16.0.18 TFB-dbserver >> /etc/hosts
+      echo 172.16.0.17 TFB-loadserver >> /etc/hosts
+      echo 172.16.0.16 TFB-appserver >> /etc/hosts
+      echo Updated /etc/hosts file:
+      cat /etc/hosts"
+  end
+
   # Build the DB and client servers before the 
   # Build the DB and client servers before the 
   # app server
   # app server
-  config.vm.define "db" do |db|
-    db.vm.hostname = "TFB-dbserver"
-    db.vm.box = "ubuntu/trusty64"
-    db.vm.network "private_network", ip: "172.16.16.18"
-    db.vm.synced_folder "../../..", "/FrameworkBenchmarks"
+  config.vm.define "load" do |load|
+    load.vm.hostname = "TFB-loadserver"
+    load.vm.box = "ubuntu/trusty64"
+    # virtualbox
+    #load.vm.network "private_network", ip: "172.16.16.17"
+    #load.vm.synced_folder "../../..", "/FrameworkBenchmarks"
 
 
-    # Database-specific setup
-    db.vm.provision "shell" do |sh|
-      sh.inline = "cat ~/.ssh/database.pub >> ~/.ssh/authorized_keys"
+    # Configure our SSH key 
+    # (and hostname for AWS)
+    load.vm.provision "shell" do |sh|
+      sh.inline = "cat ~/.ssh/client.pub >> ~/.ssh/authorized_keys
+                   echo 'TFB-loadserver' | sudo tee /etc/hostname
+                   sudo hostname 'TFB-loadserver'"
       sh.privileged = false
       sh.privileged = false
     end
     end
 
 
-    db.vm.provision "shell" do |sh|
+    load.vm.provision "shell" do |sh|
       sh.path = "bootstrap.sh"
       sh.path = "bootstrap.sh"
       sh.privileged = false
       sh.privileged = false
-      sh.args = "database"
+      sh.args = "client"
+    end
+
+    load.vm.provider :aws do |aws, override|
+      aws.access_key_id = ENV['TFB_AWS_ACCESS_KEY'] 
+      aws.secret_access_key = ENV['TFB_AWS_SECRET_KEY']
+      aws.keypair_name = ENV['TFB_AWS_KEY_NAME']
+      override.ssh.private_key_path = ENV['TFB_AWS_KEY_PATH']
+
+      override.vm.box = "dummy"
+      override.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
+      aws.ami = "ami-62c8160a"
+      override.ssh.username = "ubuntu"
+      
+      aws.private_ip_address = "172.16.0.17"
+      aws.associate_public_ip = true
+      aws.subnet_id = "subnet-2737230f"
+      aws.security_groups = ["sg-871240e2"]
+
+      aws.tags = {
+        'Project' => 'FrameworkBenchmarks',
+        'TFB_role' => 'loadgen'
+       }
+
+      aws.instance_type = "m1.small"
     end
     end
   end
   end
 
 
   # Build the DB and client servers before the 
   # Build the DB and client servers before the 
   # app server
   # app server
-  config.vm.define "load" do |load|
-    load.vm.hostname = "TFB-loadserver"
-    load.vm.box = "ubuntu/trusty64"
-    load.vm.network "private_network", ip: "172.16.16.17"
-    load.vm.synced_folder "../../..", "/FrameworkBenchmarks"
+  config.vm.define "db" do |db|
+    db.vm.hostname = "TFB-dbserver"
+    db.vm.box = "ubuntu/trusty64"
+    
+    # Only work in virtualbox
+    #db.vm.network "private_network", ip: "172.16.0.18"
+    #db.vm.synced_folder "../../..", "/FrameworkBenchmarks"
 
 
-    load.vm.provision "shell" do |sh|
-      sh.inline = "cat ~/.ssh/client.pub >> ~/.ssh/authorized_keys"
+    # Configure our SSH key 
+    # (and hostname for AWS)
+    db.vm.provision "shell" do |sh|
+      sh.inline = "cat ~/.ssh/database.pub >> ~/.ssh/authorized_keys
+                   echo 'TFB-dbserver' | sudo tee /etc/hostname
+                   sudo hostname 'TFB-dbserver'"
       sh.privileged = false
       sh.privileged = false
     end
     end
 
 
-    load.vm.provision "shell" do |sh|
+    db.vm.provision "shell" do |sh|
       sh.path = "bootstrap.sh"
       sh.path = "bootstrap.sh"
       sh.privileged = false
       sh.privileged = false
-      sh.args = "client"
+      sh.args = "database"
+    end
+
+    db.vm.provider :aws do |aws, override|
+      aws.access_key_id = ENV['TFB_AWS_ACCESS_KEY'] 
+      aws.secret_access_key = ENV['TFB_AWS_SECRET_KEY']
+      aws.keypair_name = ENV['TFB_AWS_KEY_NAME']
+      override.ssh.private_key_path = ENV['TFB_AWS_KEY_PATH']
+
+      override.vm.box = "dummy"
+      override.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
+      aws.ami = "ami-62c8160a"
+      override.ssh.username = "ubuntu"
+      
+      aws.private_ip_address = "172.16.0.18"
+      aws.associate_public_ip = true
+      aws.subnet_id = "subnet-2737230f"
+      aws.security_groups = ["sg-871240e2"]
+
+      aws.tags = {
+        'Project' => 'FrameworkBenchmarks',
+        'TFB_role' => 'database'
+       }
+
+      aws.instance_type = "m1.small"
     end
     end
   end
   end
 
 
@@ -57,16 +126,47 @@ Vagrant.configure("2") do |config|
     app.vm.hostname = "TFB-appserver"
     app.vm.hostname = "TFB-appserver"
     app.vm.box = "ubuntu/trusty64"
     app.vm.box = "ubuntu/trusty64"
     app.vm.network "private_network", ip: "172.16.16.16"
     app.vm.network "private_network", ip: "172.16.16.16"
-    app.vm.synced_folder "../../..", "/FrameworkBenchmarks"
+    
+    # app.vm.synced_folder "../../..", "/FrameworkBenchmarks"
+    
     app.vm.network :forwarded_port, guest: 8080, host: 28080
     app.vm.network :forwarded_port, guest: 8080, host: 28080
 
 
+    # Configure our Hostname for AWS
+    app.vm.provision "shell" do |sh|
+      sh.inline = "echo 'TFB-appserver' | tee /etc/hostname
+                   hostname 'TFB-appserver'"
+    end
+
     app.vm.provision "shell" do |sh|
     app.vm.provision "shell" do |sh|
       sh.path = "bootstrap.sh"
       sh.path = "bootstrap.sh"
       sh.privileged = false
       sh.privileged = false
       sh.args = "server"
       sh.args = "server"
     end
     end
+
+    app.vm.provider :aws do |aws, override|
+      aws.access_key_id = ENV['TFB_AWS_ACCESS_KEY'] 
+      aws.secret_access_key = ENV['TFB_AWS_SECRET_KEY']
+      aws.keypair_name = ENV['TFB_AWS_KEY_NAME']
+      override.ssh.private_key_path = ENV['TFB_AWS_KEY_PATH']
+
+      override.vm.box = "dummy"
+      override.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
+      aws.ami = "ami-62c8160a"
+      override.ssh.username = "ubuntu"
+      
+      aws.private_ip_address = "172.16.0.16"
+      aws.associate_public_ip = true
+      aws.subnet_id = "subnet-2737230f"
+      aws.security_groups = ["sg-871240e2"]
+
+      aws.tags = {
+        'Project' => 'FrameworkBenchmarks',
+        'TFB_role' => 'appserver'
+       }
+
+      aws.instance_type = "m1.small"
+    end
   end
   end
 
 
 
 
-  
 end
 end

+ 3 - 3
toolset/deployment/vagrant-multi/bootstrap.sh

@@ -7,9 +7,9 @@
 # and Amazon (username ubuntu)
 # and Amazon (username ubuntu)
 
 
 # Setup some nice TFB defaults
 # Setup some nice TFB defaults
-echo "export TFB_SERVER_HOST=172.16.16.16" >> ~/.bash_profile
-echo "export TFB_CLIENT_HOST=172.16.16.17" >> ~/.bash_profile
-echo "export TFB_DATABASE_HOST=172.16.16.18" >> ~/.bash_profile
+echo "export TFB_SERVER_HOST=172.16.0.16" >> ~/.bash_profile
+echo "export TFB_CLIENT_HOST=172.16.0.17" >> ~/.bash_profile
+echo "export TFB_DATABASE_HOST=172.16.0.18" >> ~/.bash_profile
 echo "export TFB_CLIENT_USER=$USER" >> ~/.bash_profile
 echo "export TFB_CLIENT_USER=$USER" >> ~/.bash_profile
 echo "export TFB_DATABASE_USER=$USER" >> ~/.bash_profile
 echo "export TFB_DATABASE_USER=$USER" >> ~/.bash_profile
 echo "export TFB_CLIENT_IDENTITY_FILE=$HOME/.ssh/client" >> ~/.bash_profile
 echo "export TFB_CLIENT_IDENTITY_FILE=$HOME/.ssh/client" >> ~/.bash_profile

+ 98 - 0
toolset/deployment/vagrant-multi/setup_aws.py

@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+#
+# Prepares Amazon to run our test setup script
+#
+
+import subprocess
+import json
+import logging
+log = logging.getLogger('aws')
+
+nwtags = "Key=Project,Value=FrameworkBenchmarks Key=TFB_Role,Value=network"
+
+def setup_vpc():
+  '''Sets up a Virtual Private Cloud to allow hosts to communicate'''
+  
+  # Setup VPC
+  log.info("Creating a new Virtual Private Cloud...")
+  log.info(" See details at http://console.aws.amazon.com/vpc")
+  vpc = run_aws("create-vpc --cidr-block 172.16.0.0/16 --instance-tenancy default")
+  vpcid = vpc["Vpc"]["VpcId"]
+
+  run_aws("modify-vpc-attribute --vpc-id %s --enable-dns-support" % vpcid)
+  run_aws("modify-vpc-attribute --vpc-id %s --no-enable-dns-hostnames" % vpcid)
+  run_aws("create-tags --resources %s --tags %s Key=Name,Value=TFB_Network" % (vpcid, nwtags))
+  log.debug(run_aws("describe-vpcs --vpc-id %s" % vpcid, load=False))
+
+  # Setup internet gateway
+  log.info("Creating InternetGateway for the VPC...")
+  igw = run_aws("create-internet-gateway")
+  igwid = igw["InternetGateway"]["InternetGatewayId"]
+  run_aws("create-tags --resources %s --tags %s Key=Name,Value=TFB_Gateway" % (igwid, nwtags))
+  run_aws("attach-internet-gateway --internet-gateway-id %s --vpc-id %s" % (igwid, vpcid))
+  log.debug(run_aws("describe-internet-gateways --internet-gateway-ids %s" % igwid, load=False))
+
+  # Setup public subnet 
+  # NOTE: We considered using a public and private subnet, but 
+  # this requires us to launch an extra EC2 instance for the duration of the 
+  # benchmark to handle the NAT between the public subnet and the private subnet,
+  # so the cost is quite high. Also, Internet traffic is only generated during 
+  # framework setup stages (e.g. during software installation), not during the 
+  # running of the benchmark. 
+  # We chose to use a single public subnet and filter inbound traffic to prevent 
+  # interference during the test
+  log.info("Creating subnet inside the VPC...")
+  pubsub = run_aws("create-subnet --vpc-id %s --cidr-block 172.16.0.0/24" % vpcid)
+  pubid = pubsub["Subnet"]["SubnetId"]
+  log.debug("Found subnet id: %s", pubid)
+
+  #run_aws("modify-subnet-attribute --subnet-id %s --map-public-ip-on-launch" % pubid)
+  run_aws("create-tags --resources %s --tags %s Key=Name,Value=TFB_Public" % (pubid, nwtags))
+  log.debug(run_aws("describe-subnets --subnet-ids %s" % pubid, load=False))
+  
+  # Setup routing
+  log.info("Creating routing table for VPC...")
+  route = run_aws("describe-route-tables --filters Name=vpc-id,Values=%s" % vpcid)
+  routeid = route["RouteTables"][0]["RouteTableId"]
+  run_aws("create-tags --resources %s --tags %s Key=Name,Value=TFB_Routing" % (routeid, nwtags))
+  log.info("  Creating route to internet...")
+  run_aws("create-route --route-table-id %s --destination-cidr-block 0.0.0.0/0 --gateway-id %s" % (routeid, igwid)) 
+  log.info("  Associating routing table and subnet...")
+  run_aws("associate-route-table --route-table-id %s --subnet-id %s" % (routeid, pubid))
+
+  # Setup default security group for instances launched in the VPC
+  log.info("Creating default security group for VPC")
+  group = run_aws("create-security-group --group-name TFB_Security --vpc-id %s --description 'FrameworkBenchmarks security group'" % vpcid)
+  groupid = group["GroupId"]
+  run_aws("create-tags --resources %s --tags %s Key=Name,Value=TFB_Security" % (groupid, nwtags))
+  run_aws("authorize-security-group-ingress --group-id %s --protocol tcp --port 22 --cidr 0.0.0.0/0" % groupid)
+  # run_aws("authorize-security-group-egress --group-id %s --protocol -1 --cidr 0.0.0.0/0 --port all" % groupid)
+  run_aws("authorize-security-group-ingress --group-id %s --source-group %s --protocol -1 --port -1" % (groupid, groupid))
+
+  return vpcid
+
+def unset_vpc(vpcid):
+  run_aws("delete-vpc --vpc-id %s" % vpcid)
+
+def run_aws(command, prefix=True, load=True):
+  '''Runs an AWS command and returns the JSON
+  prefix: Should we prefix "aws ec2 " to your command
+  load: Should we auto-load the response JSON into a python object? 
+  '''
+  if prefix:
+    command = "aws ec2 %s" % command
+  log.debug("Request : %s", command)
+  result = subprocess.check_output(command, shell=True)
+  log.debug("Response: %s", result)
+  if load:
+    return json.loads(result)
+  else:
+    return result
+
+if __name__ == "__main__":
+  logging.basicConfig(level=logging.INFO)
+  usage = '''Usage: '''
+
+  vpcid = setup_vpc()
+
+  # unset_vpc(vpcid)