vm_shepherd 3.2.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c93104a5569a16a2bec5d35a2861429a229c2deb
4
- data.tar.gz: 7495d0600e7d4f2a4a7bee91826182eb245d4529
3
+ metadata.gz: 244e9c4bff360b11b78a561dc70c60501a32cf54
4
+ data.tar.gz: cf11ae1030f1c9b6e2c1ab1e0eb60f938e429825
5
5
  SHA512:
6
- metadata.gz: 3456e991ed128fa9ec34b0556809f36e55a32d048751510dfd4134e57dac113c44da66145d17d5df63f7270522b1c297a616eb91169b8de52a80430c55b3cd45
7
- data.tar.gz: fde39b5b95888111acf5a79a2b39589a369632e77757f357380ea046daa441f882d4c885c8cbf781f71b2bd5f481a9269445f717269f77441aedcbfeffdfa7d3
6
+ metadata.gz: 72acaa44c186bd8508b27534b1e1440738ba94b20ecce4e5cd42d31ef716cac19fb42ffc96b2b5ba3f6fed65f1db58184cc9862583f3b8ec07b33e92aa809dec
7
+ data.tar.gz: e2cc0d3804d5e70e146181092fffc9907b90c67ad716d715bf75c215f4884e5c509eb7f679e16d215aea81e28ef3523d860fb0f58bfd31347d0aacaf47225fe3
@@ -13,6 +13,9 @@ module VmShepherd
13
13
 
14
14
  CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS'
15
15
  CREATE_COMPLETE = 'CREATE_COMPLETE'
16
+ UPDATE_IN_PROGRESS = 'UPDATE_IN_PROGRESS'
17
+ UPDATE_COMPLETE = 'UPDATE_COMPLETE'
18
+ UPDATE_COMPLETE_CLEANUP_IN_PROGRESS = 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS'
16
19
  ROLLBACK_IN_PROGRESS = 'ROLLBACK_IN_PROGRESS'
17
20
  ROLLBACK_COMPLETE = 'ROLLBACK_COMPLETE'
18
21
  DELETE_IN_PROGRESS = 'DELETE_IN_PROGRESS'
@@ -33,18 +36,35 @@ module VmShepherd
33
36
  template = File.read(cloudformation_template_file)
34
37
 
35
38
  cfm = AWS::CloudFormation.new
36
- logger.info('Starting CloudFormation Stack Creation')
37
- stack = cfm.stacks.create(env_config.fetch('stack_name'), template, parameters: env_config.fetch('parameters'), capabilities: ['CAPABILITY_IAM'])
39
+ stack_name = env_config.fetch('stack_name')
38
40
 
39
- logger.info("Waiting for status: #{CREATE_COMPLETE}")
41
+ stack = cfm.stacks[stack_name]
42
+
43
+ if stack and env_config.fetch('update_existing', false)
44
+ logger.info('Found existing stack - upgrading it')
45
+ stack.update(:template => template, parameters: env_config.fetch('parameters'), capabilities: ['CAPABILITY_IAM'])
46
+ waiting_for_status = UPDATE_COMPLETE
47
+ else
48
+ logger.info('Starting CloudFormation Stack Creation')
49
+ stack = cfm.stacks.create(stack_name, template, parameters: env_config.fetch('parameters'), capabilities: ['CAPABILITY_IAM'])
50
+ waiting_for_status = CREATE_COMPLETE
51
+ end
52
+
53
+ logger.info("Waiting for status [#{waiting_for_status}] on stack [#{stack.name}]")
40
54
  retry_until(retry_limit: 80, retry_interval: 30) do
41
55
  status = stack.status
42
56
  logger.info("current stack status: #{status}")
43
57
  case status
44
58
  when CREATE_COMPLETE
45
59
  true
60
+ when UPDATE_COMPLETE
61
+ true
46
62
  when CREATE_IN_PROGRESS
47
63
  false
64
+ when UPDATE_IN_PROGRESS
65
+ false
66
+ when UPDATE_COMPLETE_CLEANUP_IN_PROGRESS
67
+ false
48
68
  when ROLLBACK_IN_PROGRESS
49
69
  false
50
70
  else
@@ -207,13 +207,14 @@ module VmShepherd
207
207
  @ami_manager ||=
208
208
  VmShepherd::AwsManager.new(
209
209
  env_config: {
210
- 'stack_name' => @env_config.dig('stack_name'),
211
- 'aws_access_key' => @env_config.dig('aws_access_key'),
212
- 'aws_secret_key' => @env_config.dig('aws_secret_key'),
213
- 'region' => @env_config.dig('region'),
214
- 'json_file' => @env_config.dig('json_file'),
215
- 'parameters' => @env_config.dig('parameters'),
216
- 'outputs' => @env_config.dig('outputs'),
210
+ 'stack_name' => @env_config.dig('stack_name'),
211
+ 'aws_access_key' => @env_config.dig('aws_access_key'),
212
+ 'aws_secret_key' => @env_config.dig('aws_secret_key'),
213
+ 'region' => @env_config.dig('region'),
214
+ 'json_file' => @env_config.dig('json_file'),
215
+ 'parameters' => @env_config.dig('parameters'),
216
+ 'outputs' => @env_config.dig('outputs'),
217
+ 'update_existing' => true == @env_config.dig('update_existing'),
217
218
  }.merge(ami_elb_config),
218
219
  logger: stdout_logger,
219
220
  )
@@ -1,3 +1,3 @@
1
1
  module VmShepherd
2
- VERSION = '3.2.1'.freeze
2
+ VERSION = '3.3.0'.freeze
3
3
  end
@@ -58,176 +58,223 @@ module VmShepherd
58
58
 
59
59
  describe '#prepare_environment' do
60
60
  let(:cloudformation_template_file) { Tempfile.new('cloudformation_template_file').tap { |f| f.write('{}'); f.close } }
61
- let(:cfm) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
62
- let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'CREATE_COMPLETE') }
61
+ let(:cfn) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
62
+ let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'CREATE_COMPLETE', update: true, name: 'sample-stack') }
63
+
63
64
  let(:stack_collection) { instance_double(AWS::CloudFormation::StackCollection) }
64
65
  let(:elb) { instance_double(AWS::ELB, load_balancers: load_balancers) }
65
66
  let(:load_balancers) { instance_double(AWS::ELB::LoadBalancerCollection) }
66
67
 
67
68
  before do
68
- allow(AWS::CloudFormation).to receive(:new).and_return(cfm)
69
+ allow(AWS::CloudFormation).to receive(:new).and_return(cfn)
69
70
  allow(AWS::ELB).to receive(:new).and_return(elb)
70
- allow(stack_collection).to receive(:create).and_return(stack)
71
+ allow(stack_collection).to receive(:[]).and_return(nil)
71
72
  end
72
73
 
73
- describe 'cloudformation' do
74
- it 'polls the status every 30 seconds' do
75
- expect(ami_manager).to receive(:retry_until).with(retry_limit: 80, retry_interval: 30)
76
-
77
- ami_manager.prepare_environment(cloudformation_template_file.path)
74
+ context 'when a stack already exists' do
75
+ before do
76
+ allow(stack_collection).to receive(:[]).with('aws-stack-name').and_return(stack)
78
77
  end
79
78
 
80
- it 'creates the stack with the correct parameters' do
81
- expect(stack_collection).to receive(:create).with(
82
- 'aws-stack-name',
83
- '{}',
84
- parameters: {
85
- 'some_parameter' => 'some-answer',
86
- },
87
- capabilities: ['CAPABILITY_IAM']
88
- )
89
- ami_manager.prepare_environment(cloudformation_template_file.path)
90
- end
79
+ context 'when update_existing is enabled' do
91
80
 
92
- it 'waits for the stack to finish creating' do
93
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE')
81
+ let(:extra_configs) { {'update_existing' => true} }
82
+ let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'UPDATE_COMPLETE', update: true, name: 'stack-fails-to-update') }
94
83
 
95
- ami_manager.prepare_environment(cloudformation_template_file.path)
96
- end
84
+ it 'upgrades the existing stack with the provided template' do
85
+ ami_manager.prepare_environment(cloudformation_template_file.path)
97
86
 
98
- it 'stops retrying after 80 times' do
99
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS').
100
- exactly(80).times
87
+ expect(stack).to have_received(:update)
88
+ end
101
89
 
102
- expect { ami_manager.prepare_environment(cloudformation_template_file.path) }.to raise_error(AwsManager::RetryLimitExceeded)
90
+ it 'aborts if stack fails to update' do
91
+ expect(stack).to receive(:status).and_return('UPDATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
92
+ expect(stack).to receive(:delete)
93
+ expect(stack).to receive(:events).and_return([])
94
+ expect {
95
+ ami_manager.prepare_environment(cloudformation_template_file.path)
96
+ }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
97
+ end
103
98
  end
104
99
 
105
- it 'aborts if stack fails to create' do
106
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
107
- expect(stack).to receive(:delete)
108
- expect(stack).to receive(:name).and_return('dummy')
109
- expect(stack).to receive(:events).and_return([])
110
- expect {
100
+ context 'when update_existing is disabled' do
101
+ let(:extra_configs) { {'update_existing' => false} }
102
+
103
+ it 'errors out due to the stack already existing' do
104
+ allow(stack_collection).to receive(:create).and_return(stack)
105
+
111
106
  ami_manager.prepare_environment(cloudformation_template_file.path)
112
- }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
107
+
108
+ expect(stack).not_to have_received(:update)
109
+ end
113
110
  end
114
111
  end
115
112
 
116
- context 'when the elb setting is present' do
117
- let(:extra_configs) do
118
- {
119
- 'elbs' => [
120
- {
121
- 'name' => 'elb-1-name',
122
- 'port_mappings' => [[1111, 11]],
123
- 'health_check' => {
124
- 'ping_target' => 'TCP:1234',
125
- },
126
- 'stack_output_keys' => {
127
- 'vpc_id' => 'vpc_id',
128
- 'subnet_id' => 'private_subnet',
129
- },
130
- },
131
- {
132
- 'name' => 'elb-2-name',
133
- 'port_mappings' => [[2222, 22]],
134
- 'stack_output_keys' => {
135
- 'vpc_id' => 'vpc_id',
136
- 'subnet_id' => 'private_subnet',
137
- },
138
- }
139
- ],
140
- }
141
- end
142
- let(:stack) do
143
- instance_double(AWS::CloudFormation::Stack,
144
- name: 'fake-stack-name',
145
- creation_time: Time.utc(2015, 5, 29),
146
- status: 'CREATE_COMPLETE',
147
- outputs: stack_outputs
148
- )
149
- end
150
- let(:stack_outputs) do
151
- [
152
- instance_double(AWS::CloudFormation::StackOutput, key: 'private_subnet', value: 'fake-subnet-id'),
153
- instance_double(AWS::CloudFormation::StackOutput, key: 'vpc_id', value: 'fake-vpc-id'),
154
- ]
155
- end
156
- let(:ec2_client) { double(AWS::EC2::Client) }
157
- let(:create_security_group_response_1) do
158
- {group_id: 'elb-1-security-group'}
159
- end
160
- let(:create_security_group_response_2) do
161
- {group_id: 'elb-2-security-group'}
162
- end
163
- let(:security_groups) do
164
- {
165
- 'elb-1-security-group' => elb_1_security_group,
166
- 'elb-2-security-group' => elb_2_security_group,
167
- }
113
+ context 'when the stack does not yet exist' do
114
+ before do
115
+ allow(stack_collection).to receive(:[]).and_return([])
116
+ allow(stack_collection).to receive(:create).and_return(stack)
168
117
  end
169
- let(:elb_1_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-1-security-group-id') }
170
- let(:elb_2_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-2-security-group-id') }
171
118
 
172
- let(:elb_1) { instance_double(AWS::ELB::LoadBalancer, configure_health_check: nil) }
173
- let(:elb_2) { instance_double(AWS::ELB::LoadBalancer) }
119
+ describe 'cloudformation' do
120
+ it 'polls the status every 30 seconds' do
121
+ expect(ami_manager).to receive(:retry_until).with(retry_limit: 80, retry_interval: 30)
174
122
 
175
- before do
176
- allow(ec2).to receive(:client).and_return(ec2_client)
177
- allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-1-name')).
178
- and_return(create_security_group_response_1)
179
- allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-2-name')).
180
- and_return(create_security_group_response_2)
181
- allow(ec2).to receive(:security_groups).and_return(security_groups)
182
- allow(elb_1_security_group).to receive(:authorize_ingress)
183
- allow(elb_2_security_group).to receive(:authorize_ingress)
184
- allow(load_balancers).to receive(:create).and_return(elb_1)
185
- end
186
-
187
- it 'creates and attaches a security group for the ELBs' do
188
- elb_1_security_group_args = {
189
- group_name: 'fake-stack-name_elb-1-name',
190
- description: 'ELB Security Group',
191
- vpc_id: 'fake-vpc-id',
192
- }
193
- expect(ec2_client).to receive(:create_security_group).with(elb_1_security_group_args).and_return(create_security_group_response_1)
194
- expect(elb_1_security_group).to receive(:authorize_ingress).with(:tcp, 1111, '0.0.0.0/0')
123
+ ami_manager.prepare_environment(cloudformation_template_file.path)
124
+ end
195
125
 
196
- elb_2_security_group_args = {
197
- group_name: 'fake-stack-name_elb-2-name',
198
- description: 'ELB Security Group',
199
- vpc_id: 'fake-vpc-id',
200
- }
201
- expect(ec2_client).to receive(:create_security_group).with(elb_2_security_group_args).and_return(create_security_group_response_2)
202
- expect(elb_2_security_group).to receive(:authorize_ingress).with(:tcp, 2222, '0.0.0.0/0')
126
+ it 'creates the stack with the correct parameters' do
127
+ expect(stack_collection).to receive(:create).with(
128
+ 'aws-stack-name',
129
+ '{}',
130
+ parameters: {
131
+ 'some_parameter' => 'some-answer',
132
+ },
133
+ capabilities: ['CAPABILITY_IAM']
134
+ )
135
+ ami_manager.prepare_environment(cloudformation_template_file.path)
136
+ end
137
+
138
+ it 'waits for the stack to finish creating' do
139
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE')
203
140
 
204
- ami_manager.prepare_environment(cloudformation_template_file.path)
141
+ ami_manager.prepare_environment(cloudformation_template_file.path)
142
+ end
143
+
144
+ it 'stops retrying after 80 times' do
145
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS').
146
+ exactly(80).times
147
+
148
+ expect { ami_manager.prepare_environment(cloudformation_template_file.path) }.to raise_error(AwsManager::RetryLimitExceeded)
149
+ end
150
+
151
+ it 'aborts if stack fails to create' do
152
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
153
+ expect(stack).to receive(:delete)
154
+ expect(stack).to receive(:name).and_return('dummy')
155
+ expect(stack).to receive(:events).and_return([])
156
+ expect {
157
+ ami_manager.prepare_environment(cloudformation_template_file.path)
158
+ }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
159
+ end
205
160
  end
206
161
 
207
- it 'attaches an elb with the name of the stack for the ELBs' do
208
- health_check_params = {
209
- healthy_threshold: 2,
210
- unhealthy_threshold: 5,
211
- interval: 5,
212
- timeout: 2,
213
- }
214
- elb_1_params = {
215
- listeners: [{protocol: 'TCP', load_balancer_port: 1111, instance_protocol: 'TCP', instance_port: 11}],
216
- subnets: ['fake-subnet-id'],
217
- security_groups: ['elb-1-security-group-id']
218
- }
219
- expect(load_balancers).to receive(:create).with('elb-1-name', elb_1_params).and_return(elb_1)
220
- expect(elb_1).to receive(:configure_health_check).with(
221
- health_check_params.merge(target: 'TCP:1234')
222
- )
223
- elb_2_params = {
224
- listeners: [{protocol: 'TCP', load_balancer_port: 2222, instance_protocol: 'TCP', instance_port: 22}],
225
- subnets: ['fake-subnet-id'],
226
- security_groups: ['elb-2-security-group-id']
227
- }
228
- expect(load_balancers).to receive(:create).with('elb-2-name', elb_2_params).and_return(elb_2)
229
- expect(elb_2).not_to receive(:configure_health_check)
230
- ami_manager.prepare_environment(cloudformation_template_file.path)
162
+ context 'when the elb setting is present' do
163
+ let(:extra_configs) do
164
+ {
165
+ 'elbs' => [
166
+ {
167
+ 'name' => 'elb-1-name',
168
+ 'port_mappings' => [[1111, 11]],
169
+ 'health_check' => {
170
+ 'ping_target' => 'TCP:1234',
171
+ },
172
+ 'stack_output_keys' => {
173
+ 'vpc_id' => 'vpc_id',
174
+ 'subnet_id' => 'private_subnet',
175
+ },
176
+ },
177
+ {
178
+ 'name' => 'elb-2-name',
179
+ 'port_mappings' => [[2222, 22]],
180
+ 'stack_output_keys' => {
181
+ 'vpc_id' => 'vpc_id',
182
+ 'subnet_id' => 'private_subnet',
183
+ },
184
+ }
185
+ ],
186
+ }
187
+ end
188
+ let(:stack) do
189
+ instance_double(AWS::CloudFormation::Stack,
190
+ name: 'fake-stack-name',
191
+ creation_time: Time.utc(2015, 5, 29),
192
+ status: 'CREATE_COMPLETE',
193
+ outputs: stack_outputs
194
+ )
195
+ end
196
+ let(:stack_outputs) do
197
+ [
198
+ instance_double(AWS::CloudFormation::StackOutput, key: 'private_subnet', value: 'fake-subnet-id'),
199
+ instance_double(AWS::CloudFormation::StackOutput, key: 'vpc_id', value: 'fake-vpc-id'),
200
+ ]
201
+ end
202
+ let(:ec2_client) { double(AWS::EC2::Client) }
203
+ let(:create_security_group_response_1) do
204
+ {group_id: 'elb-1-security-group'}
205
+ end
206
+ let(:create_security_group_response_2) do
207
+ {group_id: 'elb-2-security-group'}
208
+ end
209
+ let(:security_groups) do
210
+ {
211
+ 'elb-1-security-group' => elb_1_security_group,
212
+ 'elb-2-security-group' => elb_2_security_group,
213
+ }
214
+ end
215
+ let(:elb_1_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-1-security-group-id') }
216
+ let(:elb_2_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-2-security-group-id') }
217
+
218
+ let(:elb_1) { instance_double(AWS::ELB::LoadBalancer, configure_health_check: nil) }
219
+ let(:elb_2) { instance_double(AWS::ELB::LoadBalancer) }
220
+
221
+ before do
222
+ allow(ec2).to receive(:client).and_return(ec2_client)
223
+ allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-1-name')).
224
+ and_return(create_security_group_response_1)
225
+ allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-2-name')).
226
+ and_return(create_security_group_response_2)
227
+ allow(ec2).to receive(:security_groups).and_return(security_groups)
228
+ allow(elb_1_security_group).to receive(:authorize_ingress)
229
+ allow(elb_2_security_group).to receive(:authorize_ingress)
230
+ allow(load_balancers).to receive(:create).and_return(elb_1)
231
+ end
232
+
233
+ it 'creates and attaches a security group for the ELBs' do
234
+ elb_1_security_group_args = {
235
+ group_name: 'fake-stack-name_elb-1-name',
236
+ description: 'ELB Security Group',
237
+ vpc_id: 'fake-vpc-id',
238
+ }
239
+ expect(ec2_client).to receive(:create_security_group).with(elb_1_security_group_args).and_return(create_security_group_response_1)
240
+ expect(elb_1_security_group).to receive(:authorize_ingress).with(:tcp, 1111, '0.0.0.0/0')
241
+
242
+ elb_2_security_group_args = {
243
+ group_name: 'fake-stack-name_elb-2-name',
244
+ description: 'ELB Security Group',
245
+ vpc_id: 'fake-vpc-id',
246
+ }
247
+ expect(ec2_client).to receive(:create_security_group).with(elb_2_security_group_args).and_return(create_security_group_response_2)
248
+ expect(elb_2_security_group).to receive(:authorize_ingress).with(:tcp, 2222, '0.0.0.0/0')
249
+
250
+ ami_manager.prepare_environment(cloudformation_template_file.path)
251
+ end
252
+
253
+ it 'attaches an elb with the name of the stack for the ELBs' do
254
+ health_check_params = {
255
+ healthy_threshold: 2,
256
+ unhealthy_threshold: 5,
257
+ interval: 5,
258
+ timeout: 2,
259
+ }
260
+ elb_1_params = {
261
+ listeners: [{protocol: 'TCP', load_balancer_port: 1111, instance_protocol: 'TCP', instance_port: 11}],
262
+ subnets: ['fake-subnet-id'],
263
+ security_groups: ['elb-1-security-group-id']
264
+ }
265
+ expect(load_balancers).to receive(:create).with('elb-1-name', elb_1_params).and_return(elb_1)
266
+ expect(elb_1).to receive(:configure_health_check).with(
267
+ health_check_params.merge(target: 'TCP:1234')
268
+ )
269
+ elb_2_params = {
270
+ listeners: [{protocol: 'TCP', load_balancer_port: 2222, instance_protocol: 'TCP', instance_port: 22}],
271
+ subnets: ['fake-subnet-id'],
272
+ security_groups: ['elb-2-security-group-id']
273
+ }
274
+ expect(load_balancers).to receive(:create).with('elb-2-name', elb_2_params).and_return(elb_2)
275
+ expect(elb_2).not_to receive(:configure_health_check)
276
+ ami_manager.prepare_environment(cloudformation_template_file.path)
277
+ end
231
278
  end
232
279
  end
233
280
  end
@@ -369,7 +416,7 @@ module VmShepherd
369
416
  let(:instance2) { instance_double(AWS::EC2::Instance, tags: {}, id: 'instance2') }
370
417
  let(:subnet1_instances) { [instance1] }
371
418
  let(:subnet2_instances) { [instance2] }
372
- let(:cfm) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
419
+ let(:cfn) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
373
420
  let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'DELETE_COMPLETE', delete: nil) }
374
421
  let(:stack_collection) { instance_double(AWS::CloudFormation::StackCollection) }
375
422
 
@@ -382,7 +429,7 @@ module VmShepherd
382
429
  let(:s3_client) { instance_double(AWS::S3, buckets: buckets) }
383
430
 
384
431
  before do
385
- allow(AWS::CloudFormation).to receive(:new).and_return(cfm)
432
+ allow(AWS::CloudFormation).to receive(:new).and_return(cfn)
386
433
  allow(stack_collection).to receive(:[]).and_return(stack)
387
434
 
388
435
  allow(ec2).to receive(:subnets).and_return(subnets)
@@ -16,6 +16,7 @@ module VmShepherd
16
16
  'aws_secret_key' => 'aws-secret-key',
17
17
  'region' => 'aws-region',
18
18
  'json_file' => 'cloudformation.json',
19
+ 'update_existing' => false,
19
20
  'parameters' => {
20
21
  'key_pair_name' => 'key_pair_name'
21
22
  },
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vm_shepherd
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ops Manager Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-29 00:00:00.000000000 Z
11
+ date: 2016-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-v1