Class: Capistrano::ASG::Rolling::Instance

Inherits:
Object
  • Object
show all
Includes:
AWS
Defined in:
lib/capistrano/asg/rolling/instance.rb

Overview

AWS EC2 instance.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AWS

#aws_autoscaling_client, #aws_ec2_client

Constructor Details

#initialize(id, private_ip_address, public_ip_address, image_id, autoscale_group) ⇒ Instance

Returns a new instance of Instance.



17
18
19
20
21
22
23
24
25
# File 'lib/capistrano/asg/rolling/instance.rb', line 17

def initialize(id, private_ip_address, public_ip_address, image_id, autoscale_group)
  @id = id
  @private_ip_address = private_ip_address
  @public_ip_address = public_ip_address
  @image_id = image_id
  @autoscale_group = autoscale_group
  @auto_terminate = true
  @terminated = false
end

Instance Attribute Details

#auto_terminateObject Also known as: auto_terminate?

Returns the value of attribute auto_terminate.



13
14
15
# File 'lib/capistrano/asg/rolling/instance.rb', line 13

def auto_terminate
  @auto_terminate
end

#autoscale_groupObject (readonly)

Returns the value of attribute autoscale_group.



12
13
14
# File 'lib/capistrano/asg/rolling/instance.rb', line 12

def autoscale_group
  @autoscale_group
end

#idObject (readonly)

Returns the value of attribute id.



12
13
14
# File 'lib/capistrano/asg/rolling/instance.rb', line 12

def id
  @id
end

#image_idObject (readonly)

Returns the value of attribute image_id.



12
13
14
# File 'lib/capistrano/asg/rolling/instance.rb', line 12

def image_id
  @image_id
end

#private_ip_addressObject (readonly)

Returns the value of attribute private_ip_address.



12
13
14
# File 'lib/capistrano/asg/rolling/instance.rb', line 12

def private_ip_address
  @private_ip_address
end

#public_ip_addressObject (readonly)

Returns the value of attribute public_ip_address.



12
13
14
# File 'lib/capistrano/asg/rolling/instance.rb', line 12

def public_ip_address
  @public_ip_address
end

#terminatedObject Also known as: terminated?

Returns the value of attribute terminated.



13
14
15
# File 'lib/capistrano/asg/rolling/instance.rb', line 13

def terminated
  @terminated
end

Class Method Details

.run(autoscaling_group:, overrides: nil) ⇒ Object

Launch a new instance based on settings from Auto Scaling Group and associated Launch Template.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/capistrano/asg/rolling/instance.rb', line 28

def self.run(autoscaling_group:, overrides: nil)
  launch_template = autoscaling_group.launch_template

  aws_ec2_client = autoscaling_group.aws_ec2_client
  options = {
    min_count: 1,
    max_count: 1,
    launch_template: {
      launch_template_id: launch_template.id,
      version: launch_template.version
    }
  }

  # Add a subnet defined in the Auto Scaling Group, but only when the Launch Template
  # does not define a network interface. Otherwise it will trigger the following error:
  # => Network interfaces and an instance-level subnet ID may not be specified on the same request
  options[:subnet_id] = autoscaling_group.subnet_ids.sample if launch_template.network_interfaces.empty?

  # Optionally override settings in the Launch Template.
  options.merge!(overrides) if overrides

  resource_tags = [
    { key: 'Name', value: autoscaling_group.name_tag }
  ]
  options[:tag_specifications] = [
    { resource_type: 'instance', tags: resource_tags },
    { resource_type: 'volume', tags: resource_tags }
  ]

  response = aws_ec2_client.run_instances(options)

  instance = response.instances.first

  # Wait until the instance is running and has a public IP address.
  aws_instance = ::Aws::EC2::Instance.new(instance.instance_id, client: aws_ec2_client)
  instance = aws_instance.wait_until_running

  new(instance.instance_id, instance.private_ip_address, instance.public_ip_address, instance.image_id, autoscaling_group)
end

Instance Method Details

#create_ami(name: nil, description: nil, tags: nil) ⇒ Object



103
104
105
106
107
108
# File 'lib/capistrano/asg/rolling/instance.rb', line 103

def create_ami(name: nil, description: nil, tags: nil)
  ami_tags = { 'Name' => autoscale_group.name_tag }
  ami_tags.merge!(tags) if tags

  AMI.create(instance: self, name: name || ami_name, description: description, tags: ami_tags)
end

#ip_addressObject



80
81
82
# File 'lib/capistrano/asg/rolling/instance.rb', line 80

def ip_address
  Configuration.use_private_ip_address? ? private_ip_address : public_ip_address
end

#startObject



84
85
86
87
# File 'lib/capistrano/asg/rolling/instance.rb', line 84

def start
  aws_ec2_client.start_instances(instance_ids: [id])
  aws_ec2_client.wait_until(:instance_running, instance_ids: [id])
end

#stopObject



89
90
91
92
# File 'lib/capistrano/asg/rolling/instance.rb', line 89

def stop
  aws_ec2_client.stop_instances(instance_ids: [id])
  aws_ec2_client.wait_until(:instance_stopped, instance_ids: [id])
end

#terminate(wait: false) ⇒ Object



94
95
96
97
98
99
100
101
# File 'lib/capistrano/asg/rolling/instance.rb', line 94

def terminate(wait: false)
  aws_ec2_client.terminate_instances(instance_ids: [id])
  aws_ec2_client.wait_until(:instance_terminated, instance_ids: [id]) if wait

  @terminated = true
rescue Aws::EC2::Errors::ServiceError => e
  raise Capistrano::ASG::Rolling::InstanceTerminateFailed.new(self, e)
end

#wait_for_sshObject



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/capistrano/asg/rolling/instance.rb', line 68

def wait_for_ssh
  started_at = Time.now

  loop do
    result = SSH.test?(ip_address, autoscale_group.properties[:user], Configuration.ssh_options)

    break if result || Time.now - started_at > 300

    sleep 1
  end
end