stemcell 0.11.11 → 0.13.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 +5 -5
- data/.travis.yml +1 -2
- data/CHANGELOG.md +17 -0
- data/Gemfile +1 -1
- data/README.md +2 -2
- data/examples/stemcell.json +6 -2
- data/lib/stemcell/launcher.rb +77 -200
- data/lib/stemcell/metadata_launcher.rb +1 -0
- data/lib/stemcell/metadata_source/configuration.rb +2 -2
- data/lib/stemcell/metadata_source.rb +6 -1
- data/lib/stemcell/option_parser.rb +6 -29
- data/lib/stemcell/templates/bootstrap.sh.erb +93 -20
- data/lib/stemcell/version.rb +1 -1
- data/spec/fixtures/chef_repo/stemcell-azs-missing.json +3 -1
- data/spec/fixtures/chef_repo/stemcell-backing-store-legacy.json +13 -0
- data/spec/fixtures/chef_repo/stemcell-cookbook-attribute.json +3 -1
- data/spec/fixtures/chef_repo/stemcell-defaults-missing.json +3 -1
- data/spec/fixtures/chef_repo/stemcell-options-parser.json +6 -2
- data/spec/fixtures/chef_repo/stemcell.json +3 -1
- data/spec/lib/stemcell/launcher_spec.rb +108 -123
- data/spec/lib/stemcell/metadata_source/configuration_spec.rb +16 -3
- data/spec/lib/stemcell/metadata_source_spec.rb +2 -1
- data/stemcell.gemspec +6 -3
- metadata +40 -13
- data/bin/necrosis +0 -114
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e65ab6388e741e11ab2f46af451098bd7fe70cb847f3ea8f1b9b9d229c860c2c
|
4
|
+
data.tar.gz: 568f4aecc9c7518ed156355035b39843b04d006bec7876438d707e097e071d30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53d4581e807c8c1373189437a5e0afb42e0dc00c62b3b2b18797a31ae72d483ac066af02c455cfc3fc9a98dcc5452f433bfef618b8f8e56643f5748cff22ce12
|
7
|
+
data.tar.gz: 431fe9ee22ac0f42ff40227f1ce39e74a88af53af1fb4dc571cace78d167e346d125a2615d35799060853767801412a8c8d4ba35603d269ebc1b5232ec4bbda5
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# 0.13.0
|
2
|
+
- Migrate to AWS SDK to v3
|
3
|
+
- Drop support for ClassicLink
|
4
|
+
- Removed `necrosis` script
|
5
|
+
|
6
|
+
# 0.12.2
|
7
|
+
- Support for using a custom EC2 endpoint
|
8
|
+
|
9
|
+
# 0.12.1
|
10
|
+
- Add support for Amazon Linux to the default bootstrap script
|
11
|
+
- Allow setting backing_store options per region
|
12
|
+
- Display private ip for launched instances
|
13
|
+
|
14
|
+
# 0.12.0
|
15
|
+
- Require Nokogiri ~> 1.8.2 due to vulnerability CVE-2017-15412
|
16
|
+
- Require ruby version >= 2.1 for Nokogiri compatibility
|
17
|
+
|
1
18
|
# 0.11.11
|
2
19
|
- Fix set_classic_link issue - vpc_id could be nil or false
|
3
20
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -77,10 +77,10 @@ $ stemcell $your_chef_role --tail
|
|
77
77
|
|
78
78
|
### Terminating:
|
79
79
|
|
80
|
-
To terminate, use the
|
80
|
+
To terminate, use the AWS CLI and pass a space separated list of instance ids:
|
81
81
|
|
82
82
|
```bash
|
83
|
-
$
|
83
|
+
$ aws ec2 terminate-instances --instance-ids i-12345678 i-12345679 i-12345670
|
84
84
|
```
|
85
85
|
|
86
86
|
## Automation ##
|
data/examples/stemcell.json
CHANGED
@@ -9,10 +9,14 @@
|
|
9
9
|
|
10
10
|
"backing_store": {
|
11
11
|
"ebs": {
|
12
|
-
"
|
12
|
+
"us-east-1": {
|
13
|
+
"image_id": "ami-23d9a94a"
|
14
|
+
}
|
13
15
|
},
|
14
16
|
"instance_store": {
|
15
|
-
"
|
17
|
+
"us-east-1": {
|
18
|
+
"image_id": "ami-d9d6a6b0"
|
19
|
+
}
|
16
20
|
}
|
17
21
|
},
|
18
22
|
|
data/lib/stemcell/launcher.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require 'aws-sdk-
|
1
|
+
require 'aws-sdk-ec2'
|
2
|
+
require 'base64'
|
2
3
|
require 'logger'
|
3
4
|
require 'erb'
|
4
5
|
require 'set'
|
@@ -48,7 +49,6 @@ module Stemcell
|
|
48
49
|
'security_groups',
|
49
50
|
'security_group_ids',
|
50
51
|
'tags',
|
51
|
-
'classic_link',
|
52
52
|
'iam_role',
|
53
53
|
'ebs_optimized',
|
54
54
|
'termination_protection',
|
@@ -75,6 +75,7 @@ module Stemcell
|
|
75
75
|
|
76
76
|
@region = opts['region']
|
77
77
|
@vpc_id = opts['vpc_id']
|
78
|
+
@ec2_endpoint = opts['ec2_endpoint']
|
78
79
|
@aws_access_key = opts['aws_access_key']
|
79
80
|
@aws_secret_key = opts['aws_secret_key']
|
80
81
|
@aws_session_token = opts['aws_session_token']
|
@@ -89,7 +90,7 @@ module Stemcell
|
|
89
90
|
opts['git_key'] = try_file(opts['git_key'])
|
90
91
|
opts['chef_data_bag_secret'] = try_file(opts['chef_data_bag_secret'])
|
91
92
|
|
92
|
-
# generate tags and merge in any that were
|
93
|
+
# generate tags and merge in any that were specified as inputs
|
93
94
|
tags = {
|
94
95
|
'Name' => "#{opts['chef_role']}-#{opts['chef_environment']}",
|
95
96
|
'Group' => "#{opts['chef_role']}-#{opts['chef_environment']}",
|
@@ -105,31 +106,38 @@ module Stemcell
|
|
105
106
|
:image_id => opts['image_id'],
|
106
107
|
:instance_type => opts['instance_type'],
|
107
108
|
:key_name => opts['key_name'],
|
108
|
-
:
|
109
|
+
:min_count => opts['count'],
|
110
|
+
:max_count => opts['count'],
|
109
111
|
}
|
110
112
|
|
113
|
+
|
114
|
+
# Associate Public IP can only bet set on network_interfaces, and if present
|
115
|
+
# security groups and subnet should be set on the interface. VPC-only.
|
116
|
+
# Primary network interface
|
117
|
+
network_interface = {
|
118
|
+
device_index: 0,
|
119
|
+
}
|
120
|
+
launch_options[:network_interfaces] = [network_interface]
|
121
|
+
|
111
122
|
if opts['security_group_ids'] && !opts['security_group_ids'].empty?
|
112
|
-
|
123
|
+
network_interface[:groups] = opts['security_group_ids']
|
113
124
|
end
|
114
125
|
|
115
126
|
if opts['security_groups'] && !opts['security_groups'].empty?
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
launch_options[:security_group_ids].concat(security_group_ids)
|
121
|
-
else
|
122
|
-
launch_options[:security_groups] = opts['security_groups']
|
123
|
-
end
|
127
|
+
# convert sg names to sg ids as VPC only accepts ids
|
128
|
+
security_group_ids = get_vpc_security_group_ids(@vpc_id, opts['security_groups'])
|
129
|
+
network_interface[:groups] ||= []
|
130
|
+
network_interface[:groups].concat(security_group_ids)
|
124
131
|
end
|
125
132
|
|
133
|
+
launch_options[:placement] = placement = {}
|
126
134
|
# specify availability zone (optional)
|
127
135
|
if opts['availability_zone']
|
128
|
-
|
136
|
+
placement[:availability_zone] = opts['availability_zone']
|
129
137
|
end
|
130
138
|
|
131
139
|
if opts['subnet']
|
132
|
-
|
140
|
+
network_interface[:subnet_id] = opts['subnet']
|
133
141
|
end
|
134
142
|
|
135
143
|
if opts['private_ip_address']
|
@@ -137,23 +145,23 @@ module Stemcell
|
|
137
145
|
end
|
138
146
|
|
139
147
|
if opts['dedicated_tenancy']
|
140
|
-
|
148
|
+
placement[:tenancy] = 'dedicated'
|
141
149
|
end
|
142
150
|
|
143
151
|
if opts['associate_public_ip_address']
|
144
|
-
|
152
|
+
network_interface[:associate_public_ip_address] = opts['associate_public_ip_address']
|
145
153
|
end
|
146
154
|
|
147
155
|
# specify IAM role (optional)
|
148
156
|
if opts['iam_role']
|
149
|
-
launch_options[:iam_instance_profile] =
|
157
|
+
launch_options[:iam_instance_profile] = {
|
158
|
+
name: opts['iam_role']
|
159
|
+
}
|
150
160
|
end
|
151
161
|
|
152
162
|
# specify placement group (optional)
|
153
163
|
if opts['placement_group']
|
154
|
-
|
155
|
-
:group_name => opts['placement_group'],
|
156
|
-
}
|
164
|
+
placement[:group_name] = opts['placement_group']
|
157
165
|
end
|
158
166
|
|
159
167
|
# specify an EBS-optimized instance (optional)
|
@@ -181,35 +189,31 @@ module Stemcell
|
|
181
189
|
end
|
182
190
|
end
|
183
191
|
|
192
|
+
if opts['termination_protection']
|
193
|
+
launch_options[:disable_api_termination] = true
|
194
|
+
end
|
195
|
+
|
184
196
|
# generate user data script to bootstrap instance, include in launch
|
185
197
|
# options UNLESS we have manually set the user-data (ie. for ec2admin)
|
186
|
-
launch_options[:user_data] = opts.fetch('user_data', render_template(opts))
|
198
|
+
launch_options[:user_data] = Base64.encode64(opts.fetch('user_data', render_template(opts)))
|
199
|
+
|
200
|
+
# add tags to launch options so we don't need to make a separate CreateTags call
|
201
|
+
launch_options[:tag_specifications] = [{
|
202
|
+
resource_type: 'instance',
|
203
|
+
tags: tags.map { |k, v| { key: k, value: v } }
|
204
|
+
}]
|
187
205
|
|
188
206
|
# launch instances
|
189
207
|
instances = do_launch(launch_options)
|
190
208
|
|
191
209
|
# everything from here on out must succeed, or we kill the instances we just launched
|
192
210
|
begin
|
193
|
-
# set tags on all instances launched
|
194
|
-
set_tags(instances, tags)
|
195
|
-
@log.info "sent ec2 api tag requests successfully"
|
196
|
-
|
197
|
-
# link to classiclink
|
198
|
-
unless @vpc_id
|
199
|
-
set_classic_link(instances, opts['classic_link'])
|
200
|
-
@log.info "successfully applied classic link settings (if any)"
|
201
|
-
end
|
202
|
-
|
203
|
-
# turn on termination protection
|
204
|
-
# we do this now to make sure all other settings worked
|
205
|
-
if opts['termination_protection']
|
206
|
-
enable_termination_protection(instances)
|
207
|
-
@log.info "successfully enabled termination protection"
|
208
|
-
end
|
209
|
-
|
210
211
|
# wait for aws to report instance stats
|
211
212
|
if opts.fetch('wait', true)
|
212
|
-
|
213
|
+
instance_ids = instances.map(&:instance_id)
|
214
|
+
@log.info "Waiting up to #{MAX_RUNNING_STATE_WAIT_TIME} seconds for #{instances.count} " \
|
215
|
+
"instance(s): (#{instance_ids})"
|
216
|
+
instances = wait(instance_ids)
|
213
217
|
print_run_info(instances)
|
214
218
|
@log.info "launched instances successfully"
|
215
219
|
end
|
@@ -226,19 +230,18 @@ module Stemcell
|
|
226
230
|
return instances
|
227
231
|
end
|
228
232
|
|
229
|
-
def kill(
|
230
|
-
return if !
|
233
|
+
def kill(instance_ids, opts={})
|
234
|
+
return if !instance_ids || instance_ids.empty?
|
231
235
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
check_errors(:kill, instances.map(&:id), errors)
|
236
|
+
@log.warn "Terminating instances #{instance_ids}"
|
237
|
+
ec2.terminate_instances(instance_ids: instance_ids)
|
238
|
+
nil # nil == success
|
239
|
+
rescue Aws::EC2::Errors::InvalidInstanceIDNotFound => e
|
240
|
+
raise unless opts[:ignore_not_found]
|
241
|
+
|
242
|
+
invalid_ids = e.message.scan(/i-[a-z0-9]+/)
|
243
|
+
instance_ids -= invalid_ids
|
244
|
+
retry unless instance_ids.empty? || invalid_ids.empty? # don't retry if we couldn't find any instance ids
|
242
245
|
end
|
243
246
|
|
244
247
|
# this is made public for ec2admin usage
|
@@ -248,7 +251,7 @@ module Stemcell
|
|
248
251
|
erb_template = ERB.new(template_file)
|
249
252
|
last_bootstrap_line = LAST_BOOTSTRAP_LINE
|
250
253
|
generated_template = erb_template.result(binding)
|
251
|
-
@log.debug "
|
254
|
+
@log.debug "generated template is #{generated_template}"
|
252
255
|
return generated_template
|
253
256
|
end
|
254
257
|
|
@@ -258,22 +261,23 @@ module Stemcell
|
|
258
261
|
puts "\nhere is the info for what's launched:"
|
259
262
|
instances.each do |instance|
|
260
263
|
puts "\tinstance_id: #{instance.instance_id}"
|
261
|
-
puts "\tpublic ip: #{instance.public_ip_address}"
|
264
|
+
puts "\tpublic ip: #{instance.public_ip_address || 'none'}"
|
265
|
+
puts "\tprivate ip: #{instance.private_ip_address || 'none'}"
|
262
266
|
puts
|
263
267
|
end
|
264
268
|
puts "install logs will be in /var/log/init and /var/log/init.err"
|
265
269
|
end
|
266
270
|
|
267
|
-
def wait(
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
271
|
+
def wait(instance_ids)
|
272
|
+
started_at = Time.now
|
273
|
+
result = ec2.wait_until(:instance_running, instance_ids: instance_ids) do |w|
|
274
|
+
w.max_attempts = nil
|
275
|
+
w.delay = RUNNING_STATE_WAIT_SLEEP_TIME
|
276
|
+
w.before_wait do |attempts, response|
|
277
|
+
throw :failure if Time.now - started_at > MAX_RUNNING_STATE_WAIT_TIME
|
278
|
+
end
|
274
279
|
end
|
275
|
-
|
276
|
-
@log.info "all instances in running state"
|
280
|
+
result.map { |page| page.reservations.map(&:instances) }.flatten
|
277
281
|
end
|
278
282
|
|
279
283
|
def verify_required_options(params, required_options)
|
@@ -289,35 +293,22 @@ module Stemcell
|
|
289
293
|
def do_launch(opts={})
|
290
294
|
@log.debug "about to launch instance(s) with options #{opts}"
|
291
295
|
@log.info "launching instances"
|
292
|
-
instances = ec2.
|
293
|
-
instances = [instances] unless Array === instances
|
296
|
+
instances = ec2.run_instances(opts).instances
|
294
297
|
instances.each do |instance|
|
295
298
|
@log.info "launched instance #{instance.instance_id}"
|
296
299
|
end
|
297
300
|
return instances
|
298
301
|
end
|
299
302
|
|
300
|
-
def set_tags(instances=[], tags)
|
301
|
-
@log.info "setting tags on instance(s)"
|
302
|
-
errors = run_batch_operation(instances) do |instance|
|
303
|
-
begin
|
304
|
-
instance.tags.set(tags)
|
305
|
-
nil # nil == success
|
306
|
-
rescue AWS::EC2::Errors::InvalidInstanceID::NotFound => e
|
307
|
-
e
|
308
|
-
end
|
309
|
-
end
|
310
|
-
check_errors(:set_tags, instances.map(&:id), errors)
|
311
|
-
end
|
312
|
-
|
313
303
|
# Resolve security group names to their ids in the given VPC
|
314
304
|
def get_vpc_security_group_ids(vpc_id, group_names)
|
315
305
|
group_map = {}
|
316
306
|
@log.info "resolving security groups #{group_names} in #{vpc_id}"
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
307
|
+
ec2.describe_security_groups(filters: [{ name: 'vpc-id', values: [vpc_id] }]).
|
308
|
+
each do |response|
|
309
|
+
response.security_groups.each do |sg|
|
310
|
+
group_map[sg.group_name] = sg.group_id
|
311
|
+
end
|
321
312
|
end
|
322
313
|
group_ids = []
|
323
314
|
group_names.each do |sg_name|
|
@@ -327,129 +318,15 @@ module Stemcell
|
|
327
318
|
group_ids
|
328
319
|
end
|
329
320
|
|
330
|
-
def set_classic_link(left_to_process, classic_link)
|
331
|
-
return unless classic_link
|
332
|
-
return unless classic_link['vpc_id']
|
333
|
-
|
334
|
-
security_group_ids = classic_link['security_group_ids'] || []
|
335
|
-
security_group_names = classic_link['security_groups'] || []
|
336
|
-
return if security_group_ids.empty? && security_group_names.empty?
|
337
|
-
|
338
|
-
if !security_group_names.empty?
|
339
|
-
extra_group_ids = get_vpc_security_group_ids(classic_link['vpc_id'], security_group_names)
|
340
|
-
security_group_ids = security_group_ids + extra_group_ids
|
341
|
-
end
|
342
|
-
|
343
|
-
@log.info "applying classic link settings on #{left_to_process.count} instance(s)"
|
344
|
-
|
345
|
-
errors = []
|
346
|
-
processed = []
|
347
|
-
times_out_at = Time.now + MAX_RUNNING_STATE_WAIT_TIME
|
348
|
-
until left_to_process.empty?
|
349
|
-
wait_time_expire_or_sleep(times_out_at)
|
350
|
-
|
351
|
-
# we can only apply classic link when instances are in the running state
|
352
|
-
# lets apply classiclink as instances become available so we don't wait longer than necessary
|
353
|
-
recently_running = left_to_process.select{ |inst| inst.status == :running }
|
354
|
-
left_to_process = left_to_process.reject{ |inst| recently_running.include?(inst) }
|
355
|
-
|
356
|
-
processed += recently_running
|
357
|
-
errors += run_batch_operation(recently_running) do |instance|
|
358
|
-
begin
|
359
|
-
result = ec2.client.attach_classic_link_vpc({
|
360
|
-
:instance_id => instance.id,
|
361
|
-
:vpc_id => classic_link['vpc_id'],
|
362
|
-
:groups => security_group_ids,
|
363
|
-
})
|
364
|
-
result.error
|
365
|
-
rescue StandardError => e
|
366
|
-
e
|
367
|
-
end
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
|
-
check_errors(:set_classic_link, processed.map(&:id), errors)
|
372
|
-
end
|
373
|
-
|
374
|
-
def enable_termination_protection(instances)
|
375
|
-
@log.info "enabling termination protection on instance(s)"
|
376
|
-
errors = run_batch_operation(instances) do |instance|
|
377
|
-
begin
|
378
|
-
resp = ec2.client.modify_instance_attribute({
|
379
|
-
:instance_id => instance.id,
|
380
|
-
:disable_api_termination => {
|
381
|
-
:value => true
|
382
|
-
}
|
383
|
-
})
|
384
|
-
resp.error # returns nil (success) unless there was an error
|
385
|
-
rescue StandardError => e
|
386
|
-
e
|
387
|
-
end
|
388
|
-
end
|
389
|
-
check_errors(:enable_termination_protection, instances.map(&:id), errors)
|
390
|
-
end
|
391
|
-
|
392
321
|
# attempt to accept keys as file paths
|
393
322
|
def try_file(opt="")
|
394
323
|
File.read(File.expand_path(opt)) rescue opt
|
395
324
|
end
|
396
325
|
|
397
|
-
INITIAL_RETRY_SEC = 1
|
398
|
-
|
399
|
-
# Return a Hash of instance => error. Empty hash indicates "no error"
|
400
|
-
# for code block:
|
401
|
-
# - if block returns nil, success
|
402
|
-
# - if block returns non-nil value (e.g., exception), retry 3 times w/ backoff
|
403
|
-
# - if block raises exception, fail
|
404
|
-
def run_batch_operation(instances)
|
405
|
-
instances.map do |instance|
|
406
|
-
begin
|
407
|
-
attempt = 0
|
408
|
-
result = nil
|
409
|
-
while attempt < @max_attempts
|
410
|
-
# sleep idempotently except for the first attempt
|
411
|
-
sleep(INITIAL_RETRY_SEC * 2 ** attempt) if attempt != 0
|
412
|
-
result = yield(instance)
|
413
|
-
break if result.nil? # nil indicates success
|
414
|
-
attempt += 1
|
415
|
-
end
|
416
|
-
result # result for this instance is nil or returned exception
|
417
|
-
rescue => e
|
418
|
-
e # result for this instance is caught exception
|
419
|
-
end
|
420
|
-
end
|
421
|
-
end
|
422
|
-
|
423
|
-
def check_errors(operation, instance_ids, errors)
|
424
|
-
return if errors.all?(&:nil?)
|
425
|
-
raise IncompleteOperation.new(
|
426
|
-
operation,
|
427
|
-
instance_ids,
|
428
|
-
instance_ids.zip(errors).reject { |i, e| e.nil? }
|
429
|
-
)
|
430
|
-
end
|
431
|
-
|
432
326
|
def ec2
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
ec2_url = "ec2.#{@region}.amazonaws.com"
|
437
|
-
|
438
|
-
if @vpc_id
|
439
|
-
@ec2 = AWS::EC2::VPC.new(@vpc_id, :ec2_endpoint => ec2_url)
|
440
|
-
else
|
441
|
-
@ec2 = AWS::EC2.new(:ec2_endpoint => ec2_url)
|
442
|
-
end
|
443
|
-
|
444
|
-
@ec2
|
445
|
-
end
|
446
|
-
|
447
|
-
def wait_time_expire_or_sleep(times_out_at)
|
448
|
-
now = Time.now
|
449
|
-
if now >= times_out_at
|
450
|
-
raise TimeoutError, "exceded timeout of #{MAX_RUNNING_STATE_WAIT_TIME} seconds"
|
451
|
-
else
|
452
|
-
sleep [RUNNING_STATE_WAIT_SLEEP_TIME, times_out_at - now].min
|
327
|
+
@ec2 ||= begin
|
328
|
+
opts = @ec2_endpoint ? { endpoint: @ec2_endpoint } : {}
|
329
|
+
Aws::EC2::Client.new(opts)
|
453
330
|
end
|
454
331
|
end
|
455
332
|
|
@@ -463,7 +340,7 @@ module Stemcell
|
|
463
340
|
aws_configs.merge!({
|
464
341
|
:session_token => @aws_session_token,
|
465
342
|
}) if @aws_session_token
|
466
|
-
|
343
|
+
Aws.config.update(aws_configs)
|
467
344
|
end
|
468
345
|
end
|
469
346
|
end
|
@@ -101,6 +101,7 @@ module Stemcell
|
|
101
101
|
'region' => options['region'],
|
102
102
|
'vpc_id' => options['vpc_id'],
|
103
103
|
'max_attempts' => options['batch_operation_retries'],
|
104
|
+
'ec2_endpoint' => options['ec2_endpoint'],
|
104
105
|
})
|
105
106
|
# Slice off just the options used for launching.
|
106
107
|
launch_options = {}
|
@@ -21,10 +21,10 @@ module Stemcell
|
|
21
21
|
validate_configutation
|
22
22
|
end
|
23
23
|
|
24
|
-
def options_for_backing_store(backing_store)
|
24
|
+
def options_for_backing_store(backing_store, region)
|
25
25
|
options = backing_store_options[backing_store]
|
26
26
|
raise UnknownBackingStoreError.new(backing_store) if options.nil?
|
27
|
-
options
|
27
|
+
options.fetch(region, options)
|
28
28
|
end
|
29
29
|
|
30
30
|
def random_az_for_region(region)
|
@@ -84,9 +84,14 @@ module Stemcell
|
|
84
84
|
backing_store ||= config.default_options['backing_store']
|
85
85
|
backing_store ||= DEFAULT_BACKING_STORE
|
86
86
|
|
87
|
+
backing_store_region = override_options['region']
|
88
|
+
backing_store_region ||= role_options.to_hash['region'] if role_options
|
89
|
+
backing_store_region ||= config.default_options['region']
|
90
|
+
backing_store_region ||= DEFAULT_OPTIONS['region']
|
91
|
+
|
87
92
|
# Step 3: Retrieve the backing store options from the defaults.
|
88
93
|
|
89
|
-
backing_store_options = config.options_for_backing_store(backing_store)
|
94
|
+
backing_store_options = config.options_for_backing_store(backing_store, backing_store_region)
|
90
95
|
backing_store_options['backing_store'] = backing_store
|
91
96
|
|
92
97
|
# Step 4: Merge the options together in priority order.
|
@@ -42,6 +42,12 @@ module Stemcell
|
|
42
42
|
:env => 'AWS_SESSION_TOKEN',
|
43
43
|
:hide => true
|
44
44
|
},
|
45
|
+
{
|
46
|
+
:name => 'ec2_endpoint',
|
47
|
+
:desc => 'EC2 endpoint',
|
48
|
+
:type => String,
|
49
|
+
:env => 'EC2_ENDPOINT',
|
50
|
+
},
|
45
51
|
{
|
46
52
|
:name => 'region',
|
47
53
|
:desc => "ec2 region to launch in",
|
@@ -90,24 +96,6 @@ module Stemcell
|
|
90
96
|
:type => String,
|
91
97
|
:env => 'VPC_ID'
|
92
98
|
},
|
93
|
-
{
|
94
|
-
:name => 'classic_link_vpc_id',
|
95
|
-
:desc => 'VPC ID to which this instance will be classic-linked',
|
96
|
-
:type => String,
|
97
|
-
:env => 'CLASSIC_LINK_VPC_ID',
|
98
|
-
},
|
99
|
-
{
|
100
|
-
:name => 'classic_link_security_group_ids',
|
101
|
-
:desc => 'comma-separated list of security group IDs to link into ClassicLink; not used unless classic_link_vpc_id is set',
|
102
|
-
:type => String,
|
103
|
-
:env => 'CLASSIC_LINK_SECURITY_GROUP_IDS',
|
104
|
-
},
|
105
|
-
{
|
106
|
-
:name => 'classic_link_security_groups',
|
107
|
-
:desc => 'comma-separated list of security groups to link into ClassicLink; not used unless classic_link_vpc_id is set',
|
108
|
-
:type => String,
|
109
|
-
:env => 'CLASSIC_LINK_SECURITY_GROUPS',
|
110
|
-
},
|
111
99
|
{
|
112
100
|
:name => 'subnet',
|
113
101
|
:desc => "VPC subnet for which to launch this instance",
|
@@ -424,17 +412,6 @@ module Stemcell
|
|
424
412
|
# convert chef_cookbook_attributes from comma separated string to ruby array
|
425
413
|
options['chef_cookbook_attributes'] &&= options['chef_cookbook_attributes'].split(',')
|
426
414
|
|
427
|
-
# format the classic link options
|
428
|
-
if options['classic_link_vpc_id']
|
429
|
-
options['classic_link']['vpc_id'] = options['classic_link_vpc_id']
|
430
|
-
end
|
431
|
-
if options['classic_link_security_group_ids']
|
432
|
-
options['classic_link']['security_group_ids'] = options['classic_link_security_group_ids'].split(',')
|
433
|
-
end
|
434
|
-
if options['classic_link_security_groups']
|
435
|
-
options['classic_link']['security_groups'] = options['classic_link_security_groups'].split(',')
|
436
|
-
end
|
437
|
-
|
438
415
|
options
|
439
416
|
end
|
440
417
|
|