cloud-mu 3.2.0 → 3.5.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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/ansible/roles/mu-nat/tasks/main.yml +3 -0
  4. data/bin/mu-adopt +12 -1
  5. data/bin/mu-aws-setup +41 -7
  6. data/bin/mu-azure-setup +34 -0
  7. data/bin/mu-configure +214 -119
  8. data/bin/mu-gcp-setup +37 -2
  9. data/bin/mu-load-config.rb +2 -1
  10. data/bin/mu-node-manage +3 -0
  11. data/bin/mu-refresh-ssl +67 -0
  12. data/bin/mu-run-tests +28 -6
  13. data/bin/mu-self-update +30 -10
  14. data/bin/mu-upload-chef-artifacts +30 -26
  15. data/cloud-mu.gemspec +10 -8
  16. data/cookbooks/mu-master/attributes/default.rb +5 -1
  17. data/cookbooks/mu-master/metadata.rb +2 -2
  18. data/cookbooks/mu-master/recipes/default.rb +81 -26
  19. data/cookbooks/mu-master/recipes/init.rb +197 -62
  20. data/cookbooks/mu-master/recipes/update_nagios_only.rb +1 -1
  21. data/cookbooks/mu-master/recipes/vault.rb +78 -77
  22. data/cookbooks/mu-master/templates/default/mods/rewrite.conf.erb +1 -0
  23. data/cookbooks/mu-master/templates/default/nagios.conf.erb +103 -0
  24. data/cookbooks/mu-master/templates/default/web_app.conf.erb +14 -30
  25. data/cookbooks/mu-tools/attributes/default.rb +12 -0
  26. data/cookbooks/mu-tools/files/centos-6/CentOS-Base.repo +47 -0
  27. data/cookbooks/mu-tools/libraries/helper.rb +98 -4
  28. data/cookbooks/mu-tools/libraries/monkey.rb +1 -1
  29. data/cookbooks/mu-tools/recipes/apply_security.rb +31 -9
  30. data/cookbooks/mu-tools/recipes/aws_api.rb +8 -2
  31. data/cookbooks/mu-tools/recipes/base_repositories.rb +1 -1
  32. data/cookbooks/mu-tools/recipes/gcloud.rb +2 -9
  33. data/cookbooks/mu-tools/recipes/google_api.rb +7 -0
  34. data/cookbooks/mu-tools/recipes/rsyslog.rb +8 -1
  35. data/cookbooks/mu-tools/resources/disk.rb +113 -42
  36. data/cookbooks/mu-tools/resources/mommacat_request.rb +1 -2
  37. data/cookbooks/mu-tools/templates/centos-8/sshd_config.erb +215 -0
  38. data/extras/Gemfile.lock.bootstrap +394 -0
  39. data/extras/bucketstubs/error.html +0 -0
  40. data/extras/bucketstubs/index.html +0 -0
  41. data/extras/clean-stock-amis +11 -3
  42. data/extras/generate-stock-images +6 -3
  43. data/extras/git_rpm/build.sh +20 -0
  44. data/extras/git_rpm/mugit.spec +53 -0
  45. data/extras/image-generators/AWS/centos7.yaml +19 -16
  46. data/extras/image-generators/AWS/{rhel7.yaml → rhel71.yaml} +0 -0
  47. data/extras/image-generators/AWS/{win2k12.yaml → win2k12r2.yaml} +0 -0
  48. data/extras/image-generators/VMWare/centos8.yaml +15 -0
  49. data/extras/openssl_rpm/build.sh +19 -0
  50. data/extras/openssl_rpm/mussl.spec +46 -0
  51. data/extras/python_rpm/muthon.spec +14 -4
  52. data/extras/ruby_rpm/muby.spec +9 -5
  53. data/extras/sqlite_rpm/build.sh +19 -0
  54. data/extras/sqlite_rpm/muqlite.spec +47 -0
  55. data/install/installer +7 -5
  56. data/modules/mommacat.ru +2 -2
  57. data/modules/mu.rb +14 -7
  58. data/modules/mu/adoption.rb +5 -5
  59. data/modules/mu/cleanup.rb +47 -25
  60. data/modules/mu/cloud.rb +29 -1
  61. data/modules/mu/cloud/dnszone.rb +0 -2
  62. data/modules/mu/cloud/machine_images.rb +1 -1
  63. data/modules/mu/cloud/providers.rb +6 -1
  64. data/modules/mu/cloud/resource_base.rb +16 -7
  65. data/modules/mu/cloud/ssh_sessions.rb +5 -1
  66. data/modules/mu/cloud/wrappers.rb +20 -7
  67. data/modules/mu/config.rb +28 -12
  68. data/modules/mu/config/bucket.rb +31 -2
  69. data/modules/mu/config/cache_cluster.rb +1 -1
  70. data/modules/mu/config/cdn.rb +100 -0
  71. data/modules/mu/config/container_cluster.rb +1 -1
  72. data/modules/mu/config/database.rb +3 -3
  73. data/modules/mu/config/dnszone.rb +4 -3
  74. data/modules/mu/config/endpoint.rb +1 -0
  75. data/modules/mu/config/firewall_rule.rb +1 -1
  76. data/modules/mu/config/function.rb +16 -7
  77. data/modules/mu/config/job.rb +89 -0
  78. data/modules/mu/config/notifier.rb +7 -18
  79. data/modules/mu/config/ref.rb +55 -9
  80. data/modules/mu/config/schema_helpers.rb +12 -3
  81. data/modules/mu/config/server.rb +11 -5
  82. data/modules/mu/config/server_pool.rb +2 -2
  83. data/modules/mu/config/vpc.rb +11 -10
  84. data/modules/mu/defaults/AWS.yaml +106 -106
  85. data/modules/mu/deploy.rb +40 -14
  86. data/modules/mu/groomers/chef.rb +2 -2
  87. data/modules/mu/master.rb +70 -3
  88. data/modules/mu/mommacat.rb +28 -9
  89. data/modules/mu/mommacat/daemon.rb +13 -7
  90. data/modules/mu/mommacat/naming.rb +2 -2
  91. data/modules/mu/mommacat/search.rb +16 -5
  92. data/modules/mu/mommacat/storage.rb +67 -32
  93. data/modules/mu/providers/aws.rb +298 -85
  94. data/modules/mu/providers/aws/alarm.rb +5 -5
  95. data/modules/mu/providers/aws/bucket.rb +284 -50
  96. data/modules/mu/providers/aws/cache_cluster.rb +26 -26
  97. data/modules/mu/providers/aws/cdn.rb +782 -0
  98. data/modules/mu/providers/aws/collection.rb +16 -16
  99. data/modules/mu/providers/aws/container_cluster.rb +84 -64
  100. data/modules/mu/providers/aws/database.rb +59 -55
  101. data/modules/mu/providers/aws/dnszone.rb +29 -12
  102. data/modules/mu/providers/aws/endpoint.rb +535 -50
  103. data/modules/mu/providers/aws/firewall_rule.rb +32 -26
  104. data/modules/mu/providers/aws/folder.rb +1 -1
  105. data/modules/mu/providers/aws/function.rb +300 -134
  106. data/modules/mu/providers/aws/group.rb +16 -14
  107. data/modules/mu/providers/aws/habitat.rb +4 -4
  108. data/modules/mu/providers/aws/job.rb +469 -0
  109. data/modules/mu/providers/aws/loadbalancer.rb +67 -45
  110. data/modules/mu/providers/aws/log.rb +17 -17
  111. data/modules/mu/providers/aws/msg_queue.rb +22 -13
  112. data/modules/mu/providers/aws/nosqldb.rb +99 -8
  113. data/modules/mu/providers/aws/notifier.rb +137 -65
  114. data/modules/mu/providers/aws/role.rb +119 -83
  115. data/modules/mu/providers/aws/search_domain.rb +166 -30
  116. data/modules/mu/providers/aws/server.rb +209 -118
  117. data/modules/mu/providers/aws/server_pool.rb +95 -130
  118. data/modules/mu/providers/aws/storage_pool.rb +19 -11
  119. data/modules/mu/providers/aws/user.rb +5 -5
  120. data/modules/mu/providers/aws/userdata/linux.erb +5 -4
  121. data/modules/mu/providers/aws/vpc.rb +109 -54
  122. data/modules/mu/providers/aws/vpc_subnet.rb +43 -39
  123. data/modules/mu/providers/azure.rb +78 -12
  124. data/modules/mu/providers/azure/server.rb +20 -4
  125. data/modules/mu/providers/cloudformation/server.rb +1 -1
  126. data/modules/mu/providers/google.rb +21 -5
  127. data/modules/mu/providers/google/bucket.rb +1 -1
  128. data/modules/mu/providers/google/container_cluster.rb +1 -1
  129. data/modules/mu/providers/google/database.rb +1 -1
  130. data/modules/mu/providers/google/firewall_rule.rb +1 -1
  131. data/modules/mu/providers/google/folder.rb +7 -3
  132. data/modules/mu/providers/google/function.rb +66 -31
  133. data/modules/mu/providers/google/group.rb +1 -1
  134. data/modules/mu/providers/google/habitat.rb +1 -1
  135. data/modules/mu/providers/google/loadbalancer.rb +1 -1
  136. data/modules/mu/providers/google/role.rb +6 -3
  137. data/modules/mu/providers/google/server.rb +1 -1
  138. data/modules/mu/providers/google/server_pool.rb +1 -1
  139. data/modules/mu/providers/google/user.rb +1 -1
  140. data/modules/mu/providers/google/vpc.rb +28 -3
  141. data/modules/tests/aws-jobs-functions.yaml +46 -0
  142. data/modules/tests/aws-servers-with-handrolled-iam.yaml +37 -0
  143. data/modules/tests/centos6.yaml +4 -0
  144. data/modules/tests/centos7.yaml +4 -0
  145. data/modules/tests/ecs.yaml +2 -2
  146. data/modules/tests/eks.yaml +1 -1
  147. data/modules/tests/functions/node-function/lambda_function.js +10 -0
  148. data/modules/tests/functions/python-function/lambda_function.py +12 -0
  149. data/modules/tests/k8s.yaml +1 -1
  150. data/modules/tests/microservice_app.yaml +288 -0
  151. data/modules/tests/rds.yaml +5 -5
  152. data/modules/tests/regrooms/rds.yaml +5 -5
  153. data/modules/tests/server-with-scrub-muisms.yaml +1 -1
  154. data/modules/tests/super_complex_bok.yml +2 -2
  155. data/modules/tests/super_simple_bok.yml +2 -2
  156. metadata +42 -17
@@ -27,7 +27,7 @@ module MU
27
27
 
28
28
  # Called automatically by {MU::Deploy#createResources}
29
29
  def create
30
- MU.setVar("curRegion", @config['region']) if !@config['region'].nil?
30
+ MU.setVar("curRegion", @region) if !@region.nil?
31
31
 
32
32
  createUpdateLaunchConfig
33
33
 
@@ -37,7 +37,7 @@ module MU
37
37
 
38
38
  zones_to_try = @config["zones"]
39
39
  begin
40
- asg = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_auto_scaling_group(asg_options)
40
+ asg = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).create_auto_scaling_group(asg_options)
41
41
  rescue Aws::AutoScaling::Errors::ValidationError => e
42
42
  if zones_to_try != nil and zones_to_try.size > 0
43
43
  MU.log "#{e.message}, retrying with individual AZs", MU::WARN
@@ -52,7 +52,7 @@ module MU
52
52
  if zones_to_try != nil and zones_to_try.size < @config["zones"].size
53
53
  zones_to_try.each { |zone|
54
54
  begin
55
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
55
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).update_auto_scaling_group(
56
56
  auto_scaling_group_name: @mu_name,
57
57
  availability_zones: [zone]
58
58
  )
@@ -70,11 +70,11 @@ module MU
70
70
  attempts = 0
71
71
  begin
72
72
  sleep 5
73
- desc = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
73
+ desc = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
74
74
  MU.log "Looking for #{desc.min_size} instances in #{@mu_name}, found #{desc.instances.size}", MU::DEBUG
75
75
  attempts = attempts + 1
76
76
  if attempts > 25 and desc.instances.size == 0
77
- MU.log "No instances spun up after #{5*attempts} seconds, something's wrong with Autoscale group #{@mu_name}", MU::ERR, details: MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_scaling_activities(auto_scaling_group_name: @mu_name).activities
77
+ MU.log "No instances spun up after #{5*attempts} seconds, something's wrong with Autoscale group #{@mu_name}", MU::ERR, details: MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_scaling_activities(auto_scaling_group_name: @mu_name).activities
78
78
  raise MuError, "No instances spun up after #{5*attempts} seconds, something's wrong with Autoscale group #{@mu_name}"
79
79
  end
80
80
  end while desc.instances.size < desc.min_size
@@ -131,7 +131,7 @@ module MU
131
131
  t.join
132
132
  }
133
133
  MU.log "Setting min_size to #{@config['min_size']} and max_size to #{@config['max_size']}"
134
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
134
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).update_auto_scaling_group(
135
135
  auto_scaling_group_name: @mu_name,
136
136
  min_size: @config['min_size'],
137
137
  max_size: @config['max_size']
@@ -151,7 +151,7 @@ module MU
151
151
  def setScaleInProtection(need_instances = @config['min_size'])
152
152
  live_instances = []
153
153
  begin
154
- desc = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
154
+ desc = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
155
155
 
156
156
  live_instances = desc.instances.map { |i| i.instance_id }
157
157
  already_set = 0
@@ -163,7 +163,7 @@ module MU
163
163
  elsif already_set > need_instances
164
164
  unset_me = live_instances.sample(already_set - need_instances)
165
165
  MU.log "Disabling scale-in protection for #{unset_me.size.to_s} instances in #{@mu_name}", MU::NOTICE, details: unset_me
166
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).set_instance_protection(
166
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).set_instance_protection(
167
167
  auto_scaling_group_name: @mu_name,
168
168
  instance_ids: unset_me,
169
169
  protected_from_scale_in: false
@@ -172,7 +172,7 @@ module MU
172
172
  live_instances = live_instances.sample(need_instances)
173
173
  MU.log "Enabling scale-in protection for #{@config['scale_in_protection']} instances in #{@mu_name}", details: live_instances
174
174
  begin
175
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).set_instance_protection(
175
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).set_instance_protection(
176
176
  auto_scaling_group_name: @mu_name,
177
177
  instance_ids: live_instances,
178
178
  protected_from_scale_in: true
@@ -193,10 +193,10 @@ module MU
193
193
  # @return [Array<MU::Cloud::Server>]
194
194
  def listNodes
195
195
  nodes = []
196
- me = MU::Cloud::AWS::ServerPool.find(cloud_id: cloud_id)
197
- if me and me.first and me.first.instances
198
- me.first.instances.each { |instance|
199
- found = MU::MommaCat.findStray("AWS", "server", cloud_id: instance.instance_id, region: @config["region"], dummy_ok: true)
196
+ me = MU::Cloud::AWS::ServerPool.find(cloud_id: cloud_id).values.first
197
+ if me and me.instances
198
+ me.instances.each { |instance|
199
+ found = MU::MommaCat.findStray("AWS", "server", cloud_id: instance.instance_id, region: @region, dummy_ok: true)
200
200
  nodes.concat(found)
201
201
  }
202
202
  end
@@ -210,7 +210,7 @@ module MU
210
210
  arn = if @config['notifications']['topic'].match(/^arn:/)
211
211
  @config['notifications']['topic']
212
212
  else
213
- "arn:#{MU::Cloud::AWS.isGovCloud?(@config['region']) ? "aws-us-gov" : "aws"}:sns:#{@config['region']}:#{MU::Cloud::AWS.credToAcct(@config['credentials'])}:#{@config['notifications']['topic']}"
213
+ "arn:#{MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws"}:sns:#{@region}:#{MU::Cloud::AWS.credToAcct(@credentials)}:#{@config['notifications']['topic']}"
214
214
  end
215
215
  eventmap = {
216
216
  "launch" => "autoscaling:EC2_INSTANCE_LAUNCH",
@@ -219,7 +219,7 @@ module MU
219
219
  "failed_terminate" => "autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
220
220
  }
221
221
  MU.log "Sending simple notifications (#{@config['notifications']['events'].join(", ")}) to #{arn}"
222
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_notification_configuration(
222
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).put_notification_configuration(
223
223
  auto_scaling_group_name: @mu_name,
224
224
  topic_arn: arn,
225
225
  notification_types: @config['notifications']['events'].map { |e|
@@ -229,7 +229,7 @@ module MU
229
229
  end
230
230
 
231
231
  if @config['schedule']
232
- ext_actions = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_scheduled_actions(
232
+ ext_actions = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_scheduled_actions(
233
233
  auto_scaling_group_name: @mu_name
234
234
  ).scheduled_update_group_actions
235
235
 
@@ -250,7 +250,7 @@ module MU
250
250
  if s['action_name'] == ext.scheduled_action_name
251
251
  if !MU.hashCmp(MU.structToHash(ext), sched_config, missing_is_default: true)
252
252
  MU.log "Removing scheduled action #{s['action_name']} from AutoScale group #{@mu_name}"
253
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_scheduled_action(
253
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).delete_scheduled_action(
254
254
  auto_scaling_group_name: @mu_name,
255
255
  scheduled_action_name: s['action_name']
256
256
  )
@@ -262,7 +262,7 @@ module MU
262
262
  }
263
263
  if !action_already_correct
264
264
  MU.log "Adding scheduled action to AutoScale group #{@mu_name}", MU::NOTICE, details: sched_config
265
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_scheduled_update_group_action(
265
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).put_scheduled_update_group_action(
266
266
  sched_config
267
267
  )
268
268
  end
@@ -290,30 +290,29 @@ module MU
290
290
  if need_tag_update
291
291
  MU.log "Updating ServerPool #{@mu_name} with new tags", MU::NOTICE, details: tag_conf[:tags]
292
292
 
293
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_or_update_tags(tag_conf)
293
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).create_or_update_tags(tag_conf)
294
294
  current.instances.each { |instance|
295
295
  tag_conf[:tags].each { |t|
296
- MU::Cloud::AWS.createTag(instance.instance_id, t[:key], t[:value], region: @config['region'], credentials: @config['credentials'])
296
+ MU::Cloud::AWS.createTag(instance.instance_id, t[:key], t[:value], region: @region, credentials: @credentials)
297
297
  }
298
298
  }
299
299
  end
300
300
 
301
301
  # XXX actually compare for changes instead of just blindly updating
302
- #pp current
303
- #pp asg_options
302
+
304
303
  asg_options.delete(:tags)
305
304
  asg_options[:min_size] = @config["min_size"]
306
305
  asg_options[:max_size] = @config["max_size"]
307
306
  asg_options[:new_instances_protected_from_scale_in] = (@config['scale_in_protection'] == "all")
308
307
  if asg_options[:target_group_arns]
309
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).attach_load_balancer_target_groups(
308
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).attach_load_balancer_target_groups(
310
309
  auto_scaling_group_name: @mu_name,
311
310
  target_group_arns: asg_options[:target_group_arns]
312
311
  )
313
312
  asg_options.delete(:target_group_arns)
314
313
  end
315
314
 
316
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(asg_options)
315
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).update_auto_scaling_group(asg_options)
317
316
 
318
317
  if @config['scale_in_protection']
319
318
  if @config['scale_in_protection'] == "all"
@@ -327,7 +326,7 @@ module MU
327
326
  setScaleInProtection(0)
328
327
  end
329
328
 
330
- ext_pols = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_policies(
329
+ ext_pols = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_policies(
331
330
  auto_scaling_group_name: @mu_name
332
331
  ).scaling_policies
333
332
  if @config["scaling_policies"] and @config["scaling_policies"].size > 0
@@ -339,7 +338,7 @@ module MU
339
338
  ext_pols.each { |ext|
340
339
  if !legit_policies.include?(ext.policy_name)
341
340
  MU.log "Scaling policy #{ext.policy_name} is not named in scaling_policies, removing from #{@mu_name}", MU::NOTICE, details: ext
342
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_policy(
341
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).delete_policy(
343
342
  auto_scaling_group_name: @mu_name,
344
343
  policy_name: ext.policy_name
345
344
  )
@@ -400,7 +399,7 @@ module MU
400
399
  ext_pols.each { |ext|
401
400
  if ext.policy_name == policy_name
402
401
  if !MU.hashCmp(MU.structToHash(ext), policy_params, missing_is_default: true)
403
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_policy(
402
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).delete_policy(
404
403
  auto_scaling_group_name: @mu_name,
405
404
  policy_name: policy_name
406
405
  )
@@ -412,7 +411,7 @@ module MU
412
411
  }
413
412
  if !policy_already_correct
414
413
  MU.log "Putting scaling policy #{policy_name} for #{@mu_name}", MU::NOTICE, details: policy_params
415
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_scaling_policy(policy_params)
414
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).put_scaling_policy(policy_params)
416
415
  end
417
416
 
418
417
  }
@@ -425,7 +424,8 @@ module MU
425
424
  # @return [OpenStruct]
426
425
  def cloud_desc(use_cache: true)
427
426
  return @cloud_desc_cache if @cloud_desc_cache and use_cache
428
- @cloud_desc_cache = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(
427
+ return nil if !@cloud_id
428
+ @cloud_desc_cache = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_auto_scaling_groups(
429
429
  auto_scaling_group_names: [@mu_name]
430
430
  ).auto_scaling_groups.first
431
431
  @cloud_desc_cache
@@ -489,9 +489,9 @@ module MU
489
489
  def toKitten(**_args)
490
490
  bok = {
491
491
  "cloud" => "AWS",
492
- "credentials" => @config['credentials'],
492
+ "credentials" => @credentials,
493
493
  "cloud_id" => @cloud_id,
494
- "region" => @config['region']
494
+ "region" => @region
495
495
  }
496
496
 
497
497
  if !cloud_desc
@@ -516,7 +516,7 @@ module MU
516
516
  bok['max_size'] = cloud_desc.max_size
517
517
 
518
518
  if cloud_desc.launch_configuration_name
519
- launch = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @credentials).describe_launch_configurations(
519
+ launch = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_launch_configurations(
520
520
  launch_configuration_names: [cloud_desc.launch_configuration_name]
521
521
  ).launch_configurations.first
522
522
  bok['basis'] = {
@@ -531,14 +531,25 @@ module MU
531
531
  if cloud_desc.vpc_zone_identifier and
532
532
  !cloud_desc.vpc_zone_identifier.empty?
533
533
  nets = cloud_desc.vpc_zone_identifier.split(/,/)
534
- resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_subnets(subnet_ids: nets).subnets.first
535
- bok['vpc'] = MU::Config::Ref.get(
536
- id: resp.vpc_id,
537
- cloud: "AWS",
538
- credentials: @credentials,
539
- type: "vpcs",
540
- subnets: nets.map { |s| { "subnet_id" => s } }
541
- )
534
+ begin
535
+ resp = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_subnets(subnet_ids: nets).subnets.first
536
+ bok['vpc'] = MU::Config::Ref.get(
537
+ id: resp.vpc_id,
538
+ cloud: "AWS",
539
+ credentials: @credentials,
540
+ type: "vpcs",
541
+ subnets: nets.map { |s| { "subnet_id" => s } }
542
+ )
543
+ rescue Aws::EC2::Errors::InvalidSubnetIDNotFound => e
544
+ if e.message.match(/The subnet ID '(subnet-[a-f0-9]+)' does not exist/)
545
+ nets.delete(Regexp.last_match[1])
546
+ if nets.empty?
547
+ MU.log "Autoscale Group #{@cloud_id} was configured for a VPC, but the configuration held no valid subnets", MU::WARN, details: cloud_desc.vpc_zone_identifier.split(/,/)
548
+ end
549
+ else
550
+ raise e
551
+ end
552
+ end
542
553
  end
543
554
 
544
555
  # MU.log @cloud_id, MU::NOTICE, details: cloud_desc
@@ -897,41 +908,13 @@ module MU
897
908
  MU.log "Cannot mix iam_policies with generate_iam_role set to false", MU::ERR
898
909
  ok = false
899
910
  end
900
- else
901
- s3_objs = ['arn:'+(MU::Cloud::AWS.isGovCloud?(pool['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU::Cloud::AWS.adminBucketName(pool['credentials'])+'/Mu_CA.pem']
902
-
903
- role = {
904
- "name" => pool["name"],
905
- "cloud" => "AWS",
906
- "strip_path" => pool["role_strip_path"],
907
- "can_assume" => [
908
- {
909
- "entity_id" => "ec2.amazonaws.com",
910
- "entity_type" => "service"
911
- }
912
- ],
913
- "policies" => [
914
- {
915
- "name" => "MuSecrets",
916
- "permissions" => ["s3:GetObject"],
917
- "targets" => s3_objs.map { |f| { "identifier" => f } }
918
- }
919
- ]
920
- }
921
- if launch['iam_policies']
922
- role['iam_policies'] = launch['iam_policies'].dup
923
- end
924
- if pool['canned_iam_policies']
925
- role['import'] = pool['canned_iam_policies'].dup
926
- end
927
- if pool['iam_role']
928
- # XXX maybe break this down into policies and add those?
929
- end
930
-
931
- role['credentials'] = pool['credentials'] if pool['credentials']
932
- configurator.insertKitten(role, "roles")
933
- MU::Config.addDependency(pool, pool['name'], "role")
934
911
  end
912
+
913
+ ["generate_iam_role", "iam_role", "canned_iam_policies", "iam_policies"].each { |key|
914
+ pool[key] = launch[key] if !launch[key].nil?
915
+ }
916
+ MU::Cloud.resourceClass("AWS", "Server").generateStandardRole(pool, configurator)
917
+
935
918
  launch["ami_id"] ||= launch["image_id"]
936
919
  if launch["server"].nil? and launch["instance_id"].nil? and launch["ami_id"].nil?
937
920
  img_id = MU::Cloud.getStockImage("AWS", platform: pool['platform'], region: pool['region'])
@@ -944,7 +927,7 @@ module MU
944
927
  end
945
928
  end
946
929
  if launch["server"] != nil
947
- MU::Config.addDependency(pool, launch["server"], "server", phase: "groom")
930
+ MU::Config.addDependency(pool, launch["server"], "server", their_phase: "groom")
948
931
  # XXX I dunno, maybe toss an error if this isn't done already
949
932
  # servers.each { |server|
950
933
  # if server["name"] == launch["server"]
@@ -1050,7 +1033,7 @@ module MU
1050
1033
  # @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
1051
1034
  # @param region [String]: The cloud provider region
1052
1035
  # @return [void]
1053
- def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
1036
+ def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
1054
1037
  MU.log "AWS::ServerPool.cleanup: need to support flags['known']", MU::DEBUG, details: flags
1055
1038
 
1056
1039
  filters = [{name: "key", values: ["MU-ID"]}]
@@ -1073,7 +1056,7 @@ module MU
1073
1056
  if asg.key == "MU-MASTER-IP" and asg.value != MU.mu_public_ip and !ignoremaster
1074
1057
  no_purge << asg.resource_id
1075
1058
  end
1076
- if asg.key == "MU-ID" and asg.value == MU.deploy_id
1059
+ if asg.key == "MU-ID" and asg.value == deploy_id
1077
1060
  maybe_purge << asg.resource_id
1078
1061
  end
1079
1062
  }
@@ -1144,20 +1127,20 @@ module MU
1144
1127
  @config['basis']['launch_config']["ami_id"] = MU::Cloud.resourceClass("AWS", "Server").createImage(
1145
1128
  name: @mu_name,
1146
1129
  instance_id: @config['basis']['launch_config']["instance_id"],
1147
- credentials: @config['credentials'],
1148
- region: @config['region']
1149
- )[@config['region']]
1130
+ credentials: @credentials,
1131
+ region: @region
1132
+ )[@region]
1150
1133
  end
1151
- MU::Cloud.resourceClass("AWS", "Server").waitForAMI(@config['basis']['launch_config']["ami_id"], credentials: @config['credentials'])
1134
+ MU::Cloud.resourceClass("AWS", "Server").waitForAMI(@config['basis']['launch_config']["ami_id"].to_s, credentials: @credentials)
1152
1135
 
1153
- oldlaunch = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_launch_configurations(
1136
+ oldlaunch = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_launch_configurations(
1154
1137
  launch_configuration_names: [@mu_name]
1155
1138
  ).launch_configurations.first
1156
1139
 
1157
1140
  userdata = MU::Cloud.fetchUserdata(
1158
1141
  platform: @config["platform"],
1159
1142
  cloud: "AWS",
1160
- credentials: @config['credentials'],
1143
+ credentials: @credentials,
1161
1144
  template_variables: {
1162
1145
  "deployKey" => Base64.urlsafe_encode64(@deploy.public_key),
1163
1146
  "deploySSHKey" => @deploy.ssh_public_key,
@@ -1210,16 +1193,6 @@ module MU
1210
1193
 
1211
1194
  storage.concat(MU::Cloud.resourceClass("AWS", "Server").ephemeral_mappings)
1212
1195
 
1213
- if @config['basis']['launch_config']['generate_iam_role']
1214
- role = @deploy.findLitterMate(name: @config['name'], type: "roles")
1215
- if role
1216
- s3_objs = ["#{@deploy.deploy_id}-secret", "#{role.mu_name}.pfx", "#{role.mu_name}.crt", "#{role.mu_name}.key", "#{role.mu_name}-winrm.crt", "#{role.mu_name}-winrm.key"].map { |file|
1217
- 'arn:'+(MU::Cloud::AWS.isGovCloud?(@config['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU::Cloud::AWS.adminBucketName(@credentials)+'/'+file
1218
- }
1219
- role.cloudobj.injectPolicyTargets("MuSecrets", s3_objs)
1220
- end
1221
- end
1222
-
1223
1196
  if !oldlaunch.nil?
1224
1197
  olduserdata = Base64.decode64(oldlaunch.user_data)
1225
1198
  if userdata == olduserdata and
@@ -1236,7 +1209,7 @@ module MU
1236
1209
  # Put our Autoscale group onto a temporary launch config
1237
1210
  begin
1238
1211
 
1239
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_launch_configuration(
1212
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).create_launch_configuration(
1240
1213
  launch_configuration_name: @mu_name+"-TMP",
1241
1214
  user_data: Base64.encode64(olduserdata),
1242
1215
  image_id: oldlaunch.image_id,
@@ -1259,12 +1232,12 @@ module MU
1259
1232
  end
1260
1233
 
1261
1234
 
1262
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
1235
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).update_auto_scaling_group(
1263
1236
  auto_scaling_group_name: @mu_name,
1264
1237
  launch_configuration_name: @mu_name+"-TMP"
1265
1238
  )
1266
1239
  # ...now back to an identical one with the "real" name
1267
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_launch_configuration(
1240
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).delete_launch_configuration(
1268
1241
  launch_configuration_name: @mu_name
1269
1242
  )
1270
1243
  end
@@ -1297,30 +1270,30 @@ module MU
1297
1270
  end
1298
1271
  }
1299
1272
  rolename = nil
1273
+
1300
1274
  ['generate_iam_role', 'iam_policies', 'canned_iam_policies', 'iam_role'].each { |field|
1301
- @config['basis']['launch_config'][field] ||= @config[field]
1275
+ if !@config['basis']['launch_config'].nil?
1276
+ @config[field] = @config['basis']['launch_config'][field]
1277
+ else
1278
+ @config['basis']['launch_config'][field] = @config[field]
1279
+ end
1302
1280
  }
1303
1281
 
1304
- if @config['basis']['launch_config']['generate_iam_role']
1305
- role = @deploy.findLitterMate(name: @config['name'], type: "roles")
1306
-
1307
- @config['iam_role'] = role.mu_name
1308
-
1309
- launch_options[:iam_instance_profile] = role.cloudobj.createInstanceProfile
1310
- elsif @config['basis']['launch_config']['iam_role'].nil?
1311
- raise MuError, "#{@mu_name} has generate_iam_role set to false, but no iam_role assigned."
1312
- else
1313
- launch_options[:iam_instance_profile] = @config['basis']['launch_config']['iam_role']
1314
- end
1315
-
1316
- @config['iam_role'] = rolename ? rolename : launch_options[:iam_instance_profile]
1282
+ @config['iam_role'] = @config['basis']['launch_config']['iam_role'] = launch_options[:iam_instance_profile] = MU::Cloud.resourceClass("AWS", "Server").getIAMProfile(
1283
+ @config['name'],
1284
+ @deploy,
1285
+ generated: @config['basis']['launch_config']['generate_iam_role'],
1286
+ role_name: @config['basis']['launch_config']['iam_role'],
1287
+ region: @region,
1288
+ credentials: @credentials
1289
+ ).values.first
1317
1290
 
1318
1291
  lc_attempts = 0
1319
1292
  begin
1320
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_launch_configuration(launch_options)
1293
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).create_launch_configuration(launch_options)
1321
1294
  rescue Aws::AutoScaling::Errors::ValidationError => e
1322
1295
  if lc_attempts > 3
1323
- MU.log "Got error while creating #{@mu_name} Launch Config#{@config['credentials'] ? " with credentials #{@config['credentials']}" : ""}: #{e.message}, retrying in 10s", MU::WARN, details: launch_options.reject { |k,_v | k == :user_data }
1296
+ MU.log "Got error while creating #{@mu_name} Launch Config#{@credentials ? " with credentials #{@credentials}" : ""}: #{e.message}, retrying in 10s", MU::WARN, details: launch_options.reject { |k,_v | k == :user_data }
1324
1297
  end
1325
1298
  sleep 5
1326
1299
  lc_attempts += 1
@@ -1329,11 +1302,11 @@ module MU
1329
1302
 
1330
1303
  if !oldlaunch.nil?
1331
1304
  # Tell the ASG to use the new one, and nuke the old one
1332
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
1305
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).update_auto_scaling_group(
1333
1306
  auto_scaling_group_name: @mu_name,
1334
1307
  launch_configuration_name: @mu_name
1335
1308
  )
1336
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_launch_configuration(
1309
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).delete_launch_configuration(
1337
1310
  launch_configuration_name: @mu_name+"-TMP"
1338
1311
  )
1339
1312
  MU.log "Launch Configuration #{@mu_name} replaced"
@@ -1403,20 +1376,12 @@ module MU
1403
1376
  # XXX probably have to query API to get the DNS name of this one
1404
1377
  }
1405
1378
  elsif lb["concurrent_load_balancer"]
1406
- raise MuError, "No loadbalancers exist! I need one named #{lb['concurrent_load_balancer']}" if !@deploy.deployment["loadbalancers"]
1407
- found = false
1408
- @deploy.deployment["loadbalancers"].each_pair { |lb_name, deployed_lb|
1409
- if lb_name == lb['concurrent_load_balancer']
1410
- lbs << deployed_lb["awsname"] # XXX check for classic
1411
- if deployed_lb.has_key?("targetgroups")
1412
- deployed_lb["targetgroups"].values.each { |tg_arn|
1413
- tg_arns << tg_arn
1414
- }
1415
- end
1416
- found = true
1417
- end
1418
- }
1419
- raise MuError, "I need a loadbalancer named #{lb['concurrent_load_balancer']}, but none seems to have been created!" if !found
1379
+ lb = @deploy.findLitterMate(name: lb['concurrent_load_balancer'], type: "loadbalancers")
1380
+ raise MuError, "No loadbalancers exist! I need one named #{lb['concurrent_load_balancer']}" if !lb
1381
+ lbs << lb.mu_name
1382
+ if lb.targetgroups
1383
+ tg_arns = lb.targetgroups.values.map { |tg| tg.target_group_arn }
1384
+ end
1420
1385
  end
1421
1386
  }
1422
1387
  if tg_arns.size > 0
@@ -1481,8 +1446,8 @@ module MU
1481
1446
  # Do the dance of specifying individual zones if we haven't asked to
1482
1447
  # use particular VPC subnets.
1483
1448
  if @config['zones'].nil? and asg_options[:vpc_zone_identifier].nil?
1484
- @config["zones"] = MU::Cloud::AWS.listAZs(region: @config['region'])
1485
- MU.log "Using zones from #{@config['region']}", MU::DEBUG, details: @config['zones']
1449
+ @config["zones"] = MU::Cloud::AWS.listAZs(region: @region)
1450
+ MU.log "Using zones from #{@region}", MU::DEBUG, details: @config['zones']
1486
1451
  end
1487
1452
  asg_options[:availability_zones] = @config["zones"] if @config["zones"] != nil
1488
1453
  asg_options