Module: MovableInk::AWS::EC2

Included in:
MovableInk::AWS
Defined in:
lib/movable_ink/aws/ec2.rb

Instance Method Summary collapse

Instance Method Details

#all_instances(region: my_region, no_filter: false) ⇒ Object



56
57
58
59
# File 'lib/movable_ink/aws/ec2.rb', line 56

def all_instances(region: my_region, no_filter: false)
  @all_instances ||= {}
  @all_instances[region] ||= load_all_instances(region, no_filter: no_filter)
end

#assign_ip_address(role:) ⇒ Object



157
158
159
160
161
162
163
164
# File 'lib/movable_ink/aws/ec2.rb', line 157

def assign_ip_address(role:)
  run_with_backoff do
    ec2.associate_address({
      instance_id: instance_id,
      allocation_id: available_elastic_ips(role: role).sample.allocation_id
    })
  end
end

#available_elastic_ips(role:) ⇒ Object



153
154
155
# File 'lib/movable_ink/aws/ec2.rb', line 153

def available_elastic_ips(role:)
  unassigned_elastic_ips.select { |address| address.tags.detect { |t| t.key == 'mi:roles' && t.value == role } }
end

#ec2(region: my_region) ⇒ Object



4
5
6
7
# File 'lib/movable_ink/aws/ec2.rb', line 4

def ec2(region: my_region)
  @ec2_client ||= {}
  @ec2_client[region] ||= Aws::EC2::Client.new(region: region)
end

#elastic_ipsObject



143
144
145
146
147
# File 'lib/movable_ink/aws/ec2.rb', line 143

def elastic_ips
  @all_elastic_ips ||= run_with_backoff do
    ec2.describe_addresses.flat_map(&:addresses)
  end
end

#instance_idObject



81
82
83
84
85
86
87
# File 'lib/movable_ink/aws/ec2.rb', line 81

def instance_id
  @instance_id ||= begin
    az = `ec2metadata --instance-id 2>/dev/null`.chomp
    raise(MovableInk::AWS::Errors::EC2Required) if az.empty?
    az
  end
end

#instance_ip_addresses_by_role(role:, availability_zone: nil) ⇒ Object



124
125
126
# File 'lib/movable_ink/aws/ec2.rb', line 124

def instance_ip_addresses_by_role(role:, availability_zone: nil)
  private_ip_addresses(instances(role: role, availability_zone: availability_zone))
end

#instance_ip_addresses_by_role_ordered(role:) ⇒ Object



128
129
130
131
132
133
# File 'lib/movable_ink/aws/ec2.rb', line 128

def instance_ip_addresses_by_role_ordered(role:)
  instances = instances(role: role)
  instances_in_my_az = instances.select { |instance| instance.placement.availability_zone == availability_zone }
  ordered_instances = instances_in_my_az.shuffle + (instances - instances_in_my_az).shuffle
  private_ip_addresses(ordered_instances)
end

#instances(role:, region: my_region, availability_zone: nil) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/movable_ink/aws/ec2.rb', line 93

def instances(role:, region: my_region, availability_zone: nil)
  role_pattern = mi_env == 'production' ? "^#{role}$" : "^*#{role}*$"
  role_pattern = role_pattern.gsub('**','*').gsub('*','.*')
  instances = all_instances(region: region).select { |instance|
    instance.tags.detect { |tag|
      tag.key == 'mi:roles'&&
        Regexp.new(role_pattern).match(tag.value) &&
        !tag.value.include?('decommissioned')
    }
  }
  if availability_zone
    instances.select { |instance|
      instance.placement.availability_zone == availability_zone
    }
  else
    instances
  end
end

#load_all_instances(region, no_filter: false) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/movable_ink/aws/ec2.rb', line 61

def load_all_instances(region, no_filter: false)
  filters = if no_filter
    nil
  else
    [{
      name: 'instance-state-name',
      values: ['running']
    },
    {
      name: 'tag:mi:env',
      values: [mi_env]
    }]
  end
  run_with_backoff do
    ec2(region: region).describe_instances(filters: filters).flat_map do |resp|
      resp.reservations.flat_map(&:instances)
    end
  end
end

#load_mi_envObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/movable_ink/aws/ec2.rb', line 13

def load_mi_env
  run_with_backoff(quiet: true) do
    begin
      ec2.describe_tags(filters: [
            {
              name: 'resource-id',
              values: [instance_id]
            }
          ])
        .tags
        .detect { |tag| tag.key == 'mi:env' }
        .value
    rescue NoMethodError
      raise MovableInk::AWS::Errors::NoEnvironmentTagError
    end
  end
end

#load_thopter_instanceObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/movable_ink/aws/ec2.rb', line 35

def load_thopter_instance
  run_with_backoff do
    ec2(region: 'us-east-1').describe_instances(filters: [
      {
        name: 'tag:mi:roles',
        values: ['*thopter*']
      },
      {
        name: 'tag:mi:env',
        values: [mi_env]
      },
      {
        name: 'instance-state-name',
        values: ['running']
      }
    ])
    .reservations
    .flat_map(&:instances)
  end
end

#meObject



89
90
91
# File 'lib/movable_ink/aws/ec2.rb', line 89

def me
  @me ||= all_instances.select{|instance| instance.instance_id == instance_id}
end

#mi_envObject



9
10
11
# File 'lib/movable_ink/aws/ec2.rb', line 9

def mi_env
  @mi_env ||= load_mi_env
end

#private_ip_addresses(instances) ⇒ Object



120
121
122
# File 'lib/movable_ink/aws/ec2.rb', line 120

def private_ip_addresses(instances)
  instances.map(&:private_ip_address)
end

#redis_by_role(role, port) ⇒ Object



135
136
137
138
139
140
141
# File 'lib/movable_ink/aws/ec2.rb', line 135

def redis_by_role(role, port)
  instance_ip_addresses_by_role(role: role)
    .shuffle
    .inject([]) { |redii, instance|
      redii.push({"host" => instance, "port" => port})
    }
end

#statsd_hostObject



116
117
118
# File 'lib/movable_ink/aws/ec2.rb', line 116

def statsd_host
  instance_ip_addresses_by_role(role: 'statsd', availability_zone: availability_zone).sample
end

#thopterObject



112
113
114
# File 'lib/movable_ink/aws/ec2.rb', line 112

def thopter
  private_ip_addresses(thopter_instance).first
end

#thopter_instanceObject



31
32
33
# File 'lib/movable_ink/aws/ec2.rb', line 31

def thopter_instance
  @thopter_instance ||= load_thopter_instance
end

#unassigned_elastic_ipsObject



149
150
151
# File 'lib/movable_ink/aws/ec2.rb', line 149

def unassigned_elastic_ips
  @unassigned_elastic_ips ||= elastic_ips.select { |address| address.association_id.nil? }
end