tass 0.2.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/tass +53 -26
- data/lib/tapjoy/autoscaling_bootstrap.rb +45 -65
- data/lib/tapjoy/autoscaling_bootstrap/AWS/Autoscaling/group.rb +19 -15
- data/lib/tapjoy/autoscaling_bootstrap/AWS/ec2.rb +19 -1
- data/lib/tapjoy/autoscaling_bootstrap/audit.rb +1 -1
- data/lib/tapjoy/autoscaling_bootstrap/autoscaling/group.rb +63 -0
- data/lib/tapjoy/autoscaling_bootstrap/autoscaling/policy.rb +1 -1
- data/lib/tapjoy/autoscaling_bootstrap/autoscaling_group.rb +1 -19
- data/lib/tapjoy/autoscaling_bootstrap/ec2.rb +26 -0
- data/lib/tapjoy/autoscaling_bootstrap/elb.rb +23 -7
- data/lib/tapjoy/autoscaling_bootstrap/errors.rb +9 -0
- data/lib/tapjoy/autoscaling_bootstrap/version.rb +3 -3
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d63df49ef7d75eeec0d74aef90721a098a829efa
|
4
|
+
data.tar.gz: 23bf79d63f1bb9157c51896c85e05ed28ed20f47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 921b36ca3ccf7eab2817009c1493357b87f11377b13b92099f7a5af0439c9d29e3aa4fe55f5f189928edee0fcd46eff8253b947af901e4b2bb58a28b5908a96b
|
7
|
+
data.tar.gz: 6a1edbb35badfd93bb59c988982581b9bd0cb9be651ebabef6dda8fcb88620b7a14b341e3d66758c240777f0328e5185f6988334c70b6ff9758035e7be14b4ff
|
data/bin/tass
CHANGED
@@ -2,20 +2,31 @@
|
|
2
2
|
|
3
3
|
require 'tapjoy/autoscaling_bootstrap'
|
4
4
|
|
5
|
+
def common_args
|
6
|
+
opt :filename, 'Specify config file to load', type: :string, required: true
|
7
|
+
opt :prompt, 'Enable/disable prompts', default: true
|
8
|
+
opt :env, 'Specify which environment config to load', type: :string
|
9
|
+
end
|
10
|
+
|
5
11
|
def confirm_config(aws_env, misc_config, opts)
|
6
12
|
use_vpc = true if misc_config[:vpc_subnets]
|
7
|
-
|
8
|
-
|
13
|
+
has_elb = true if misc_config.key?(:elb)
|
14
|
+
Tapjoy::AutoscalingBootstrap::Base.new.confirm_config(**aws_env,
|
15
|
+
**misc_config, **opts, use_vpc: use_vpc, has_elb: has_elb,
|
16
|
+
config: misc_config)
|
17
|
+
end
|
9
18
|
|
10
|
-
|
11
|
-
|
19
|
+
def configure_environment(opts)
|
20
|
+
config, aws_env, user_data = Tapjoy::AutoscalingBootstrap::Base.new.configure_environment(opts)
|
21
|
+
Aws.config[:region] = config[:aws_region]
|
22
|
+
[config, aws_env, user_data]
|
12
23
|
end
|
13
24
|
|
14
|
-
SUB_COMMANDS = %w(create update audit)
|
25
|
+
SUB_COMMANDS = %w(create update audit scale)
|
15
26
|
Trollop::options do
|
16
27
|
usage '[SUB_COMMAND] [options]'
|
17
28
|
synopsis "\nConfigures autoscaling groups.\nAvailable subcommands are: #{SUB_COMMANDS}"
|
18
|
-
version "#{File.basename($
|
29
|
+
version "#{File.basename($PROGRAM_NAME)} #{Tapjoy::AutoscalingBootstrap::VERSION} \u00A9 2015 Tapjoy, Inc."
|
19
30
|
stop_on SUB_COMMANDS
|
20
31
|
end
|
21
32
|
|
@@ -27,33 +38,43 @@ when 'create'
|
|
27
38
|
usage 'create [options]'
|
28
39
|
synopsis 'This command creates new autoscaling groups, and overwrites existing ones.'
|
29
40
|
|
30
|
-
opt :filename, 'Specify config file to load', type: :string, required: true
|
31
|
-
opt :config_dir, 'Specify the directory for configuration files', type: :string, short: :none, default: Tapjoy::AutoscalingBootstrap.config_dir
|
32
|
-
opt :env, 'Specify which environment config to load', type: :string
|
33
41
|
opt :clobber_elb, 'Force ELB creation', default: false, short: :none
|
34
42
|
opt :clobber_as, 'Force AS group creation', default: false, short: :none
|
35
|
-
|
43
|
+
common_args
|
36
44
|
end
|
37
45
|
|
38
|
-
config, aws_env, user_data =
|
39
|
-
Aws.config[:region] = config[:aws_region]
|
40
|
-
confirm_config(aws_env, config, opts)
|
46
|
+
config, aws_env, user_data = configure_environment(opts)
|
41
47
|
|
42
48
|
Tapjoy::AutoscalingBootstrap::Base.new.check_clobber(opts, config)
|
49
|
+
unless confirm_config(aws_env, config, opts)
|
50
|
+
abort('Cannot continue if configuration is not correct. Please fix.')
|
51
|
+
end
|
43
52
|
Tapjoy::AutoscalingBootstrap::AutoscalingGroup.new.create(opts, config, aws_env, user_data)
|
53
|
+
|
54
|
+
if config.key?(:elb)
|
55
|
+
config[:elb].each do |elb|
|
56
|
+
elb.each do |elb_name, elb_config|
|
57
|
+
Tapjoy::AutoscalingBootstrap.elb_name = elb_name
|
58
|
+
elb_hash = {
|
59
|
+
elb_name => config[:default_elb_parameters].merge!(elb[elb_name])
|
60
|
+
}
|
61
|
+
|
62
|
+
Tapjoy::AutoscalingBootstrap::ELB.new(
|
63
|
+
elb_hash, config[:clobber_elb], config[:zones],
|
64
|
+
config[:security_groups])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
44
69
|
when 'update'
|
45
70
|
opts = Trollop.options do
|
46
71
|
# Set help message
|
47
72
|
usage 'update [options]'
|
48
73
|
synopsis 'This command creates new launch configurations based on existing autoscaling groups using local instance configuration files as overrides.'
|
49
|
-
|
50
|
-
opt :config_dir, 'Specify the directory for configuration files', type: :string, short: :none, default: Tapjoy::AutoscalingBootstrap.config_dir
|
51
|
-
opt :env, 'Specify which environment config to load', type: :string
|
52
|
-
opt :prompt, 'Enable/disable prompts', default: true
|
74
|
+
common_args
|
53
75
|
end
|
54
76
|
|
55
|
-
config, aws_env, user_data =
|
56
|
-
Aws.config[:region] = config[:aws_region]
|
77
|
+
config, aws_env, user_data = configure_environment(opts)
|
57
78
|
confirm_config(aws_env, config, opts)
|
58
79
|
|
59
80
|
Tapjoy::AutoscalingBootstrap::LaunchConfiguration.new(config, aws_env, user_data)
|
@@ -61,17 +82,23 @@ when 'audit'
|
|
61
82
|
opts = Trollop.options do
|
62
83
|
usage 'audit'
|
63
84
|
synopsis 'This command compares local configuration files for a given cluster to the existing launch configuration and autoscaling group running in AWS.'
|
64
|
-
|
65
|
-
opt :config_dir, 'Specify the directory for configuration files', type: :string, short: :none, default: Tapjoy::AutoscalingBootstrap.config_dir
|
66
|
-
opt :env, 'Specify which environment config to load', required: true, type: :string
|
67
|
-
opt :prompt, 'Enable/disable prompts', default: true
|
85
|
+
common_args
|
68
86
|
end
|
69
87
|
|
70
|
-
config, aws_env, user_data =
|
71
|
-
Aws.config[:region] = config[:aws_region]
|
88
|
+
config, aws_env, user_data = configure_environment(opts)
|
72
89
|
|
73
|
-
config.merge!(aws_env.merge(
|
90
|
+
config.merge!(aws_env.merge(user_data: Base64.encode64("#{user_data}")))
|
74
91
|
Tapjoy::AutoscalingBootstrap::Audit.new(config)
|
92
|
+
when 'scale'
|
93
|
+
opts = Trollop.options do
|
94
|
+
usage 'scale [options]'
|
95
|
+
synopsis 'This command is used to scale up/down auto scaling groups'
|
96
|
+
common_args
|
97
|
+
opt :instance_ids, 'Instance IDs to scale down', type: :strings
|
98
|
+
end
|
99
|
+
|
100
|
+
config, aws_env, user_data = configure_environment(opts)
|
101
|
+
Tapjoy::AutoscalingBootstrap::Autoscaling::Group.new.scale(config)
|
75
102
|
else
|
76
103
|
Trollop.educate
|
77
104
|
end
|
@@ -30,6 +30,7 @@ require_relative 'autoscaling_bootstrap/autoscaling_group'
|
|
30
30
|
require_relative 'autoscaling_bootstrap/launch_configuration'
|
31
31
|
require_relative 'autoscaling_bootstrap/version'
|
32
32
|
require_relative 'autoscaling_bootstrap/audit'
|
33
|
+
require_relative 'autoscaling_bootstrap/ec2'
|
33
34
|
|
34
35
|
module Tapjoy
|
35
36
|
# Module for Autoscaling Bootstrap
|
@@ -45,24 +46,6 @@ module Tapjoy
|
|
45
46
|
@elb_name = str
|
46
47
|
end
|
47
48
|
|
48
|
-
# If you're using AutoscalingBootstrap to join to a list of existing ELBs, that array
|
49
|
-
# goes here. This list can include or not include the provided elb_name, the
|
50
|
-
# array + a custom elb_name will be uniq-ed before being passed to Amazon
|
51
|
-
def elb_list=(list)
|
52
|
-
@elb_list = list
|
53
|
-
end
|
54
|
-
|
55
|
-
def elb_list
|
56
|
-
@elb_list ||= []
|
57
|
-
end
|
58
|
-
|
59
|
-
# This is the list of elbs passed to the autoscaling configuration. It will include
|
60
|
-
# the created elb, as well as the specific list of elbs to join. It will call uniq
|
61
|
-
# on the list in case you accidentally specify the same elb twice
|
62
|
-
def elbs_to_join
|
63
|
-
(elb_list + [Tapjoy::AutoscalingBootstrap.elb_name]).uniq
|
64
|
-
end
|
65
|
-
|
66
49
|
def policy
|
67
50
|
@policy = Tapjoy::AutoscalingBootstrap::Autoscaling::Policy.new
|
68
51
|
end
|
@@ -83,9 +66,8 @@ module Tapjoy
|
|
83
66
|
@config_dir ||= ENV['TASS_CONFIG_DIR'] || "#{ENV['HOME']}/.tass"
|
84
67
|
end
|
85
68
|
|
86
|
-
def
|
87
|
-
env_list =
|
88
|
-
puts config_dir
|
69
|
+
def valid_env?(config_dir, env)
|
70
|
+
env_list = supported_envs(config_dir)
|
89
71
|
unless env_list.include?(env)
|
90
72
|
Trollop.die :env, "Currently supported enviroments are #{env_list.join(',')}"
|
91
73
|
end
|
@@ -93,7 +75,7 @@ module Tapjoy
|
|
93
75
|
|
94
76
|
def supported_envs(listing)
|
95
77
|
envs = []
|
96
|
-
Dir.entries(
|
78
|
+
Dir.entries(listing).each do |file|
|
97
79
|
next unless file.end_with?('yaml')
|
98
80
|
next if file.start_with?('defaults')
|
99
81
|
envs << file.chomp!('.yaml')
|
@@ -111,17 +93,16 @@ module Tapjoy
|
|
111
93
|
end
|
112
94
|
|
113
95
|
# Using variables passed in, generate user data file
|
114
|
-
def generate_user_data(config)
|
96
|
+
def generate_user_data(userdata_dir, bootstrap_script, config)
|
115
97
|
|
116
98
|
ERB.new(
|
117
|
-
File.new(
|
99
|
+
File.new(File.join(userdata_dir, bootstrap_script)).read, nil, '-'
|
118
100
|
).result(binding)
|
119
101
|
end
|
120
102
|
|
121
103
|
# Check if we allow clobbering and need to clobber
|
122
104
|
def check_clobber(opts, config)
|
123
105
|
fail Tapjoy::AutoscalingBootstrap::Errors::ClobberRequired if check_as_clobber(**opts, **config)
|
124
|
-
fail Tapjoy::AutoscalingBootstrap::Errors::ELB::ClobberRequired if check_elb_clobber(**opts, **config)
|
125
106
|
puts "We don't need to clobber"
|
126
107
|
end
|
127
108
|
|
@@ -130,41 +111,40 @@ module Tapjoy
|
|
130
111
|
create_as_group && Tapjoy::AutoscalingBootstrap.group.exists && !clobber_as
|
131
112
|
end
|
132
113
|
|
133
|
-
# Check ELB clobber
|
134
|
-
def check_elb_clobber(create_elb:, clobber_elb:, **unused_values)
|
135
|
-
elb = Tapjoy::AutoscalingBootstrap::ELB.new
|
136
|
-
create_elb && elb.exists && !clobber_elb
|
137
|
-
end
|
138
|
-
|
139
114
|
# Get AWS Environment
|
140
115
|
def get_security_groups(config_dir, env, group)
|
141
116
|
|
142
117
|
# Check environment file
|
143
|
-
unless File.readable?("#{config_dir}
|
118
|
+
unless File.readable?("#{config_dir}/#{env}.yaml")
|
144
119
|
fail Tapjoy::AutoscalingBootstrap::Errors::InvalidEnvironment
|
145
120
|
end
|
146
121
|
|
147
122
|
security_groups = {security_groups: group.split(',')}
|
148
123
|
end
|
149
124
|
|
125
|
+
# Clean list of ELBs
|
126
|
+
def elb_list(config)
|
127
|
+
config[:elb].map(&:keys).flatten.join(',')
|
128
|
+
end
|
129
|
+
|
150
130
|
# Confirm config settings before running autoscaling code
|
151
131
|
def confirm_config(keypair:, zones:, security_groups:, instance_type:,
|
152
132
|
image_id:, iam_instance_profile:, prompt:, use_vpc: use_vpc,
|
153
|
-
vpc_subnets: nil,
|
154
|
-
|
155
|
-
elb_name = Tapjoy::AutoscalingBootstrap.elb_name
|
133
|
+
vpc_subnets: nil, has_elb: has_elb, config:, termination_policies:,
|
134
|
+
**unused_values)
|
156
135
|
|
157
136
|
puts ' Preparing to configure the following autoscaling group:'
|
158
|
-
puts " Launch Config:
|
159
|
-
puts " Auto Scaler:
|
160
|
-
puts " ELB:
|
161
|
-
puts " Key Pair:
|
162
|
-
puts " Zones:
|
163
|
-
puts " Groups:
|
164
|
-
puts " Instance Type:
|
165
|
-
puts " Image ID:
|
166
|
-
puts " IAM Role:
|
167
|
-
puts " VPC Subnets:
|
137
|
+
puts " Launch Config: #{Tapjoy::AutoscalingBootstrap.config_name}"
|
138
|
+
puts " Auto Scaler: #{Tapjoy::AutoscalingBootstrap.scaler_name}"
|
139
|
+
puts " ELB: #{elb_list(config)}" if has_elb
|
140
|
+
puts " Key Pair: #{keypair}"
|
141
|
+
puts " Zones: #{zones.join(',')}"
|
142
|
+
puts " Groups: #{security_groups.sort.join(',')}"
|
143
|
+
puts " Instance Type: #{instance_type}"
|
144
|
+
puts " Image ID: #{image_id}"
|
145
|
+
puts " IAM Role: #{iam_instance_profile}"
|
146
|
+
puts " VPC Subnets: #{vpc_subnets}" if use_vpc
|
147
|
+
puts " Termination Policies: #{termination_policies.sort.join(',')}"
|
168
148
|
|
169
149
|
puts "\n\nNOTE! Continuing may have adverse effects if you end up " \
|
170
150
|
"deleting an IN-USE PRODUCTION scaling group. Don't be dumb."
|
@@ -174,41 +154,41 @@ module Tapjoy
|
|
174
154
|
|
175
155
|
# configure environment
|
176
156
|
|
177
|
-
def configure_environment(
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
facet_file = File.join(config_dir, 'config', 'clusters', filename)
|
183
|
-
end
|
157
|
+
def configure_environment(opts)
|
158
|
+
filename = opts[:filename]
|
159
|
+
facet_file = filename
|
160
|
+
config_dir = File.expand_path('../..', facet_file)
|
161
|
+
userdata_dir = "#{File.expand_path('../../..', facet_file)}/userdata"
|
184
162
|
|
185
|
-
common_path = File.join(config_dir, '
|
163
|
+
common_path = File.join(config_dir, 'common')
|
186
164
|
defaults_hash = self.load_yaml(File.join(common_path, 'defaults.yaml'))
|
187
165
|
facet_hash = self.load_yaml(facet_file)
|
188
|
-
env
|
189
|
-
env
|
190
|
-
Tapjoy::AutoscalingBootstrap.is_valid_env?(config_dir, env)
|
166
|
+
env = opts[:env] || facet_hash[:environment] || defaults_hash[:environment]
|
167
|
+
Tapjoy::AutoscalingBootstrap.valid_env?(common_path, env)
|
191
168
|
env_hash = self.load_yaml(File.join(common_path, "#{env}.yaml"))
|
192
169
|
|
193
170
|
new_config = defaults_hash.merge!(env_hash).merge(facet_hash)
|
194
171
|
new_config[:config_dir] = config_dir
|
195
|
-
|
172
|
+
new_config[:instance_ids] = opts[:instance_ids] if opts.key?(:instance_ids)
|
173
|
+
aws_env = self.get_security_groups(common_path, env, new_config[:group])
|
174
|
+
new_config.merge!(aws_env)
|
196
175
|
|
176
|
+
new_config[:autoscale] = false unless new_config[:scaling_type].eql?('dynamic')
|
177
|
+
new_config[:tags] << {Name: new_config[:name]}
|
197
178
|
Tapjoy::AutoscalingBootstrap.scaler_name = "#{new_config[:name]}-group"
|
198
179
|
Tapjoy::AutoscalingBootstrap.config_name = "#{new_config[:name]}-config"
|
199
180
|
# If there's no ELB, then Not a ELB
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
user_data = self.generate_user_data(new_config)
|
205
|
-
return new_config, aws_env, user_data
|
181
|
+
user_data = self.generate_user_data(userdata_dir,
|
182
|
+
new_config[:bootstrap_script], new_config)
|
183
|
+
|
184
|
+
[new_config, aws_env, user_data]
|
206
185
|
end
|
207
186
|
|
208
187
|
# Exponential backup
|
209
188
|
def aws_wait(tries)
|
210
|
-
|
211
|
-
|
189
|
+
backoff_sleep = 2 ** tries
|
190
|
+
puts "Sleeping for #{backoff_sleep}..."
|
191
|
+
sleep backoff_sleep
|
212
192
|
end
|
213
193
|
|
214
194
|
# Check if security group exists and create it if it does not
|
@@ -9,11 +9,10 @@ module Tapjoy
|
|
9
9
|
@client ||= Tapjoy::AutoscalingBootstrap::AWS::Autoscaling.client
|
10
10
|
end
|
11
11
|
|
12
|
-
def resize(
|
12
|
+
def resize(min: 0, max: 0, desired:0)
|
13
13
|
self.client.update_auto_scaling_group(
|
14
14
|
auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
|
15
|
-
min_size:
|
16
|
-
desired_capacity: desired_capacity)
|
15
|
+
min_size: min, max_size: max, desired_capacity: desired)
|
17
16
|
end
|
18
17
|
|
19
18
|
def delete(force_delete: true)
|
@@ -30,31 +29,36 @@ module Tapjoy
|
|
30
29
|
)[0][0]
|
31
30
|
end
|
32
31
|
|
32
|
+
def detach
|
33
|
+
self.client.detach_instances(
|
34
|
+
instance_ids: describe.instances.map(&:instance_id),
|
35
|
+
auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
|
36
|
+
should_decrement_desired_capacity: true,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
33
40
|
def create(zones:, health_check_type: nil, tags:,
|
34
|
-
vpc_subnets: nil,
|
41
|
+
vpc_subnets: nil, termination_policies: , **unused_values)
|
35
42
|
|
36
43
|
group_hash = {
|
37
44
|
auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
|
38
45
|
availability_zones: zones,
|
39
46
|
launch_configuration_name: Tapjoy::AutoscalingBootstrap.config_name,
|
40
47
|
min_size: 0, max_size: 0, desired_capacity: 0,
|
41
|
-
termination_policies:
|
48
|
+
termination_policies: termination_policies,
|
42
49
|
vpc_zone_identifier: vpc_subnets,
|
43
50
|
tags: Tapjoy::AutoscalingBootstrap::Autoscaling::Group.new.generate_tags(tags)
|
44
51
|
}
|
45
52
|
|
46
|
-
# If we've chosen to explicitly create an ELB and assign to this ASG
|
47
|
-
# OR if we've given it a list of ELBs to join (or both)
|
48
|
-
if create_elb || !Tapjoy::AutoscalingBootstrap.elb_list.empty?
|
49
|
-
group_hash.merge!({
|
50
|
-
load_balancer_names: Tapjoy::AutoscalingBootstrap.elbs_to_join,
|
51
|
-
health_check_type: health_check_type,
|
52
|
-
health_check_grace_period: 300,
|
53
|
-
})
|
54
|
-
end
|
55
|
-
|
56
53
|
self.client.create_auto_scaling_group(**group_hash)
|
57
54
|
end
|
55
|
+
|
56
|
+
def attach_elb(elb_list)
|
57
|
+
self.client.attach_load_balancers({
|
58
|
+
auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
|
59
|
+
load_balancer_names: elb_list.split(','),
|
60
|
+
})
|
61
|
+
end
|
58
62
|
end
|
59
63
|
end
|
60
64
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Tapjoy
|
2
2
|
module AutoscalingBootstrap
|
3
3
|
module AWS
|
4
|
-
# This class contains AWS methods for
|
4
|
+
# This class contains AWS methods for EC2
|
5
5
|
module EC2
|
6
6
|
class << self
|
7
7
|
def client
|
@@ -16,6 +16,24 @@ module Tapjoy
|
|
16
16
|
self.client.create_security_group(group_name: group,
|
17
17
|
description: "Security group for #{Tapjoy::AutoscalingBootstrap.scaler_name}")
|
18
18
|
end
|
19
|
+
|
20
|
+
def describe_instances_by_tag(config)
|
21
|
+
self.client.describe_instances(filters: [
|
22
|
+
{name: 'tag:Name', values: [config[:name]]},
|
23
|
+
{name: 'instance-state-name', values: %w(running)}
|
24
|
+
])
|
25
|
+
end
|
26
|
+
|
27
|
+
def toggle_termination_protection(instance_id, state)
|
28
|
+
client.modify_instance_attribute(
|
29
|
+
instance_id: instance_id,
|
30
|
+
attribute: 'disableApiTermination',
|
31
|
+
value: state)
|
32
|
+
end
|
33
|
+
|
34
|
+
def terminate_instances(instance_ids)
|
35
|
+
client.terminate_instances(instance_ids: instance_ids)
|
36
|
+
end
|
19
37
|
end
|
20
38
|
end
|
21
39
|
end
|
@@ -22,7 +22,7 @@ module Tapjoy
|
|
22
22
|
config[:key_name] = config.delete :keypair
|
23
23
|
config[:launch_configuration_name] = Tapjoy::AutoscalingBootstrap.config_name
|
24
24
|
keys = %w(bootstrap_script chef_server_url clobber clobber_elb
|
25
|
-
create_as_group
|
25
|
+
create_as_group)
|
26
26
|
delete_keys(config, keys)
|
27
27
|
|
28
28
|
config
|
@@ -61,8 +61,60 @@ module Tapjoy
|
|
61
61
|
tag_array
|
62
62
|
end
|
63
63
|
|
64
|
+
# Scale auto scaling groups
|
65
|
+
def scale(config)
|
66
|
+
if config[:scaling_type].eql?('dynamic')
|
67
|
+
Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.resize(
|
68
|
+
**config[:instance_counts])
|
69
|
+
elsif config[:scaling_type].eql?('static')
|
70
|
+
scale_static(config)
|
71
|
+
else
|
72
|
+
abort('Unknown scaling type')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
64
76
|
private
|
65
77
|
|
78
|
+
# Logic for scaling static clusters
|
79
|
+
def scale_static(config)
|
80
|
+
current_count = Tapjoy::AutoscalingBootstrap::EC2.count_static_instances(config)
|
81
|
+
count_delta = config[:instance_counts][:desired] - current_count
|
82
|
+
if count_delta < 0
|
83
|
+
count_delta = count_delta.abs
|
84
|
+
puts "Scaling #{count_delta} instances down"
|
85
|
+
abort('Instances to terminate must be specified') unless config.key?(:instance_ids)
|
86
|
+
unless config[:instance_ids].length.eql?(count_delta)
|
87
|
+
fail Tapjoy::AutoscalingBootstrap::Errors::IncorrectNumberIds
|
88
|
+
end
|
89
|
+
disable_termination_protection(config[:instance_ids])
|
90
|
+
Tapjoy::AutoscalingBootstrap::AWS::EC2.terminate_instances(config[:instance_ids])
|
91
|
+
elsif count_delta > 0
|
92
|
+
puts 'Scaling up...'
|
93
|
+
puts count_delta
|
94
|
+
Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.resize(
|
95
|
+
min: 0, max: count_delta, desired: count_delta)
|
96
|
+
wait_for_asg_to_populate(config[:instance_counts][:desired], config)
|
97
|
+
enable_termination_protection
|
98
|
+
Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.detach
|
99
|
+
else
|
100
|
+
puts 'No action needed'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Helper method to disable termination protection
|
105
|
+
def disable_termination_protection(instance_ids)
|
106
|
+
instance_ids.each do |instance|
|
107
|
+
Tapjoy::AutoscalingBootstrap::EC2.disable_termination_protection(instance)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
# Helper method to enable termination protection
|
111
|
+
def enable_termination_protection
|
112
|
+
asg = Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.describe
|
113
|
+
asg.instances.map(&:instance_id).each do |instance|
|
114
|
+
Tapjoy::AutoscalingBootstrap::EC2.enable_termination_protection(instance)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
66
118
|
# Clear out existing autoscaling group
|
67
119
|
def zero_autoscale_group
|
68
120
|
Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.resize
|
@@ -107,6 +159,17 @@ module Tapjoy
|
|
107
159
|
Tapjoy::AutoscalingBootstrap::Base.new.aws_wait(tries)
|
108
160
|
end
|
109
161
|
end
|
162
|
+
|
163
|
+
# Wait for ASG to populate
|
164
|
+
def wait_for_asg_to_populate(desired, config)
|
165
|
+
current_count = Tapjoy::AutoscalingBootstrap::EC2.count_static_instances(config)
|
166
|
+
tries = 0
|
167
|
+
until current_count.eql?(desired) do
|
168
|
+
tries += 1
|
169
|
+
Tapjoy::AutoscalingBootstrap::Base.new.aws_wait(tries)
|
170
|
+
current_count = Tapjoy::AutoscalingBootstrap::EC2.count_static_instances(config)
|
171
|
+
end
|
172
|
+
end
|
110
173
|
end
|
111
174
|
end
|
112
175
|
end
|
@@ -12,7 +12,7 @@ module Tapjoy
|
|
12
12
|
|
13
13
|
# Create autoscaling policy
|
14
14
|
def create(policy, scale)
|
15
|
-
|
15
|
+
fail Tapjoy::AutoscalingBootstrap::Errors::InvalidAutoscalingGroup unless Tapjoy::AutoscalingBootstrap.group.exists
|
16
16
|
Tapjoy::AutoscalingBootstrap::AWS::Autoscaling.put_scaling_policy(
|
17
17
|
policy_name: policy, **scale)
|
18
18
|
end
|
@@ -3,25 +3,7 @@ module Tapjoy
|
|
3
3
|
# This class is the central launching point for new autoscaling group creation
|
4
4
|
class AutoscalingGroup
|
5
5
|
# Initialize the class
|
6
|
-
def create(opts, new_config, aws_env, user_data
|
7
|
-
|
8
|
-
# ELB Parameters
|
9
|
-
elb_health_target: "#{new_config[:instance_protocol]}:#{new_config[:instance_port]}/healthz",
|
10
|
-
elb_protocol: new_config[:instance_protocol],
|
11
|
-
elb_name: "#{new_config[:name].gsub('_','-')}-discovery"
|
12
|
-
)
|
13
|
-
|
14
|
-
if new_config[:create_elb]
|
15
|
-
new_config.merge!({
|
16
|
-
elb_health_target: elb_health_target,
|
17
|
-
elb_protocol: elb_protocol,
|
18
|
-
elb_name: elb_name
|
19
|
-
})
|
20
|
-
|
21
|
-
Tapjoy::AutoscalingBootstrap::ELB.new.create(new_config, aws_env)
|
22
|
-
else
|
23
|
-
puts "\nNo ELB required"
|
24
|
-
end
|
6
|
+
def create(opts, new_config, aws_env, user_data)
|
25
7
|
|
26
8
|
Tapjoy::AutoscalingBootstrap::ConfigureAutoscalers.new(**new_config,
|
27
9
|
aws_env: aws_env, user_data: user_data, misc_config: new_config)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Tapjoy
|
2
|
+
module AutoscalingBootstrap
|
3
|
+
# This class contains tass methods for EC2
|
4
|
+
module EC2
|
5
|
+
class << self
|
6
|
+
def count_static_instances(config)
|
7
|
+
find_static_instances(config).length
|
8
|
+
end
|
9
|
+
|
10
|
+
def enable_termination_protection(instance_id)
|
11
|
+
Tapjoy::AutoscalingBootstrap::AWS::EC2.toggle_termination_protection(instance_id, 'true')
|
12
|
+
end
|
13
|
+
|
14
|
+
def disable_termination_protection(instance_id)
|
15
|
+
Tapjoy::AutoscalingBootstrap::AWS::EC2.toggle_termination_protection(instance_id, 'false')
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def find_static_instances(config)
|
20
|
+
response = Tapjoy::AutoscalingBootstrap::AWS::EC2.describe_instances_by_tag(config)
|
21
|
+
response.reservations
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -2,16 +2,32 @@ module Tapjoy
|
|
2
2
|
module AutoscalingBootstrap
|
3
3
|
# This class configures elastic load balancers
|
4
4
|
class ELB
|
5
|
-
|
6
|
-
|
5
|
+
def initialize(elb_hash, clobber_elb, zones, security_groups)
|
6
|
+
elb_config = build_config(elb_hash, zones, security_groups)
|
7
|
+
check_valid_config(elb_config)
|
8
|
+
|
9
|
+
if exists && clobber_elb
|
10
|
+
delete
|
11
|
+
create(elb_config)
|
12
|
+
elsif exists
|
13
|
+
Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.attach_elb(
|
14
|
+
Tapjoy::AutoscalingBootstrap.elb_name)
|
15
|
+
else
|
16
|
+
create(elb_config)
|
17
|
+
end
|
7
18
|
end
|
8
19
|
|
9
|
-
#
|
10
|
-
def
|
20
|
+
# Build config hash
|
21
|
+
def build_config(elb_hash, zones, security_groups)
|
22
|
+
elb_config = elb_hash[Tapjoy::AutoscalingBootstrap.elb_name]
|
23
|
+
elb_config[:elb_protocol] ||= elb_config[:instance_protocol]
|
24
|
+
elb_config[:elb_health_target] ||= "#{elb_config[:instance_protocol]}:#{elb_config[:instance_port]}/healthz"
|
25
|
+
elb_config.merge!({zones: zones, groups: security_groups})
|
26
|
+
end
|
11
27
|
|
12
|
-
|
13
|
-
|
14
|
-
Tapjoy::AutoscalingBootstrap::AWS::ELB.create(**config
|
28
|
+
# Create load balancer
|
29
|
+
def create(config)
|
30
|
+
Tapjoy::AutoscalingBootstrap::AWS::ELB.create(**config)
|
15
31
|
health_check(config)
|
16
32
|
end
|
17
33
|
|
@@ -25,6 +25,15 @@ module Tapjoy
|
|
25
25
|
abort("ERROR: Specified autoscaling group doesn't exist")
|
26
26
|
end
|
27
27
|
end
|
28
|
+
|
29
|
+
# Raise if an incorrect number of instance ids have been specified
|
30
|
+
class IncorrectNumberIds < ArgumentError
|
31
|
+
def initialize
|
32
|
+
error = 'Number of instance IDs specified must match the number '\
|
33
|
+
'of instances scaled down'
|
34
|
+
abort(error)
|
35
|
+
end
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
30
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ali Tayarani
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trollop
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '2.9'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec_junit_formatter
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.2.2
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.2.2
|
125
139
|
description: TASS is the suite of tools that the Tapjoy Operations team uses to manage
|
126
140
|
autoscaling groups and launch configurations.
|
127
141
|
email: ali.tayarani@tapjoy.com
|
@@ -150,6 +164,7 @@ files:
|
|
150
164
|
- lib/tapjoy/autoscaling_bootstrap/aws.rb
|
151
165
|
- lib/tapjoy/autoscaling_bootstrap/cloudwatch.rb
|
152
166
|
- lib/tapjoy/autoscaling_bootstrap/configure_autoscaler.rb
|
167
|
+
- lib/tapjoy/autoscaling_bootstrap/ec2.rb
|
153
168
|
- lib/tapjoy/autoscaling_bootstrap/elb.rb
|
154
169
|
- lib/tapjoy/autoscaling_bootstrap/errors.rb
|
155
170
|
- lib/tapjoy/autoscaling_bootstrap/errors/elb.rb
|