Class: CloudMaker::EC2
- Inherits:
-
Object
- Object
- CloudMaker::EC2
- Defined in:
- lib/cloud_maker/ec2.rb
Constant Summary collapse
- CLOUD_MAKER_CONFIG =
Public: A CloudMaker::Config hash that describes the config properties EC2 relies on.
{ 'cloud-maker' => { 'ami' => { 'required' => true, 'description' => "The Amazon AMI ID for the instance." }, 'instance_type' => { 'required' => true, 'description' => "The Amazon instance type, eg. m1.small." }, 'availability_zone' => { 'required' => true, 'description' => "The Amazon availability zone, eg. us-east-1a" }, 'key_pair' => { 'default' => "", 'description' => "The name of an Amazon key pair, so you can actually login to the instance." }, 'elastic_ip' => { 'default' => '', 'description' => "An elastic IP address you control that you would like to associate to the instance." }, 'security_group' => { 'default' => 'default', 'required' => true, 'description' => 'The Amazon EC2 security group to launch the instance with.' }, 'iam_role' => { 'default' => '', 'description' => 'The IAM instance profile name or ARN you would like to use.' }, 'cname' => { 'default' => '', 'description' => "A dns entry you would like to CNAME to this instance." } } }
- BUCKET_TAG =
Public: The name of the tag that will be used to find the name of an s3 bucket for archiving/information retrieval
's3_archive_bucket'
Instance Attribute Summary collapse
-
#aws_access_key_id ⇒ Object
Public: Gets/Sets the AWS secret.
-
#aws_secret_access_key ⇒ Object
Public: Gets/Sets the AWS access key.
-
#ec2 ⇒ Object
Internal: Gets/Sets the AWS::EC2 instance.
Class Method Summary collapse
-
.instance_to_hash(instance) ⇒ Object
Public: Generates a hash of properties from an AWS::EC2 instance.
Instance Method Summary collapse
-
#find_instance(instance_id) ⇒ Object
Internal: Find the instance object for an instance ID regardless of what region the instance is in.
-
#find_region(availability_zone) ⇒ Object
Internal: Find the region object for a given availability zone.
-
#info(instance_id) ⇒ Object
Public: Fetch archived information about an instance.
-
#initialize(options) ⇒ EC2
constructor
Public: Creates a new EC2 instance.
-
#launch(cloud_maker_config) ⇒ Object
Public: Launches a new EC2 instance, associates any specified elastic IPS with it, adds any specified tags, and archives the launch details to S3.
-
#terminate(instance_id) ⇒ Object
Public: Terminates the specified EC2 instance.
Constructor Details
#initialize(options) ⇒ EC2
Public: Creates a new EC2 instance
cloud_maker_config - A CloudMaker::Config object describing the instance
to be managed.
options - S3 configuration options
:aws_access_key_id - (required) The AWS access key
:aws_secret_access_key - (required) The AWS secret
Returns a new CloudMaker::EC2 instance Raises RuntimeError if any of the required options are not specified
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/cloud_maker/ec2.rb', line 62 def initialize() required_keys = [:aws_access_key_id, :aws_secret_access_key] unless (required_keys - .keys).empty? raise RuntimeError.new("Instantiated #{self.class} without required attributes: #{required_keys - .keys}.") end self.aws_access_key_id = [:aws_access_key_id] self.aws_secret_access_key = [:aws_secret_access_key] self.ec2 = AWS::EC2.new(:access_key_id => self.aws_access_key_id, :secret_access_key => self.aws_secret_access_key) end |
Instance Attribute Details
#aws_access_key_id ⇒ Object
Public: Gets/Sets the AWS secret.
6 7 8 |
# File 'lib/cloud_maker/ec2.rb', line 6 def aws_access_key_id @aws_access_key_id end |
#aws_secret_access_key ⇒ Object
Public: Gets/Sets the AWS access key.
4 5 6 |
# File 'lib/cloud_maker/ec2.rb', line 4 def aws_secret_access_key @aws_secret_access_key end |
#ec2 ⇒ Object
Internal: Gets/Sets the AWS::EC2 instance.
8 9 10 |
# File 'lib/cloud_maker/ec2.rb', line 8 def ec2 @ec2 end |
Class Method Details
.instance_to_hash(instance) ⇒ Object
Public: Generates a hash of properties from an AWS::EC2 instance
Returns a hash of properties for the instance.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/cloud_maker/ec2.rb', line 211 def instance_to_hash(instance) { :instance_id => instance.id, :ami => instance.image_id, :api_termination_disabled => instance.api_termination_disabled?, :dns_name => instance.dns_name, :ip_address => instance.ip_address, :private_ip_address => instance.private_ip_address, :key_name => instance.key_name, :owner_id => instance.owner_id, :status => instance.status, :tags => instance..inject({}) {|hash, tag| hash[tag.first] = tag.last;hash} } end |
Instance Method Details
#find_instance(instance_id) ⇒ Object
Internal: Find the instance object for an instance ID regardless of what region the instance is in. It looks in the default region (us-east-1) first and then looks in all regions if it’s not there.
Returns nil or an AWS::EC2::Instance
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/cloud_maker/ec2.rb', line 176 def find_instance(instance_id) # Check the default region first return ec2.instances[instance_id] if ec2.instances[instance_id].exists? # If we don't find it there look in every region instance = nil ec2.regions.each do |region| if region.instances[instance_id].exists? instance = region.instances[instance_id] break end end instance end |
#find_region(availability_zone) ⇒ Object
Internal: Find the region object for a given availability zone. Currently works based on amazon naming conventions and will break if they change.
Returns an AWS::EC2::Region Raises a RuntimeError if the region doesn’t exist
198 199 200 201 202 203 204 205 |
# File 'lib/cloud_maker/ec2.rb', line 198 def find_region(availability_zone) region_name = availability_zone.gsub(/(\d)\w$/, '\1') if ec2.regions[region_name].exists? ec2.regions[region_name] else raise RuntimeError.new("The region #{region_name} doesn't exist - region name generated from availability_zone: #{availability_zone}.") end end |
#info(instance_id) ⇒ Object
Public: Fetch archived information about an instance
Returns a hash of information about the instance as it was launched
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/cloud_maker/ec2.rb', line 77 def info(instance_id) instance = find_instance(instance_id) bucket = instance.[BUCKET_TAG] archiver = S3Archiver.new( :instance_id => instance_id, :aws_access_key_id => self.aws_access_key_id, :aws_secret_access_key => self.aws_secret_access_key, :bucket_name => bucket ) archiver.load_archive end |
#launch(cloud_maker_config) ⇒ Object
Public: Launches a new EC2 instance, associates any specified elastic IPS with it, adds any specified tags, and archives the launch details to S3.
Returns an AWS::EC2 object for the launched instance.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/cloud_maker/ec2.rb', line 102 def launch(cloud_maker_config) user_data = cloud_maker_config.to_user_data if !cloud_maker_config['availability_zone'].nil? && !cloud_maker_config['availability_zone'].empty? region = find_region(cloud_maker_config['availability_zone']) else region = ec2 # .instances.create will just put things in the default region end instance = region.instances.create( :image_id => cloud_maker_config['ami'], :iam_instance_profile => cloud_maker_config['iam_role'], :security_groups => cloud_maker_config['security_group'], :instance_type => cloud_maker_config['instance_type'], :key_name => cloud_maker_config['key_pair'], :availability_zone => cloud_maker_config['availability_zone'], :user_data => user_data ) begin instance..set(cloud_maker_config['tags']) if cloud_maker_config['tags'] rescue AWS::EC2::Errors::InvalidInstanceID::NotFound => e retries ||= 0 if retries < 5 sleep(2**retries) retries += 1 retry end end if cloud_maker_config.elastic_ip? || cloud_maker_config.cname? while instance.status == :pending #wait end instance.associate_elastic_ip(cloud_maker_config["elastic_ip"]) if cloud_maker_config.elastic_ip? if cloud_maker_config.cname? r53 = AWS::Route53::Client.new(:access_key_id => self.aws_access_key_id, :secret_access_key => self.aws_secret_access_key) zone = r53.list_hosted_zones[:hosted_zones].select {|zone| cloud_maker_config['cname'] + '.' =~ /#{Regexp.escape(zone[:name])}$/ }.first r53.change_resource_record_sets( :hosted_zone_id => zone[:id], :change_batch => { :comment => "CloudMaker initialization of #{instance.instance_id}.", :changes => [{ :action => "CREATE", :resource_record_set => { :name => cloud_maker_config['cname'], :type => 'CNAME', :ttl => 60, :resource_records => [{:value => instance.dns_name}] } }] } ) end end archiver = S3Archiver.new( :instance_id => instance.id, :aws_access_key_id => self.aws_access_key_id, :aws_secret_access_key => self.aws_secret_access_key, :bucket_name => cloud_maker_config["tags"][BUCKET_TAG] ) archiver.store_archive(cloud_maker_config, self.class.instance_to_hash(instance)) instance end |
#terminate(instance_id) ⇒ Object
Public: Terminates the specified EC2 instance.
Returns nothing.
94 95 96 |
# File 'lib/cloud_maker/ec2.rb', line 94 def terminate(instance_id) find_instance(instance_id).terminate end |