cloud-mu 3.4.0 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/ansible/roles/mu-nat/tasks/main.yml +3 -0
  3. data/bin/mu-aws-setup +41 -7
  4. data/bin/mu-azure-setup +34 -0
  5. data/bin/mu-configure +214 -119
  6. data/bin/mu-gcp-setup +37 -2
  7. data/bin/mu-node-manage +3 -0
  8. data/bin/mu-refresh-ssl +67 -0
  9. data/bin/mu-run-tests +14 -4
  10. data/bin/mu-self-update +30 -10
  11. data/bin/mu-upload-chef-artifacts +30 -26
  12. data/cloud-mu.gemspec +8 -6
  13. data/cookbooks/mu-master/attributes/default.rb +5 -1
  14. data/cookbooks/mu-master/metadata.rb +2 -2
  15. data/cookbooks/mu-master/recipes/default.rb +81 -26
  16. data/cookbooks/mu-master/recipes/init.rb +197 -62
  17. data/cookbooks/mu-master/recipes/update_nagios_only.rb +1 -1
  18. data/cookbooks/mu-master/recipes/vault.rb +78 -77
  19. data/cookbooks/mu-master/templates/default/mods/rewrite.conf.erb +1 -0
  20. data/cookbooks/mu-master/templates/default/nagios.conf.erb +103 -0
  21. data/cookbooks/mu-master/templates/default/web_app.conf.erb +14 -30
  22. data/cookbooks/mu-tools/attributes/default.rb +5 -0
  23. data/cookbooks/mu-tools/files/centos-6/CentOS-Base.repo +47 -0
  24. data/cookbooks/mu-tools/libraries/helper.rb +12 -2
  25. data/cookbooks/mu-tools/libraries/monkey.rb +1 -1
  26. data/cookbooks/mu-tools/recipes/apply_security.rb +6 -0
  27. data/cookbooks/mu-tools/recipes/aws_api.rb +6 -4
  28. data/cookbooks/mu-tools/recipes/base_repositories.rb +1 -1
  29. data/cookbooks/mu-tools/recipes/gcloud.rb +2 -9
  30. data/cookbooks/mu-tools/recipes/google_api.rb +5 -2
  31. data/cookbooks/mu-tools/resources/disk.rb +108 -58
  32. data/extras/Gemfile.lock.bootstrap +394 -0
  33. data/extras/bucketstubs/error.html +0 -0
  34. data/extras/bucketstubs/index.html +0 -0
  35. data/extras/clean-stock-amis +9 -9
  36. data/extras/git_rpm/build.sh +20 -0
  37. data/extras/git_rpm/mugit.spec +53 -0
  38. data/extras/image-generators/VMWare/centos8.yaml +15 -0
  39. data/extras/openssl_rpm/build.sh +19 -0
  40. data/extras/openssl_rpm/mussl.spec +46 -0
  41. data/extras/python_rpm/muthon.spec +14 -4
  42. data/extras/ruby_rpm/muby.spec +9 -5
  43. data/extras/sqlite_rpm/build.sh +19 -0
  44. data/extras/sqlite_rpm/muqlite.spec +47 -0
  45. data/install/installer +7 -5
  46. data/modules/mu.rb +12 -5
  47. data/modules/mu/cloud/machine_images.rb +1 -1
  48. data/modules/mu/cloud/providers.rb +6 -1
  49. data/modules/mu/cloud/resource_base.rb +1 -1
  50. data/modules/mu/cloud/ssh_sessions.rb +4 -0
  51. data/modules/mu/config.rb +28 -12
  52. data/modules/mu/config/database.rb +2 -2
  53. data/modules/mu/config/firewall_rule.rb +1 -1
  54. data/modules/mu/config/ref.rb +2 -2
  55. data/modules/mu/config/schema_helpers.rb +12 -3
  56. data/modules/mu/config/server.rb +10 -4
  57. data/modules/mu/config/server_pool.rb +2 -2
  58. data/modules/mu/config/vpc.rb +10 -10
  59. data/modules/mu/defaults/AWS.yaml +32 -32
  60. data/modules/mu/deploy.rb +23 -10
  61. data/modules/mu/groomers/chef.rb +2 -2
  62. data/modules/mu/master.rb +49 -3
  63. data/modules/mu/mommacat.rb +8 -5
  64. data/modules/mu/mommacat/naming.rb +2 -2
  65. data/modules/mu/mommacat/storage.rb +22 -27
  66. data/modules/mu/providers/aws.rb +142 -48
  67. data/modules/mu/providers/aws/alarm.rb +3 -3
  68. data/modules/mu/providers/aws/bucket.rb +19 -19
  69. data/modules/mu/providers/aws/cache_cluster.rb +22 -22
  70. data/modules/mu/providers/aws/cdn.rb +2 -2
  71. data/modules/mu/providers/aws/collection.rb +14 -14
  72. data/modules/mu/providers/aws/container_cluster.rb +27 -27
  73. data/modules/mu/providers/aws/database.rb +40 -39
  74. data/modules/mu/providers/aws/dnszone.rb +5 -5
  75. data/modules/mu/providers/aws/endpoint.rb +35 -35
  76. data/modules/mu/providers/aws/firewall_rule.rb +26 -23
  77. data/modules/mu/providers/aws/function.rb +28 -28
  78. data/modules/mu/providers/aws/group.rb +7 -7
  79. data/modules/mu/providers/aws/habitat.rb +2 -2
  80. data/modules/mu/providers/aws/job.rb +6 -6
  81. data/modules/mu/providers/aws/loadbalancer.rb +34 -34
  82. data/modules/mu/providers/aws/log.rb +14 -14
  83. data/modules/mu/providers/aws/msg_queue.rb +10 -10
  84. data/modules/mu/providers/aws/nosqldb.rb +8 -8
  85. data/modules/mu/providers/aws/notifier.rb +7 -7
  86. data/modules/mu/providers/aws/role.rb +17 -15
  87. data/modules/mu/providers/aws/search_domain.rb +10 -10
  88. data/modules/mu/providers/aws/server.rb +176 -95
  89. data/modules/mu/providers/aws/server_pool.rb +65 -105
  90. data/modules/mu/providers/aws/storage_pool.rb +17 -9
  91. data/modules/mu/providers/aws/user.rb +1 -1
  92. data/modules/mu/providers/aws/vpc.rb +103 -51
  93. data/modules/mu/providers/aws/vpc_subnet.rb +43 -39
  94. data/modules/mu/providers/azure.rb +78 -12
  95. data/modules/mu/providers/azure/server.rb +18 -3
  96. data/modules/mu/providers/cloudformation/server.rb +1 -1
  97. data/modules/mu/providers/google.rb +19 -4
  98. data/modules/mu/providers/google/folder.rb +6 -2
  99. data/modules/mu/providers/google/function.rb +65 -30
  100. data/modules/mu/providers/google/role.rb +1 -1
  101. data/modules/mu/providers/google/vpc.rb +27 -2
  102. data/modules/tests/aws-servers-with-handrolled-iam.yaml +37 -0
  103. data/modules/tests/k8s.yaml +1 -1
  104. metadata +24 -8
@@ -242,7 +242,7 @@ module MU
242
242
  else
243
243
  MU::Cloud::AWS.createStandardTags(
244
244
  instance.instance_id,
245
- region: @config['region'],
245
+ region: @region,
246
246
  credentials: @credentials,
247
247
  optional: @config['optional_tags'],
248
248
  nametag: @mu_name,
@@ -258,7 +258,7 @@ module MU
258
258
  parent_thread_id = Thread.current.object_id
259
259
  Thread.new {
260
260
  MU.dupGlobals(parent_thread_id)
261
- MU::Cloud::AWS::Server.cleanup(noop: false, ignoremaster: false, region: @config['region'], credentials: @credentials, flags: { "skipsnapshots" => true } )
261
+ MU::Cloud::AWS::Server.cleanup(noop: false, ignoremaster: false, region: @region, credentials: @credentials, flags: { "skipsnapshots" => true } )
262
262
  }
263
263
  end
264
264
  end
@@ -307,9 +307,9 @@ module MU
307
307
  instance_descriptor[:user_data] = Base64.encode64(@userdata)
308
308
  end
309
309
 
310
- MU::Cloud::AWS::Server.waitForAMI(@config["image_id"], region: @config['region'], credentials: @credentials)
310
+ MU::Cloud::AWS::Server.waitForAMI(@config["image_id"], region: @region, credentials: @credentials)
311
311
 
312
- instance_descriptor[:block_device_mappings] = MU::Cloud::AWS::Server.configureBlockDevices(image_id: @config["image_id"], storage: @config['storage'], region: @config['region'], credentials: @credentials)
312
+ instance_descriptor[:block_device_mappings] = MU::Cloud::AWS::Server.configureBlockDevices(image_id: @config["image_id"], storage: @config['storage'], region: @region, credentials: @credentials)
313
313
 
314
314
  instance_descriptor[:monitoring] = {enabled: @config['monitoring']}
315
315
 
@@ -330,10 +330,26 @@ module MU
330
330
  resp.nil? or resp.instances.nil? or instance.nil?
331
331
  }
332
332
 
333
+ bad_subnets = []
334
+ mysubnet_ids = if mySubnets
335
+ mySubnets.map { |s| s.cloud_id }
336
+ end
333
337
  begin
334
338
  MU.retrier([Aws::EC2::Errors::InvalidGroupNotFound, Aws::EC2::Errors::InvalidSubnetIDNotFound, Aws::EC2::Errors::InvalidParameterValue], loop_if: loop_if, loop_msg: "Waiting for run_instances to return #{@mu_name}") {
335
- resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).run_instances(instance_descriptor)
339
+ resp = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).run_instances(instance_descriptor)
336
340
  }
341
+ rescue Aws::EC2::Errors::Unsupported => e
342
+ bad_subnets << instance_descriptor[:subnet_id]
343
+ better_subnet = (mysubnet_ids - bad_subnets).sample
344
+ if e.message !~ /is not supported in your requested Availability Zone/ and
345
+ (mysubnet_ids.nil? or mysubnet_ids.empty? or
346
+ mysubnet_ids.size == bad_subnets.size or
347
+ better_subnet.nil? or better_subnet == "")
348
+ raise MuError.new e.message, details: mysubnet_ids
349
+ end
350
+ instance_descriptor[:subnet_id] = (mysubnet_ids - bad_subnets).sample
351
+ MU.log "One or more subnets does not support this instance type, attempting with #{instance_descriptor[:subnet_id]} instead", MU::WARN, details: bad_subnets
352
+ retry
337
353
  rescue Aws::EC2::Errors::InvalidRequest => e
338
354
  MU.log e.message, MU::ERR, details: instance_descriptor
339
355
  raise e
@@ -351,12 +367,12 @@ module MU
351
367
  if hard
352
368
  groupname = nil
353
369
  if !@config['basis'].nil?
354
- resp = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @credentials).describe_auto_scaling_instances(
370
+ resp = MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_auto_scaling_instances(
355
371
  instance_ids: [@cloud_id]
356
372
  )
357
373
  groupname = resp.auto_scaling_instances.first.auto_scaling_group_name
358
374
  MU.log "Pausing Autoscale processes in #{groupname}", MU::NOTICE
359
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @credentials).suspend_processes(
375
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).suspend_processes(
360
376
  auto_scaling_group_name: groupname,
361
377
  scaling_processes: [
362
378
  "Terminate",
@@ -365,22 +381,22 @@ module MU
365
381
  end
366
382
  begin
367
383
  MU.log "Stopping #{@mu_name} (#{@cloud_id})", MU::NOTICE
368
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).stop_instances(
384
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).stop_instances(
369
385
  instance_ids: [@cloud_id]
370
386
  )
371
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).wait_until(:instance_stopped, instance_ids: [@cloud_id]) do |waiter|
387
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).wait_until(:instance_stopped, instance_ids: [@cloud_id]) do |waiter|
372
388
  waiter.before_attempt do
373
389
  MU.log "Waiting for #{@mu_name} to stop for hard reboot"
374
390
  end
375
391
  end
376
392
  MU.log "Starting #{@mu_name} (#{@cloud_id})"
377
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).start_instances(
393
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).start_instances(
378
394
  instance_ids: [@cloud_id]
379
395
  )
380
396
  ensure
381
397
  if !groupname.nil?
382
398
  MU.log "Resuming Autoscale processes in #{groupname}", MU::NOTICE
383
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @credentials).resume_processes(
399
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).resume_processes(
384
400
  auto_scaling_group_name: groupname,
385
401
  scaling_processes: [
386
402
  "Terminate",
@@ -390,7 +406,7 @@ module MU
390
406
  end
391
407
  else
392
408
  MU.log "Rebooting #{@mu_name} (#{@cloud_id})"
393
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).reboot_instances(
409
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).reboot_instances(
394
410
  instance_ids: [@cloud_id]
395
411
  )
396
412
  end
@@ -405,7 +421,7 @@ module MU
405
421
  return nil if @config.nil? or @deploy.nil?
406
422
 
407
423
  nat_ssh_key = nat_ssh_user = nat_ssh_host = nil
408
- if !@config["vpc"].nil? and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @credentials)
424
+ if !@config["vpc"].nil? and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @region, credentials: @credentials)
409
425
  if !@nat.nil?
410
426
  if @nat.is_a?(Struct) && @nat.nat_gateway_id && @nat.nat_gateway_id.start_with?("nat-")
411
427
  raise MuError, "Configured to use NAT Gateway, but I have no route to instance. Either use Bastion, or configure VPC peering"
@@ -449,6 +465,9 @@ module MU
449
465
  raise MuError, "Couldn't find instance #{@mu_name} (#{@cloud_id})" if !cloud_desc
450
466
  return false if !MU::MommaCat.lock(@cloud_id+"-orchestrate", true)
451
467
  return false if !MU::MommaCat.lock(@cloud_id+"-groom", true)
468
+
469
+ getIAMProfile
470
+
452
471
  finish = Proc.new { |status|
453
472
  MU::MommaCat.unlock(@cloud_id+"-orchestrate")
454
473
  MU::MommaCat.unlock(@cloud_id+"-groom")
@@ -457,7 +476,7 @@ module MU
457
476
 
458
477
  MU::Cloud::AWS.createStandardTags(
459
478
  @cloud_id,
460
- region: @config['region'],
479
+ region: @region,
461
480
  credentials: @credentials,
462
481
  optional: @config['optional_tags'],
463
482
  nametag: @mu_name,
@@ -474,7 +493,15 @@ module MU
474
493
  }
475
494
  MU.retrier([Aws::EC2::Errors::ServiceError], max: 30, wait: 40, loop_if: loop_if) { |retries, _wait|
476
495
  if cloud_desc and cloud_desc.state.name == "terminated"
477
- raise MuError, "#{@cloud_id} appears to have been terminated mid-bootstrap!"
496
+ logs = if !@config['basis'].nil?
497
+ pool = @deploy.findLitterMate(type: "server_pools", name: @config["name"])
498
+ if pool
499
+ MU::Cloud::AWS.autoscale(region: @region, credentials: @credentials).describe_scaling_activities(auto_scaling_group_name: pool.cloud_id).activities
500
+ else
501
+ nil
502
+ end
503
+ end
504
+ raise MuError.new, "#{@cloud_id} appears to have been terminated mid-bootstrap!", details: logs
478
505
  end
479
506
  if retries % 3 == 0
480
507
  MU.log "Waiting for EC2 instance #{@mu_name} (#{@cloud_id}) to be ready...", MU::NOTICE
@@ -495,7 +522,7 @@ module MU
495
522
 
496
523
  if !@config['src_dst_check'] and !@config["vpc"].nil?
497
524
  MU.log "Disabling source_dest_check #{@mu_name} (making it NAT-worthy)"
498
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).modify_instance_attribute(
525
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).modify_instance_attribute(
499
526
  instance_id: @cloud_id,
500
527
  source_dest_check: { value: false }
501
528
  )
@@ -503,7 +530,7 @@ module MU
503
530
 
504
531
  # Set console termination protection. Autoscale nodes won't set this
505
532
  # by default.
506
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).modify_instance_attribute(
533
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).modify_instance_attribute(
507
534
  instance_id: @cloud_id,
508
535
  disable_api_termination: { value: true}
509
536
  )
@@ -516,7 +543,6 @@ module MU
516
543
  notify
517
544
  end
518
545
 
519
- getIAMProfile
520
546
  finish.call(false) if !bootstrapGroomer
521
547
 
522
548
  # Make sure we got our name written everywhere applicable
@@ -606,7 +632,7 @@ module MU
606
632
  "cloud" => "AWS",
607
633
  "credentials" => @credentials,
608
634
  "cloud_id" => @cloud_id,
609
- "region" => @config['region']
635
+ "region" => @region
610
636
  }
611
637
 
612
638
  if !cloud_desc
@@ -616,7 +642,7 @@ module MU
616
642
 
617
643
  asgs = MU::Cloud.resourceClass("AWS", "ServerPool").find(
618
644
  instance_id: @cloud_id,
619
- region: @config['region'],
645
+ region: @region,
620
646
  credentials: @credentials
621
647
  )
622
648
  if asgs.size > 0
@@ -651,7 +677,7 @@ module MU
651
677
 
652
678
  bok['image_id'] = cloud_desc.image_id
653
679
 
654
- ami = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_images(image_ids: [bok['image_id']]).images.first
680
+ ami = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_images(image_ids: [bok['image_id']]).images.first
655
681
 
656
682
  if ami.nil? or ami.empty?
657
683
  MU.log "#{@mu_name} source image #{bok['image_id']} no longer exists", MU::WARN
@@ -660,7 +686,7 @@ module MU
660
686
 
661
687
  if cloud_desc.block_device_mappings and !cloud_desc.block_device_mappings.empty?
662
688
  vol_map = {}
663
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_volumes(
689
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_volumes(
664
690
  volume_ids: cloud_desc.block_device_mappings.map { |d| d.ebs.volume_id if d.ebs }
665
691
  ).volumes.each { |vol|
666
692
  vol_map[vol.volume_id] = vol
@@ -696,7 +722,7 @@ module MU
696
722
  id: int.vpc_id,
697
723
  cloud: "AWS",
698
724
  credentials: @credentials,
699
- region: @config['region'],
725
+ region: @region,
700
726
  subnet_id: int.subnet_id,
701
727
  habitat: MU::Config::Ref.get(
702
728
  id: int.owner_id,
@@ -725,11 +751,11 @@ module MU
725
751
  if int.groups.size > 0
726
752
 
727
753
  require 'mu/providers/aws/firewall_rule'
728
- ifaces = MU::Cloud.resourceClass("AWS", "FirewallRule").getAssociatedInterfaces(int.groups.map { |sg| sg.group_id }, credentials: @credentials, region: @config['region'])
754
+ ifaces = MU::Cloud.resourceClass("AWS", "FirewallRule").getAssociatedInterfaces(int.groups.map { |sg| sg.group_id }, credentials: @credentials, region: @region)
729
755
  done_local_rules = false
730
756
  int.groups.each { |sg|
731
757
  if !done_local_rules and ifaces[sg.group_id].size == 1
732
- sg_desc = MU::Cloud.resourceClass("AWS", "FirewallRule").find(cloud_id: sg.group_id, credentials: @credentials, region: @config['region']).values.first
758
+ sg_desc = MU::Cloud.resourceClass("AWS", "FirewallRule").find(cloud_id: sg.group_id, credentials: @credentials, region: @region).values.first
733
759
  if sg_desc
734
760
  bok["ingress_rules"] = MU::Cloud.resourceClass("AWS", "FirewallRule").rulesToBoK(sg_desc.ip_permissions)
735
761
  bok["ingress_rules"].concat(MU::Cloud.resourceClass("AWS", "FirewallRule").rulesToBoK(sg_desc.ip_permissions_egress, egress: true))
@@ -743,7 +769,7 @@ module MU
743
769
  cloud: "AWS",
744
770
  credentials: @credentials,
745
771
  type: "firewall_rules",
746
- region: @config['region']
772
+ region: @region
747
773
  )
748
774
  }
749
775
  end
@@ -799,7 +825,7 @@ module MU
799
825
  if !@config['chef_data'].nil?
800
826
  deploydata.merge!(@config['chef_data'])
801
827
  end
802
- deploydata["region"] = @config['region'] if !@config['region'].nil?
828
+ deploydata["region"] = @region if !@region.nil?
803
829
  if !@named
804
830
  MU::MommaCat.nameKitten(self, no_dns: true)
805
831
  @named = true
@@ -883,7 +909,7 @@ module MU
883
909
  # Canonical Amazon Resource Number for this resource
884
910
  # @return [String]
885
911
  def arn
886
- "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":ec2:"+@config['region']+":"+MU::Cloud::AWS.credToAcct(@credentials)+":instance/"+@cloud_id
912
+ "arn:"+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+":ec2:"+@region+":"+MU::Cloud::AWS.credToAcct(@credentials)+":instance/"+@cloud_id
887
913
  end
888
914
 
889
915
  @cloud_desc_cache = nil
@@ -896,7 +922,7 @@ module MU
896
922
  retries = 0
897
923
  if !@cloud_id.nil?
898
924
  begin
899
- resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_instances(instance_ids: [@cloud_id])
925
+ resp = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_instances(instance_ids: [@cloud_id])
900
926
  if resp and resp.reservations and resp.reservations.first and
901
927
  resp.reservations.first.instances and
902
928
  resp.reservations.first.instances.first
@@ -943,7 +969,7 @@ module MU
943
969
  # Our deploydata gets corrupted often with server pools, this will cause us to use the wrong IP to identify a node
944
970
  # which will cause us to create certificates, DNS records and other artifacts with incorrect information which will cause our deploy to fail.
945
971
  # The cloud_id is always correct so lets use 'cloud_desc' to get the correct IPs
946
- if MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @credentials) or @deploydata["public_ip_address"].nil?
972
+ if MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @region, credentials: @credentials) or @deploydata["public_ip_address"].nil?
947
973
  @config['canonical_ip'] = cloud_desc.private_ip_address
948
974
  @deploydata["private_ip_address"] = cloud_desc.private_ip_address
949
975
  return cloud_desc.private_ip_address
@@ -1170,7 +1196,7 @@ module MU
1170
1196
  retries = 0
1171
1197
  MU.log "Waiting for Windows instance password to be set by Amazon and flagged as available from the API. Note- if you're using a source AMI that already has its password set, this may fail. You'll want to set use_cloud_provider_windows_password to false if this is the case.", MU::NOTICE
1172
1198
  begin
1173
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).wait_until(:password_data_available, instance_id: @cloud_id) do |waiter|
1199
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).wait_until(:password_data_available, instance_id: @cloud_id) do |waiter|
1174
1200
  waiter.max_attempts = 60
1175
1201
  waiter.before_attempt do |attempts|
1176
1202
  MU.log "Waiting for Windows password data to be available for node #{@mu_name}", MU::NOTICE if attempts % 5 == 0
@@ -1182,15 +1208,15 @@ module MU
1182
1208
  rescue Aws::Waiters::Errors::TooManyAttemptsError => e
1183
1209
  if retries < 2
1184
1210
  retries = retries + 1
1185
- MU.log "wait_until(:password_data_available, instance_id: #{@cloud_id}) in #{@config['region']} never got a good response, retrying (#{retries}/2)", MU::WARN, details: e.inspect
1211
+ MU.log "wait_until(:password_data_available, instance_id: #{@cloud_id}) in #{@region} never got a good response, retrying (#{retries}/2)", MU::WARN, details: e.inspect
1186
1212
  retry
1187
1213
  else
1188
- MU.log "wait_until(:password_data_available, instance_id: #{@cloud_id}) in #{@config['region']} never returned- this image may not be configured to have its password set by AWS.", MU::ERR
1214
+ MU.log "wait_until(:password_data_available, instance_id: #{@cloud_id}) in #{@region} never returned- this image may not be configured to have its password set by AWS.", MU::ERR
1189
1215
  return nil
1190
1216
  end
1191
1217
  end
1192
1218
 
1193
- resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).get_password_data(instance_id: @cloud_id)
1219
+ resp = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).get_password_data(instance_id: @cloud_id)
1194
1220
  encrypted_password = resp.password_data
1195
1221
 
1196
1222
  # Note: This is already implemented in the decrypt_windows_password API call
@@ -1209,7 +1235,7 @@ module MU
1209
1235
  # instead of VPC.
1210
1236
  # @param ip [String]: Request a specific IP address.
1211
1237
  # @param region [String]: The cloud provider region
1212
- def self.findFreeElasticIp(classic: false, ip: nil, region: MU.curRegion)
1238
+ def self.findFreeElasticIp(classic: false, ip: nil, region: MU.curRegion, credentials: nil)
1213
1239
  filters = Array.new
1214
1240
  if !classic
1215
1241
  filters << {name: "domain", values: ["vpc"]}
@@ -1219,25 +1245,22 @@ module MU
1219
1245
  filters << {name: "public-ip", values: [ip]} if ip != nil
1220
1246
 
1221
1247
  if filters.size > 0
1222
- resp = MU::Cloud::AWS.ec2(region: region).describe_addresses(filters: filters)
1248
+ resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_addresses(filters: filters)
1223
1249
  else
1224
- resp = MU::Cloud::AWS.ec2(region: region).describe_addresses()
1250
+ resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_addresses
1225
1251
  end
1226
1252
  resp.addresses.each { |address|
1227
- return address if (address.network_interface_id.nil? || address.network_interface_id.empty?) && !@eips_used.include?(address.public_ip)
1253
+ return address if (address.network_interface_id.nil? or address.network_interface_id.empty?) or !@eips_used.include?(address.public_ip)
1228
1254
  }
1229
- if ip != nil
1230
- if !classic
1231
- raise MuError, "Requested EIP #{ip}, but no such IP exists or is avaulable in VPC"
1232
- else
1233
- raise MuError, "Requested EIP #{ip}, but no such IP exists or is available in EC2 Classic"
1234
- end
1255
+ if !ip.nil?
1256
+ mode = classic ? "EC2 Classic" : "VPC"
1257
+ raise MuError.new "Requested EIP #{ip}, but no such IP exists or is available in #{mode} mode#{credentials ? " with credentials #{credentials}" : ""}", details: { "describe_address filters" => filters, "describe_address response" => resp }
1235
1258
  end
1236
1259
  if !classic
1237
- resp = MU::Cloud::AWS.ec2(region: region).allocate_address(domain: "vpc")
1260
+ resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).allocate_address(domain: "vpc")
1238
1261
  new_ip = resp.public_ip
1239
1262
  else
1240
- new_ip = MU::Cloud::AWS.ec2(region: region).allocate_address().public_ip
1263
+ new_ip = MU::Cloud::AWS.ec2(region: region, credentials: credentials).allocate_address().public_ip
1241
1264
  end
1242
1265
  filters = [{name: "public-ip", values: [new_ip]}]
1243
1266
  if resp.domain
@@ -1253,8 +1276,8 @@ module MU
1253
1276
  begin
1254
1277
  begin
1255
1278
  sleep 5
1256
- resp = MU::Cloud::AWS.ec2(region: region).describe_addresses(
1257
- filters: filters
1279
+ resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_addresses(
1280
+ filters: filters
1258
1281
  )
1259
1282
  addr = resp.addresses.first
1260
1283
  end while resp.addresses.size < 1 or addr.public_ip.nil?
@@ -1280,14 +1303,14 @@ module MU
1280
1303
  end
1281
1304
 
1282
1305
  MU.log "Creating #{size}GB #{type} volume on #{dev} for #{@cloud_id}"
1283
- creation = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).create_volume(
1306
+ creation = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).create_volume(
1284
1307
  availability_zone: cloud_desc.placement.availability_zone,
1285
1308
  size: size,
1286
1309
  volume_type: type
1287
1310
  )
1288
1311
 
1289
1312
  MU.retrier(wait: 3, loop_if: Proc.new {
1290
- creation = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_volumes(volume_ids: [creation.volume_id]).volumes.first
1313
+ creation = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_volumes(volume_ids: [creation.volume_id]).volumes.first
1291
1314
  if !["creating", "available"].include?(creation.state)
1292
1315
  raise MuError, "Saw state '#{creation.state}' while creating #{size}GB #{type} volume on #{dev} for #{@cloud_id}"
1293
1316
  end
@@ -1298,7 +1321,7 @@ module MU
1298
1321
  if @deploy
1299
1322
  MU::Cloud::AWS.createStandardTags(
1300
1323
  creation.volume_id,
1301
- region: @config['region'],
1324
+ region: @region,
1302
1325
  credentials: @credentials,
1303
1326
  optional: @config['optional_tags'],
1304
1327
  nametag: @mu_name+"-"+dev.upcase,
@@ -1306,10 +1329,10 @@ module MU
1306
1329
  )
1307
1330
  end
1308
1331
 
1309
- MU.log "Attaching #{creation.volume_id} as #{dev} to #{@cloud_id} in #{@config['region']} (credentials #{@credentials})"
1332
+ MU.log "Attaching #{creation.volume_id} as #{dev} to #{@cloud_id} in #{@region} (credentials #{@credentials})"
1310
1333
  attachment = nil
1311
1334
  MU.retrier([Aws::EC2::Errors::IncorrectState], wait: 15, max: 4) {
1312
- attachment = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).attach_volume(
1335
+ attachment = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).attach_volume(
1313
1336
  device: dev,
1314
1337
  instance_id: @cloud_id,
1315
1338
  volume_id: creation.volume_id
@@ -1317,11 +1340,16 @@ module MU
1317
1340
  }
1318
1341
 
1319
1342
  begin
1320
- attachment = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_volumes(volume_ids: [attachment.volume_id]).volumes.first.attachments.first
1321
- if !["attaching", "attached"].include?(attachment.state)
1322
- raise MuError, "Saw state '#{creation.state}' while creating #{size}GB #{type} volume on #{dev} for #{@cloud_id}"
1343
+ att_resp = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_volumes(volume_ids: [attachment.volume_id])
1344
+ if att_resp and att_resp.volumes and !att_resp.volumes.empty? and
1345
+ att_resp.volumes.first.attachments and
1346
+ !att_resp.volumes.first.attachments.empty?
1347
+ attachment = att_resp.volumes.first.attachments.first
1348
+ if !attachment.nil? and !["attaching", "attached"].include?(attachment.state)
1349
+ raise MuError, "Saw state '#{creation.state}' while creating #{size}GB #{type} volume on #{dev} for #{@cloud_id}"
1350
+ end
1323
1351
  end
1324
- end while attachment.state != "attached"
1352
+ end while attachment.nil? or attachment.state != "attached"
1325
1353
 
1326
1354
  # Set delete_on_termination, which for some reason is an instance
1327
1355
  # attribute and not on the attachment
@@ -1337,7 +1365,7 @@ module MU
1337
1365
  return true
1338
1366
  end
1339
1367
  begin
1340
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_instances(
1368
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_instances(
1341
1369
  instance_ids: [@cloud_id]
1342
1370
  ).reservations.each { |resp|
1343
1371
  if !resp.nil? and !resp.instances.nil?
@@ -1388,7 +1416,7 @@ module MU
1388
1416
  }
1389
1417
  end
1390
1418
  end
1391
- elastic_ip = findFreeElasticIp(classic: classic, ip: ip)
1419
+ elastic_ip = findFreeElasticIp(classic: classic, ip: ip, credentials: credentials)
1392
1420
  if !ip.nil? and (elastic_ip.nil? or ip != elastic_ip.public_ip)
1393
1421
  raise MuError, "Requested EIP #{ip}, but this IP does not exist or is not available"
1394
1422
  end
@@ -1740,6 +1768,7 @@ module MU
1740
1768
  return size
1741
1769
  end
1742
1770
 
1771
+
1743
1772
  return size if types.has_key?(size)
1744
1773
 
1745
1774
  if size.nil? or !types.has_key?(size)
@@ -1785,7 +1814,8 @@ module MU
1785
1814
  def self.generateStandardRole(server, configurator)
1786
1815
  role = {
1787
1816
  "name" => server["name"],
1788
- "credentials" => server["credentials"],
1817
+ "bare_policies" => !server['generate_iam_role'],
1818
+ "strip_path" => server["role_strip_path"],
1789
1819
  "can_assume" => [
1790
1820
  {
1791
1821
  "entity_id" => "ec2.amazonaws.com",
@@ -1804,6 +1834,7 @@ module MU
1804
1834
  }
1805
1835
  ]
1806
1836
  }
1837
+ role["credentials"] = server["credentials"] if server["credentials"]
1807
1838
  if server['iam_policies']
1808
1839
  role['iam_policies'] = server['iam_policies'].dup
1809
1840
  end
@@ -1837,9 +1868,10 @@ module MU
1837
1868
  MU.log "Cannot mix iam_policies with generate_iam_role set to false", MU::ERR
1838
1869
  ok = false
1839
1870
  end
1840
- else
1841
- generateStandardRole(server, configurator)
1842
1871
  end
1872
+
1873
+ generateStandardRole(server, configurator)
1874
+
1843
1875
  if !server['create_image'].nil?
1844
1876
  if server['create_image'].has_key?('copy_to_regions') and
1845
1877
  (server['create_image']['copy_to_regions'].nil? or
@@ -2088,7 +2120,7 @@ module MU
2088
2120
  def haveElasticIP?
2089
2121
  if !cloud_desc.public_ip_address.nil?
2090
2122
  begin
2091
- resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_addresses(public_ips: [cloud_desc.public_ip_address])
2123
+ resp = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_addresses(public_ips: [cloud_desc.public_ip_address])
2092
2124
  if resp.addresses.size > 0 and resp.addresses.first.instance_id == @cloud_id
2093
2125
  return true
2094
2126
  end
@@ -2103,9 +2135,9 @@ module MU
2103
2135
  def configureNetworking
2104
2136
  if !@config['static_ip'].nil?
2105
2137
  if !@config['static_ip']['ip'].nil?
2106
- MU::Cloud::AWS::Server.associateElasticIp(@cloud_id, classic: @vpc.nil?, ip: @config['static_ip']['ip'])
2138
+ MU::Cloud::AWS::Server.associateElasticIp(@cloud_id, classic: @vpc.nil?, ip: @config['static_ip']['ip'], credentials: @credentials)
2107
2139
  elsif !haveElasticIP?
2108
- MU::Cloud::AWS::Server.associateElasticIp(@cloud_id, classic: @vpc.nil?)
2140
+ MU::Cloud::AWS::Server.associateElasticIp(@cloud_id, classic: @vpc.nil?, credentials: @credentials)
2109
2141
  end
2110
2142
  end
2111
2143
 
@@ -2113,7 +2145,7 @@ module MU
2113
2145
  subnet = @vpc.getSubnet(cloud_id: cloud_desc.subnet_id)
2114
2146
 
2115
2147
  _nat_ssh_key, _nat_ssh_user, nat_ssh_host, _canonical_ip, _ssh_user, _ssh_key_name = getSSHConfig
2116
- if subnet.private? and !nat_ssh_host and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @credentials)
2148
+ if subnet.private? and !nat_ssh_host and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @region, credentials: @credentials)
2117
2149
  raise MuError, "#{@mu_name} is in a private subnet (#{subnet}), but has no bastion host configured, and I have no other route to it"
2118
2150
  end
2119
2151
 
@@ -2130,17 +2162,17 @@ module MU
2130
2162
  next
2131
2163
  end
2132
2164
  MU.log "Adding network interface on subnet #{s.cloud_id} for #{@mu_name}"
2133
- iface = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).create_network_interface(subnet_id: s.cloud_id).network_interface
2165
+ iface = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).create_network_interface(subnet_id: s.cloud_id).network_interface
2134
2166
  MU::Cloud::AWS.createStandardTags(
2135
2167
  iface.network_interface_id,
2136
- region: @config['region'],
2168
+ region: @region,
2137
2169
  credentials: @credentials,
2138
2170
  optional: @config['optional_tags'],
2139
2171
  nametag: @mu_name+"-ETH"+device_index.to_s,
2140
2172
  othertags: @config['tags']
2141
2173
  )
2142
2174
 
2143
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).attach_network_interface(
2175
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).attach_network_interface(
2144
2176
  network_interface_id: iface.network_interface_id,
2145
2177
  instance_id: cloud_desc.instance_id,
2146
2178
  device_index: device_index
@@ -2159,7 +2191,7 @@ module MU
2159
2191
  cloud_desc.network_interfaces.each { |int|
2160
2192
  if int.private_ip_address == cloud_desc.private_ip_address and int.private_ip_addresses.size < (@config['add_private_ips'] + 1)
2161
2193
  MU.log "Adding #{@config['add_private_ips']} extra private IP addresses to #{cloud_desc.instance_id}"
2162
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).assign_private_ip_addresses(
2194
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).assign_private_ip_addresses(
2163
2195
  network_interface_id: int.network_interface_id,
2164
2196
  secondary_private_ip_address_count: @config['add_private_ips'],
2165
2197
  allow_reassignment: false
@@ -2170,13 +2202,13 @@ module MU
2170
2202
  end
2171
2203
 
2172
2204
  def tagVolumes
2173
- volumes = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_volumes(filters: [name: "attachment.instance-id", values: [@cloud_id]])
2205
+ volumes = MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).describe_volumes(filters: [name: "attachment.instance-id", values: [@cloud_id]])
2174
2206
  volumes.each { |vol|
2175
2207
  vol.volumes.each { |volume|
2176
2208
  volume.attachments.each { |attachment|
2177
2209
  MU::Cloud::AWS.createStandardTags(
2178
2210
  attachment.volume_id,
2179
- region: @config['region'],
2211
+ region: @region,
2180
2212
  credentials: @credentials,
2181
2213
  optional: @config['optional_tags'],
2182
2214
  nametag: ["/dev/sda", "/dev/sda1"].include?(attachment.device) ? "ROOT-"+@mu_name : @mu_name+"-"+attachment.device.upcase,
@@ -2198,7 +2230,7 @@ module MU
2198
2230
  alarm_obj = MU::MommaCat.findStray(
2199
2231
  "AWS",
2200
2232
  "alarms",
2201
- region: @config["region"],
2233
+ region: @region,
2202
2234
  deploy_id: @deploy.deploy_id,
2203
2235
  name: alarm['name']
2204
2236
  ).first
@@ -2207,8 +2239,8 @@ module MU
2207
2239
  if alarm["enable_notifications"]
2208
2240
  # XXX vile, this should be a sibling resource generated by the
2209
2241
  # parser
2210
- topic_arn = MU::Cloud.resourceClass("AWS", "Notification").createTopic(alarm["notification_group"], region: @config["region"], credentials: @credentials)
2211
- MU::Cloud.resourceClass("AWS", "Notification").subscribe(topic_arn, alarm["notification_endpoint"], alarm["notification_type"], region: @config["region"], credentials: @config["credentials"])
2242
+ topic_arn = MU::Cloud.resourceClass("AWS", "Notification").createTopic(alarm["notification_group"], region: @region, credentials: @credentials)
2243
+ MU::Cloud.resourceClass("AWS", "Notification").subscribe(topic_arn, alarm["notification_endpoint"], alarm["notification_type"], region: @region, credentials: @credentials)
2212
2244
  alarm["alarm_actions"] = [topic_arn]
2213
2245
  alarm["ok_actions"] = [topic_arn]
2214
2246
  end
@@ -2229,39 +2261,88 @@ module MU
2229
2261
  evaluation_periods: alarm["evaluation_periods"],
2230
2262
  threshold: alarm["threshold"],
2231
2263
  comparison_operator: alarm["comparison_operator"],
2232
- region: @config["region"],
2264
+ region: @region,
2233
2265
  credentials: @credentials
2234
2266
  )
2235
2267
  }
2236
2268
  end
2237
2269
  end
2238
2270
 
2239
- # We have issues sometimes where our dns_records are pointing at the wrong node name and IP address.
2240
-
2241
2271
  def getIAMProfile
2242
- arn = if @config['generate_iam_role']
2243
- role = @deploy.findLitterMate(name: @config['name'], type: "roles", debug: true)
2272
+ self.class.getIAMProfile(
2273
+ @config['name'],
2274
+ @deploy,
2275
+ generated: @config['generate_iam_role'],
2276
+ role_name: @config['iam_role'],
2277
+ region: @region,
2278
+ credentials: @credentials,
2279
+ want_arn: true
2280
+ )
2281
+ end
2282
+
2283
+ # XXX move to public section
2284
+ def self.getIAMProfile(myname, deploy, generated: true, role_name: nil, region: nil, credentials: nil, want_arn: false)
2285
+
2286
+ arn = if generated
2287
+ role = deploy.findLitterMate(name: myname, type: "roles", debug: true)
2244
2288
  if !role
2245
- raise MuError, "Failed to find a role matching #{@config['name']}"
2289
+ raise MuError, "Failed to find a role matching #{myname}"
2246
2290
  end
2247
- 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|
2248
- 'arn:'+(MU::Cloud::AWS.isGovCloud?(@config['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU::Cloud::AWS.adminBucketName(@credentials)+'/'+file
2291
+ 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|
2292
+ 'arn:'+(MU::Cloud::AWS.isGovCloud?(region) ? "aws-us-gov" : "aws")+':s3:::'+MU::Cloud::AWS.adminBucketName(credentials)+'/'+file
2249
2293
  }
2250
- MU.log "Adding S3 read permissions to #{@mu_name}'s IAM profile", MU::NOTICE, details: s3_objs
2294
+ MU.log "Adding S3 read permissions to #{myname}'s IAM profile", MU::NOTICE, details: s3_objs
2251
2295
  role.cloudobj.injectPolicyTargets("MuSecrets", s3_objs)
2252
2296
 
2253
- @config['iam_role'] = role.mu_name
2297
+ role_name = role.mu_name
2254
2298
  role.cloudobj.createInstanceProfile
2255
2299
 
2256
- elsif @config['iam_role'].nil?
2257
- raise MuError, "#{@mu_name} has generate_iam_role set to false, but no iam_role assigned."
2300
+ elsif role_name.nil?
2301
+ raise MuError, "#{myname} has generate_iam_role set to false, but no iam_role assigned."
2302
+ else
2303
+ begin
2304
+ ext_prof = MU::Cloud::AWS.iam(credentials: credentials).get_instance_profile(instance_profile_name: role_name)
2305
+ role_name = ext_prof.instance_profile.instance_profile_name
2306
+ ext_prof.instance_profile.arn
2307
+ rescue Aws::IAM::Errors::NoSuchEntity
2308
+ role = MU::MommaCat.findStray("AWS", "role", cloud_id: role_name, dummy_ok: true, credentials: credentials).first
2309
+ if !role
2310
+ raise MuError, "#{myname} specified iam_role '#{role_name}', but I can't find a role with that name to use when creating an instance profile"
2311
+ end
2312
+ role.cloudobj.createInstanceProfile
2313
+ end
2314
+ end
2315
+
2316
+ role_or_policy = deploy.findLitterMate(name: myname, type: "roles")
2317
+
2318
+ # Make sure our permissions to read our identity secrets are set
2319
+ s3_objs = [
2320
+ "#{deploy.deploy_id}-secret",
2321
+ "#{role_or_policy.mu_name}.pfx",
2322
+ "#{role_or_policy.mu_name}.crt",
2323
+ "#{role_or_policy.mu_name}.key",
2324
+ "#{role_or_policy.mu_name}-winrm.crt",
2325
+ "#{role_or_policy.mu_name}-winrm.key"].map { |file|
2326
+ 'arn:'+(MU::Cloud::AWS.isGovCloud?(region) ? "aws-us-gov" : "aws")+':s3:::'+MU::Cloud::AWS.adminBucketName(credentials)+'/'+file
2327
+ }
2328
+ if generated
2329
+ role_or_policy.injectPolicyTargets("MuSecrets", s3_objs)
2330
+ elsif role_name
2331
+ realrole = MU::MommaCat.findStray("AWS", "role", cloud_id: role_name, dummy_ok: true, credentials: credentials).first
2332
+ if !role_or_policy
2333
+ raise MuError, "I should have a bare policy littermate named #{name} but I can't find it"
2334
+ end
2335
+ if realrole
2336
+ role_or_policy.bindTo("role", realrole.cloud_id)
2337
+ realrole.injectPolicyTargets(role_or_policy.mu_name+"-MUSECRETS", s3_objs)
2338
+ end
2258
2339
  end
2259
2340
 
2260
- if !@config["iam_role"].nil?
2261
- if arn
2341
+ if !role_name.nil?
2342
+ if arn and want_arn
2262
2343
  return {arn: arn}
2263
2344
  else
2264
- return {name: @config["iam_role"]}
2345
+ return {name: role_name}
2265
2346
  end
2266
2347
  end
2267
2348
 
@@ -2279,7 +2360,7 @@ module MU
2279
2360
  if vol[:ebs][:delete_on_termination] != delete_on_termination
2280
2361
  vol[:ebs][:delete_on_termination] = delete_on_termination
2281
2362
  MU.log "Setting delete_on_termination flag to #{delete_on_termination.to_s} on #{@mu_name}'s #{device}"
2282
- MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).modify_instance_attribute(
2363
+ MU::Cloud::AWS.ec2(region: @region, credentials: @credentials).modify_instance_attribute(
2283
2364
  instance_id: @cloud_id,
2284
2365
  block_device_mappings: mappings
2285
2366
  )
@@ -2323,7 +2404,7 @@ module MU
2323
2404
  exclude_storage: img_cfg['image_exclude_storage'],
2324
2405
  copy_to_regions: img_cfg['copy_to_regions'],
2325
2406
  make_public: img_cfg['public'],
2326
- region: @config['region'],
2407
+ region: @region,
2327
2408
  tags: @config['tags'],
2328
2409
  credentials: @credentials
2329
2410
  )
@@ -2331,9 +2412,9 @@ module MU
2331
2412
  @deploy.notify("images", @config['name'], ami_ids)
2332
2413
  @config['image_created'] = true
2333
2414
  if img_cfg['image_then_destroy']
2334
- MU::Cloud::AWS::Server.waitForAMI(ami_ids[@config['region']], region: @config['region'], credentials: @credentials)
2335
- MU.log "AMI #{ami_ids[@config['region']]} ready, removing source node #{@mu_name}"
2336
- MU::Cloud::AWS::Server.terminateInstance(id: @cloud_id, region: @config['region'], deploy_id: @deploy.deploy_id, mu_name: @mu_name, credentials: @credentials)
2415
+ MU::Cloud::AWS::Server.waitForAMI(ami_ids[@region], region: @region, credentials: @credentials)
2416
+ MU.log "AMI #{ami_ids[@region]} ready, removing source node #{@mu_name}"
2417
+ MU::Cloud::AWS::Server.terminateInstance(id: @cloud_id, region: @region, deploy_id: @deploy.deploy_id, mu_name: @mu_name, credentials: @credentials)
2337
2418
  destroy
2338
2419
  end
2339
2420
  end