cloud-mu 2.1.0beta → 3.0.0beta

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 (291) hide show
  1. checksums.yaml +5 -5
  2. data/Berksfile +4 -5
  3. data/Berksfile.lock +179 -0
  4. data/README.md +1 -6
  5. data/ansible/roles/geerlingguy.firewall/templates/firewall.bash.j2 +0 -0
  6. data/ansible/roles/mu-installer/README.md +33 -0
  7. data/ansible/roles/mu-installer/defaults/main.yml +2 -0
  8. data/ansible/roles/mu-installer/handlers/main.yml +2 -0
  9. data/ansible/roles/mu-installer/meta/main.yml +60 -0
  10. data/ansible/roles/mu-installer/tasks/main.yml +13 -0
  11. data/ansible/roles/mu-installer/tests/inventory +2 -0
  12. data/ansible/roles/mu-installer/tests/test.yml +5 -0
  13. data/ansible/roles/mu-installer/vars/main.yml +2 -0
  14. data/bin/mu-adopt +125 -0
  15. data/bin/mu-aws-setup +4 -4
  16. data/bin/mu-azure-setup +265 -0
  17. data/bin/mu-azure-tests +43 -0
  18. data/bin/mu-cleanup +20 -8
  19. data/bin/mu-configure +224 -98
  20. data/bin/mu-deploy +8 -3
  21. data/bin/mu-gcp-setup +16 -8
  22. data/bin/mu-gen-docs +92 -8
  23. data/bin/mu-load-config.rb +52 -12
  24. data/bin/mu-momma-cat +36 -0
  25. data/bin/mu-node-manage +34 -27
  26. data/bin/mu-self-update +2 -2
  27. data/bin/mu-ssh +12 -8
  28. data/bin/mu-upload-chef-artifacts +11 -4
  29. data/bin/mu-user-manage +3 -0
  30. data/cloud-mu.gemspec +8 -11
  31. data/cookbooks/firewall/libraries/helpers_iptables.rb +2 -2
  32. data/cookbooks/firewall/metadata.json +1 -1
  33. data/cookbooks/firewall/recipes/default.rb +5 -9
  34. data/cookbooks/mu-firewall/attributes/default.rb +2 -0
  35. data/cookbooks/mu-firewall/metadata.rb +1 -1
  36. data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +0 -0
  37. data/cookbooks/mu-master/Berksfile +2 -2
  38. data/cookbooks/mu-master/files/default/check_mem.pl +0 -0
  39. data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
  40. data/cookbooks/mu-master/metadata.rb +5 -4
  41. data/cookbooks/mu-master/recipes/389ds.rb +1 -1
  42. data/cookbooks/mu-master/recipes/basepackages.rb +30 -10
  43. data/cookbooks/mu-master/recipes/default.rb +59 -7
  44. data/cookbooks/mu-master/recipes/firewall-holes.rb +1 -1
  45. data/cookbooks/mu-master/recipes/init.rb +65 -47
  46. data/cookbooks/mu-master/recipes/{eks-kubectl.rb → kubectl.rb} +4 -10
  47. data/cookbooks/mu-master/recipes/sssd.rb +2 -1
  48. data/cookbooks/mu-master/recipes/update_nagios_only.rb +6 -6
  49. data/cookbooks/mu-master/templates/default/web_app.conf.erb +2 -2
  50. data/cookbooks/mu-master/templates/mods/ldap.conf.erb +4 -0
  51. data/cookbooks/mu-php54/Berksfile +1 -2
  52. data/cookbooks/mu-php54/metadata.rb +4 -5
  53. data/cookbooks/mu-php54/recipes/default.rb +1 -1
  54. data/cookbooks/mu-splunk/templates/default/splunk-init.erb +0 -0
  55. data/cookbooks/mu-tools/Berksfile +3 -2
  56. data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
  57. data/cookbooks/mu-tools/libraries/helper.rb +20 -8
  58. data/cookbooks/mu-tools/metadata.rb +5 -2
  59. data/cookbooks/mu-tools/recipes/apply_security.rb +2 -3
  60. data/cookbooks/mu-tools/recipes/eks.rb +1 -1
  61. data/cookbooks/mu-tools/recipes/gcloud.rb +5 -30
  62. data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
  63. data/cookbooks/mu-tools/recipes/rsyslog.rb +1 -0
  64. data/cookbooks/mu-tools/recipes/selinux.rb +19 -0
  65. data/cookbooks/mu-tools/recipes/split_var_partitions.rb +0 -1
  66. data/cookbooks/mu-tools/recipes/windows-client.rb +256 -122
  67. data/cookbooks/mu-tools/resources/disk.rb +3 -1
  68. data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +1 -1
  69. data/cookbooks/mu-tools/templates/default/etc_hosts.erb +1 -1
  70. data/cookbooks/mu-tools/templates/default/{kubeconfig.erb → kubeconfig-eks.erb} +0 -0
  71. data/cookbooks/mu-tools/templates/default/kubeconfig-gke.erb +27 -0
  72. data/cookbooks/mu-tools/templates/windows-10/sshd_config.erb +137 -0
  73. data/cookbooks/mu-utility/recipes/nat.rb +4 -0
  74. data/extras/alpha.png +0 -0
  75. data/extras/beta.png +0 -0
  76. data/extras/clean-stock-amis +2 -2
  77. data/extras/generate-stock-images +131 -0
  78. data/extras/git-fix-permissions-hook +0 -0
  79. data/extras/image-generators/AWS/centos6.yaml +17 -0
  80. data/extras/image-generators/{aws → AWS}/centos7-govcloud.yaml +0 -0
  81. data/extras/image-generators/{aws → AWS}/centos7.yaml +0 -0
  82. data/extras/image-generators/{aws → AWS}/rhel7.yaml +0 -0
  83. data/extras/image-generators/{aws → AWS}/win2k12.yaml +0 -0
  84. data/extras/image-generators/{aws → AWS}/win2k16.yaml +0 -0
  85. data/extras/image-generators/{aws → AWS}/windows.yaml +0 -0
  86. data/extras/image-generators/{gcp → Google}/centos6.yaml +1 -0
  87. data/extras/image-generators/Google/centos7.yaml +18 -0
  88. data/extras/python_rpm/build.sh +0 -0
  89. data/extras/release.png +0 -0
  90. data/extras/ruby_rpm/build.sh +0 -0
  91. data/extras/ruby_rpm/muby.spec +1 -1
  92. data/install/README.md +43 -5
  93. data/install/deprecated-bash-library.sh +0 -0
  94. data/install/installer +1 -1
  95. data/install/jenkinskeys.rb +0 -0
  96. data/install/mu-master.yaml +55 -0
  97. data/modules/mommacat.ru +41 -7
  98. data/modules/mu.rb +444 -149
  99. data/modules/mu/adoption.rb +500 -0
  100. data/modules/mu/cleanup.rb +235 -158
  101. data/modules/mu/cloud.rb +675 -138
  102. data/modules/mu/clouds/aws.rb +156 -24
  103. data/modules/mu/clouds/aws/alarm.rb +4 -14
  104. data/modules/mu/clouds/aws/bucket.rb +60 -18
  105. data/modules/mu/clouds/aws/cache_cluster.rb +8 -20
  106. data/modules/mu/clouds/aws/collection.rb +12 -22
  107. data/modules/mu/clouds/aws/container_cluster.rb +209 -118
  108. data/modules/mu/clouds/aws/database.rb +120 -45
  109. data/modules/mu/clouds/aws/dnszone.rb +7 -18
  110. data/modules/mu/clouds/aws/endpoint.rb +5 -15
  111. data/modules/mu/clouds/aws/firewall_rule.rb +144 -72
  112. data/modules/mu/clouds/aws/folder.rb +4 -11
  113. data/modules/mu/clouds/aws/function.rb +6 -16
  114. data/modules/mu/clouds/aws/group.rb +4 -12
  115. data/modules/mu/clouds/aws/habitat.rb +11 -13
  116. data/modules/mu/clouds/aws/loadbalancer.rb +40 -28
  117. data/modules/mu/clouds/aws/log.rb +5 -13
  118. data/modules/mu/clouds/aws/msg_queue.rb +9 -24
  119. data/modules/mu/clouds/aws/nosqldb.rb +4 -12
  120. data/modules/mu/clouds/aws/notifier.rb +6 -13
  121. data/modules/mu/clouds/aws/role.rb +69 -40
  122. data/modules/mu/clouds/aws/search_domain.rb +17 -20
  123. data/modules/mu/clouds/aws/server.rb +184 -94
  124. data/modules/mu/clouds/aws/server_pool.rb +33 -38
  125. data/modules/mu/clouds/aws/storage_pool.rb +5 -12
  126. data/modules/mu/clouds/aws/user.rb +59 -33
  127. data/modules/mu/clouds/aws/userdata/linux.erb +18 -30
  128. data/modules/mu/clouds/aws/userdata/windows.erb +9 -9
  129. data/modules/mu/clouds/aws/vpc.rb +214 -145
  130. data/modules/mu/clouds/azure.rb +978 -44
  131. data/modules/mu/clouds/azure/container_cluster.rb +413 -0
  132. data/modules/mu/clouds/azure/firewall_rule.rb +500 -0
  133. data/modules/mu/clouds/azure/habitat.rb +167 -0
  134. data/modules/mu/clouds/azure/loadbalancer.rb +205 -0
  135. data/modules/mu/clouds/azure/role.rb +211 -0
  136. data/modules/mu/clouds/azure/server.rb +810 -0
  137. data/modules/mu/clouds/azure/user.rb +257 -0
  138. data/modules/mu/clouds/azure/userdata/README.md +4 -0
  139. data/modules/mu/clouds/azure/userdata/linux.erb +137 -0
  140. data/modules/mu/clouds/azure/userdata/windows.erb +275 -0
  141. data/modules/mu/clouds/azure/vpc.rb +782 -0
  142. data/modules/mu/clouds/cloudformation.rb +12 -9
  143. data/modules/mu/clouds/cloudformation/firewall_rule.rb +5 -13
  144. data/modules/mu/clouds/cloudformation/server.rb +10 -1
  145. data/modules/mu/clouds/cloudformation/server_pool.rb +1 -0
  146. data/modules/mu/clouds/cloudformation/vpc.rb +0 -2
  147. data/modules/mu/clouds/google.rb +554 -117
  148. data/modules/mu/clouds/google/bucket.rb +173 -32
  149. data/modules/mu/clouds/google/container_cluster.rb +1112 -157
  150. data/modules/mu/clouds/google/database.rb +24 -47
  151. data/modules/mu/clouds/google/firewall_rule.rb +344 -89
  152. data/modules/mu/clouds/google/folder.rb +156 -79
  153. data/modules/mu/clouds/google/group.rb +272 -82
  154. data/modules/mu/clouds/google/habitat.rb +177 -52
  155. data/modules/mu/clouds/google/loadbalancer.rb +9 -34
  156. data/modules/mu/clouds/google/role.rb +1211 -0
  157. data/modules/mu/clouds/google/server.rb +491 -227
  158. data/modules/mu/clouds/google/server_pool.rb +233 -48
  159. data/modules/mu/clouds/google/user.rb +479 -125
  160. data/modules/mu/clouds/google/userdata/linux.erb +3 -3
  161. data/modules/mu/clouds/google/userdata/windows.erb +9 -9
  162. data/modules/mu/clouds/google/vpc.rb +381 -223
  163. data/modules/mu/config.rb +689 -214
  164. data/modules/mu/config/bucket.rb +1 -1
  165. data/modules/mu/config/cache_cluster.rb +1 -1
  166. data/modules/mu/config/cache_cluster.yml +0 -4
  167. data/modules/mu/config/container_cluster.rb +18 -9
  168. data/modules/mu/config/database.rb +6 -23
  169. data/modules/mu/config/firewall_rule.rb +9 -15
  170. data/modules/mu/config/folder.rb +22 -21
  171. data/modules/mu/config/habitat.rb +22 -21
  172. data/modules/mu/config/loadbalancer.rb +2 -2
  173. data/modules/mu/config/role.rb +9 -40
  174. data/modules/mu/config/server.rb +26 -5
  175. data/modules/mu/config/server_pool.rb +1 -1
  176. data/modules/mu/config/storage_pool.rb +2 -2
  177. data/modules/mu/config/user.rb +4 -0
  178. data/modules/mu/config/vpc.rb +350 -110
  179. data/modules/mu/defaults/{amazon_images.yaml → AWS.yaml} +37 -39
  180. data/modules/mu/defaults/Azure.yaml +17 -0
  181. data/modules/mu/defaults/Google.yaml +24 -0
  182. data/modules/mu/defaults/README.md +1 -1
  183. data/modules/mu/deploy.rb +168 -125
  184. data/modules/mu/groomer.rb +2 -1
  185. data/modules/mu/groomers/ansible.rb +104 -32
  186. data/modules/mu/groomers/chef.rb +96 -44
  187. data/modules/mu/kittens.rb +20602 -0
  188. data/modules/mu/logger.rb +38 -11
  189. data/modules/mu/master.rb +90 -8
  190. data/modules/mu/master/chef.rb +2 -3
  191. data/modules/mu/master/ldap.rb +0 -1
  192. data/modules/mu/master/ssl.rb +250 -0
  193. data/modules/mu/mommacat.rb +917 -513
  194. data/modules/scratchpad.erb +1 -1
  195. data/modules/tests/super_complex_bok.yml +0 -0
  196. data/modules/tests/super_simple_bok.yml +0 -0
  197. data/roles/mu-master.json +2 -1
  198. data/spec/azure_creds +5 -0
  199. data/spec/mu.yaml +56 -0
  200. data/spec/mu/clouds/azure_spec.rb +164 -27
  201. data/spec/spec_helper.rb +5 -0
  202. data/test/clean_up.py +0 -0
  203. data/test/exec_inspec.py +0 -0
  204. data/test/exec_mu_install.py +0 -0
  205. data/test/exec_retry.py +0 -0
  206. data/test/smoke_test.rb +0 -0
  207. metadata +90 -118
  208. data/cookbooks/mu-jenkins/Berksfile +0 -14
  209. data/cookbooks/mu-jenkins/CHANGELOG.md +0 -13
  210. data/cookbooks/mu-jenkins/LICENSE +0 -37
  211. data/cookbooks/mu-jenkins/README.md +0 -105
  212. data/cookbooks/mu-jenkins/attributes/default.rb +0 -42
  213. data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +0 -73
  214. data/cookbooks/mu-jenkins/files/default/deploy_config.xml +0 -44
  215. data/cookbooks/mu-jenkins/metadata.rb +0 -21
  216. data/cookbooks/mu-jenkins/recipes/default.rb +0 -195
  217. data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +0 -54
  218. data/cookbooks/mu-jenkins/recipes/public_key.rb +0 -24
  219. data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +0 -24
  220. data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +0 -14
  221. data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +0 -6
  222. data/cookbooks/nagios/Berksfile +0 -11
  223. data/cookbooks/nagios/CHANGELOG.md +0 -589
  224. data/cookbooks/nagios/CONTRIBUTING.md +0 -11
  225. data/cookbooks/nagios/LICENSE +0 -37
  226. data/cookbooks/nagios/README.md +0 -328
  227. data/cookbooks/nagios/TESTING.md +0 -2
  228. data/cookbooks/nagios/attributes/config.rb +0 -171
  229. data/cookbooks/nagios/attributes/default.rb +0 -228
  230. data/cookbooks/nagios/chefignore +0 -102
  231. data/cookbooks/nagios/definitions/command.rb +0 -33
  232. data/cookbooks/nagios/definitions/contact.rb +0 -33
  233. data/cookbooks/nagios/definitions/contactgroup.rb +0 -33
  234. data/cookbooks/nagios/definitions/host.rb +0 -33
  235. data/cookbooks/nagios/definitions/hostdependency.rb +0 -33
  236. data/cookbooks/nagios/definitions/hostescalation.rb +0 -34
  237. data/cookbooks/nagios/definitions/hostgroup.rb +0 -33
  238. data/cookbooks/nagios/definitions/nagios_conf.rb +0 -38
  239. data/cookbooks/nagios/definitions/resource.rb +0 -33
  240. data/cookbooks/nagios/definitions/service.rb +0 -33
  241. data/cookbooks/nagios/definitions/servicedependency.rb +0 -33
  242. data/cookbooks/nagios/definitions/serviceescalation.rb +0 -34
  243. data/cookbooks/nagios/definitions/servicegroup.rb +0 -33
  244. data/cookbooks/nagios/definitions/timeperiod.rb +0 -33
  245. data/cookbooks/nagios/libraries/base.rb +0 -314
  246. data/cookbooks/nagios/libraries/command.rb +0 -91
  247. data/cookbooks/nagios/libraries/contact.rb +0 -230
  248. data/cookbooks/nagios/libraries/contactgroup.rb +0 -112
  249. data/cookbooks/nagios/libraries/custom_option.rb +0 -36
  250. data/cookbooks/nagios/libraries/data_bag_helper.rb +0 -23
  251. data/cookbooks/nagios/libraries/default.rb +0 -90
  252. data/cookbooks/nagios/libraries/host.rb +0 -412
  253. data/cookbooks/nagios/libraries/hostdependency.rb +0 -181
  254. data/cookbooks/nagios/libraries/hostescalation.rb +0 -173
  255. data/cookbooks/nagios/libraries/hostgroup.rb +0 -119
  256. data/cookbooks/nagios/libraries/nagios.rb +0 -282
  257. data/cookbooks/nagios/libraries/resource.rb +0 -59
  258. data/cookbooks/nagios/libraries/service.rb +0 -455
  259. data/cookbooks/nagios/libraries/servicedependency.rb +0 -215
  260. data/cookbooks/nagios/libraries/serviceescalation.rb +0 -195
  261. data/cookbooks/nagios/libraries/servicegroup.rb +0 -144
  262. data/cookbooks/nagios/libraries/timeperiod.rb +0 -160
  263. data/cookbooks/nagios/libraries/users_helper.rb +0 -54
  264. data/cookbooks/nagios/metadata.rb +0 -25
  265. data/cookbooks/nagios/recipes/_load_databag_config.rb +0 -153
  266. data/cookbooks/nagios/recipes/_load_default_config.rb +0 -241
  267. data/cookbooks/nagios/recipes/apache.rb +0 -48
  268. data/cookbooks/nagios/recipes/default.rb +0 -204
  269. data/cookbooks/nagios/recipes/nginx.rb +0 -82
  270. data/cookbooks/nagios/recipes/pagerduty.rb +0 -143
  271. data/cookbooks/nagios/recipes/server_package.rb +0 -40
  272. data/cookbooks/nagios/recipes/server_source.rb +0 -164
  273. data/cookbooks/nagios/templates/default/apache2.conf.erb +0 -96
  274. data/cookbooks/nagios/templates/default/cgi.cfg.erb +0 -266
  275. data/cookbooks/nagios/templates/default/commands.cfg.erb +0 -13
  276. data/cookbooks/nagios/templates/default/contacts.cfg.erb +0 -37
  277. data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +0 -25
  278. data/cookbooks/nagios/templates/default/hosts.cfg.erb +0 -15
  279. data/cookbooks/nagios/templates/default/htpasswd.users.erb +0 -6
  280. data/cookbooks/nagios/templates/default/nagios.cfg.erb +0 -22
  281. data/cookbooks/nagios/templates/default/nginx.conf.erb +0 -62
  282. data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +0 -185
  283. data/cookbooks/nagios/templates/default/resource.cfg.erb +0 -27
  284. data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +0 -15
  285. data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +0 -14
  286. data/cookbooks/nagios/templates/default/services.cfg.erb +0 -14
  287. data/cookbooks/nagios/templates/default/templates.cfg.erb +0 -31
  288. data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +0 -13
  289. data/extras/image-generators/aws/centos6.yaml +0 -18
  290. data/modules/mu/defaults/google_images.yaml +0 -16
  291. data/roles/mu-master-jenkins.json +0 -24
@@ -20,21 +20,11 @@ module MU
20
20
  # An Amazon CloudFormation stack as configured in {MU::Config::BasketofKittens::collections}
21
21
  class Collection < MU::Cloud::Collection
22
22
 
23
- @deploy = nil
24
- @config = nil
25
- attr_reader :mu_name
26
- attr_reader :cloud_id
27
-
28
- # @param mommacat [MU::MommaCat]: A {MU::Mommacat} object containing the deploy of which this resource is/will be a member.
29
- # @param kitten_cfg [Hash]: The fully parsed and resolved {MU::Config} resource descriptor as defined in {MU::Config::BasketofKittens::vpcs}
30
- def initialize(mommacat: nil, kitten_cfg: nil, mu_name: nil, cloud_id: nil)
31
- @deploy = mommacat
32
- @config = MU::Config.manxify(kitten_cfg)
33
- if !mu_name.nil?
34
- @mu_name = mu_name
35
- else
36
- @mu_name = @deploy.getResourceName(@config['name'], need_unique_string: true)
37
- end
23
+ # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like +@vpc+, for us.
24
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
25
+ def initialize(**args)
26
+ super
27
+ @mu_name ||= @deploy.getResourceName(@config['name'], need_unique_string: true)
38
28
  MU.setVar("curRegion", @config['region']) if !@config['region'].nil?
39
29
  end
40
30
 
@@ -104,7 +94,7 @@ module MU
104
94
  else
105
95
  # json file and template path is same
106
96
  file_dir =File.dirname(ARGV[0])
107
- if File.exists? file_dir+"/"+@config["template_file"] then
97
+ if File.exist? file_dir+"/"+@config["template_file"] then
108
98
  template_body=File.read(file_dir+"/"+@config["template_file"]);
109
99
  end
110
100
  end
@@ -158,7 +148,7 @@ module MU
158
148
 
159
149
  case resource.resource_type
160
150
  when "AWS::EC2::Instance"
161
- MU::MommaCat.createStandardTags(resource.physical_resource_id)
151
+ MU::Cloud::AWS.createStandardTags(resource.physical_resource_id)
162
152
  instance_name = MU.deploy_id+"-"+@config['name']+"-"+resource.logical_resource_id
163
153
  MU::MommaCat.createTag(resource.physical_resource_id, "Name", instance_name, credentials: @config['credentials'])
164
154
 
@@ -186,14 +176,14 @@ module MU
186
176
  end
187
177
 
188
178
  when "AWS::EC2::SecurityGroup"
189
- MU::MommaCat.createStandardTags(resource.physical_resource_id)
179
+ MU::Cloud::AWS.createStandardTags(resource.physical_resource_id)
190
180
  MU::MommaCat.createTag(resource.physical_resource_id, "Name", MU.deploy_id+"-"+@config['name']+'-'+resource.logical_resource_id, credentials: @config['credentials'])
191
181
  MU::Cloud::AWS::FirewallRule.notifyDeploy(
192
182
  @config['name']+"-"+resource.logical_resource_id,
193
183
  resource.physical_resource_id
194
184
  )
195
185
  when "AWS::EC2::Subnet"
196
- MU::MommaCat.createStandardTags(resource.physical_resource_id)
186
+ MU::Cloud::AWS.createStandardTags(resource.physical_resource_id)
197
187
  MU::MommaCat.createTag(resource.physical_resource_id, "Name", MU.deploy_id+"-"+@config['name']+'-'+resource.logical_resource_id, credentials: @config['credentials'])
198
188
  data = {
199
189
  "collection" => @config["name"],
@@ -201,7 +191,7 @@ module MU
201
191
  }
202
192
  @deploy.notify("subnets", @config['name']+"-"+resource.logical_resource_id, data)
203
193
  when "AWS::EC2::VPC"
204
- MU::MommaCat.createStandardTags(resource.physical_resource_id)
194
+ MU::Cloud::AWS.createStandardTags(resource.physical_resource_id)
205
195
  MU::MommaCat.createTag(resource.physical_resource_id, "Name", MU.deploy_id+"-"+@config['name']+'-'+resource.logical_resource_id, credentials: @config['credentials'])
206
196
  data = {
207
197
  "collection" => @config["name"],
@@ -209,10 +199,10 @@ module MU
209
199
  }
210
200
  @deploy.notify("vpcs", @config['name']+"-"+resource.logical_resource_id, data)
211
201
  when "AWS::EC2::InternetGateway"
212
- MU::MommaCat.createStandardTags(resource.physical_resource_id)
202
+ MU::Cloud::AWS.createStandardTags(resource.physical_resource_id)
213
203
  MU::MommaCat.createTag(resource.physical_resource_id, "Name", MU.deploy_id+"-"+@config['name']+'-'+resource.logical_resource_id, credentials: @config['credentials'])
214
204
  when "AWS::EC2::RouteTable"
215
- MU::MommaCat.createStandardTags(resource.physical_resource_id)
205
+ MU::Cloud::AWS.createStandardTags(resource.physical_resource_id)
216
206
  MU::MommaCat.createTag(resource.physical_resource_id, "Name", MU.deploy_id+"-"+@config['name']+'-'+resource.logical_resource_id, credentials: @config['credentials'])
217
207
 
218
208
  # The rest of these aren't anything we act on
@@ -17,26 +17,12 @@ module MU
17
17
  class AWS
18
18
  # A ContainerCluster as configured in {MU::Config::BasketofKittens::container_clusters}
19
19
  class ContainerCluster < MU::Cloud::ContainerCluster
20
- @deploy = nil
21
- @config = nil
22
- attr_reader :mu_name
23
- attr_reader :config
24
- attr_reader :cloud_id
25
-
26
- @cloudformation_data = {}
27
- attr_reader :cloudformation_data
28
- # Return the list of regions where we know EKS is supported.
29
- def self.EKSRegions
30
- # XXX would prefer to query service API for this
31
- ["us-east-1", "us-west-2", "eu-west-1"]
32
- end
33
20
 
34
- # @param mommacat [MU::MommaCat]: A {MU::Mommacat} object containing the deploy of which this resource is/will be a member.
35
- # @param kitten_cfg [Hash]: The fully parsed and resolved {MU::Config} resource descriptor as defined in {MU::Config::BasketofKittens::container_clusters}
36
- def initialize(mommacat: nil, kitten_cfg: nil, mu_name: nil, cloud_id: nil)
37
- @deploy = mommacat
38
- @config = MU::Config.manxify(kitten_cfg)
39
- @cloud_id ||= cloud_id
21
+
22
+ # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like +@vpc+, for us.
23
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
24
+ def initialize(**args)
25
+ super
40
26
  @mu_name ||= @deploy.getResourceName(@config["name"])
41
27
  end
42
28
 
@@ -101,14 +87,13 @@ module MU
101
87
  retry
102
88
  end
103
89
  rescue Aws::EKS::Errors::InvalidParameterException => e
104
- if e.message.match(/role with arn: #{Regexp.quote(role_arn)}.*?(could not be assumed|does not exist)/)
90
+ if e.message.match(/role with arn: #{Regexp.quote(role_arn)}.*?(could not be assumed|does not exist)/i)
105
91
  sleep 5
106
92
  retry
107
93
  else
108
94
  MU.log e.message, MU::WARN, details: role_arn
109
95
  sleep 5
110
96
  retry
111
- puts e.message
112
97
  end
113
98
  end
114
99
 
@@ -119,6 +104,9 @@ module MU
119
104
  name: @mu_name
120
105
  )
121
106
  status = resp.cluster.status
107
+ if status == "FAILED"
108
+ raise MuError, "EKS cluster #{@mu_name} had FAILED status"
109
+ end
122
110
  if retries > 0 and (retries % 3) == 0 and status != "ACTIVE"
123
111
  MU.log "Waiting for EKS cluster #{@mu_name} to become active (currently #{status})", MU::NOTICE
124
112
  end
@@ -153,8 +141,18 @@ module MU
153
141
  serverpool = @deploy.findLitterMate(type: "server_pools", name: @config["name"]+"workers")
154
142
  resource_lookup = MU::Cloud::AWS.listInstanceTypes(@config['region'])[@config['region']]
155
143
 
156
- if @config['kubernetes']
157
- kube = ERB.new(File.read(MU.myRoot+"/cookbooks/mu-tools/templates/default/kubeconfig.erb"))
144
+ if @config['flavor'] == "EKS"
145
+ # This will be needed if a loadbalancer has never been created in
146
+ # this account; EKS applications might want one, but will fail in
147
+ # confusing ways if this hasn't been done.
148
+ begin
149
+ MU::Cloud::AWS.iam(credentials: @config['credentials']).create_service_linked_role(
150
+ aws_service_name: "elasticloadbalancing.amazonaws.com"
151
+ )
152
+ rescue ::Aws::IAM::Errors::InvalidInput
153
+ end
154
+
155
+ kube = ERB.new(File.read(MU.myRoot+"/cookbooks/mu-tools/templates/default/kubeconfig-eks.erb"))
158
156
  configmap = ERB.new(File.read(MU.myRoot+"/extras/aws-auth-cm.yaml.erb"))
159
157
  tagme = [@vpc.cloud_id]
160
158
  tagme_elb = []
@@ -167,7 +165,7 @@ module MU
167
165
  ).route_tables
168
166
  tagme.concat(rtbs.map { |r| r.route_table_id } )
169
167
  main_sg = @deploy.findLitterMate(type: "firewall_rules", name: "server_pool#{@config['name']}workers")
170
- tagme << main_sg.cloud_id
168
+ tagme << main_sg.cloud_id if main_sg
171
169
  MU.log "Applying kubernetes.io tags to VPC resources", details: tagme
172
170
  MU::Cloud::AWS.createTag("kubernetes.io/cluster/#{@mu_name}", "shared", tagme, credentials: @config['credentials'])
173
171
  MU::Cloud::AWS.createTag("kubernetes.io/cluster/elb", @mu_name, tagme_elb, credentials: @config['credentials'])
@@ -192,38 +190,27 @@ module MU
192
190
  File.open(gitlab_helper, "w"){ |k|
193
191
  k.puts gitlab.result(binding)
194
192
  }
193
+ authmap_cmd = %Q{#{MU::Master.kubectl} --kubeconfig "#{kube_conf}" apply -f "#{eks_auth}"}
195
194
 
196
- authmap_cmd = %Q{/opt/mu/bin/kubectl --kubeconfig "#{kube_conf}" apply -f "#{eks_auth}"}
195
+ authmap_cmd = %Q{#{MU::Master.kubectl} --kubeconfig "#{kube_conf}" apply -f "#{eks_auth}"}
197
196
  MU.log "Configuring Kubernetes <=> IAM mapping for worker nodes", MU::NOTICE, details: authmap_cmd
198
197
  # maybe guard this mess
199
198
  %x{#{authmap_cmd}}
200
199
 
201
200
  # and this one
202
- admin_user_cmd = %Q{/opt/mu/bin/kubectl --kubeconfig "#{kube_conf}" apply -f "#{MU.myRoot}/extras/admin-user.yaml"}
203
- admin_role_cmd = %Q{/opt/mu/bin/kubectl --kubeconfig "#{kube_conf}" apply -f "#{MU.myRoot}/extras/admin-role-binding.yaml"}
201
+ admin_user_cmd = %Q{#{MU::Master.kubectl} --kubeconfig "#{kube_conf}" apply -f "#{MU.myRoot}/extras/admin-user.yaml"}
202
+ admin_role_cmd = %Q{#{MU::Master.kubectl} --kubeconfig "#{kube_conf}" apply -f "#{MU.myRoot}/extras/admin-role-binding.yaml"}
204
203
  MU.log "Configuring Kubernetes admin-user and role", MU::NOTICE, details: admin_user_cmd+"\n"+admin_role_cmd
205
204
  %x{#{admin_user_cmd}}
206
205
  %x{#{admin_role_cmd}}
207
206
 
208
207
  if @config['kubernetes_resources']
209
- count = 0
210
- @config['kubernetes_resources'].each { |blob|
211
- blobfile = @deploy.deploy_dir+"/k8s-resource-#{count.to_s}-#{@config['name']}"
212
- File.open(blobfile, "w") { |f|
213
- f.puts blob.to_yaml
214
- }
215
- %x{/opt/mu/bin/kubectl --kubeconfig "#{kube_conf}" get -f #{blobfile} > /dev/null 2>&1}
216
- arg = $?.exitstatus == 0 ? "replace" : "create"
217
- cmd = %Q{/opt/mu/bin/kubectl --kubeconfig "#{kube_conf}" #{arg} -f #{blobfile}}
218
- MU.log "Applying Kubernetes resource #{count.to_s} with kubectl #{arg}", details: cmd
219
- output = %x{#{cmd} 2>&1}
220
- if $?.exitstatus == 0
221
- MU.log "Kuberentes resource #{count.to_s} #{arg} was successful: #{output}", details: blob.to_yaml
222
- else
223
- MU.log "Kuberentes resource #{count.to_s} #{arg} failed: #{output}", MU::WARN, details: blob.to_yaml
224
- end
225
- count += 1
226
- }
208
+ MU::Master.applyKubernetesResources(
209
+ @config['name'],
210
+ @config['kubernetes_resources'],
211
+ kubeconfig: kube_conf,
212
+ outputdir: @deploy.deploy_dir
213
+ )
227
214
  end
228
215
 
229
216
  MU.log %Q{How to interact with your Kubernetes cluster\nkubectl --kubeconfig "#{kube_conf}" get all\nkubectl --kubeconfig "#{kube_conf}" create -f some_k8s_deploy.yml\nkubectl --kubeconfig "#{kube_conf}" get nodes}, MU::SUMMARY
@@ -329,7 +316,7 @@ module MU
329
316
  created_generic_loggroup = false
330
317
 
331
318
  @config['containers'].each { |c|
332
- service_name = c['service'] ? @mu_name+"-"+c['service'].upcase : @mu_name+"-"+c['name'].upcase
319
+ service_name = c['service'] ? @mu_name+"-"+c['service'].upcase : @mu_name
333
320
  tasks[service_name] ||= []
334
321
  tasks[service_name] << c
335
322
  }
@@ -339,8 +326,10 @@ module MU
339
326
  cpu_total = 0
340
327
  mem_total = 0
341
328
  role_arn = nil
329
+ lbs = []
342
330
 
343
331
  container_definitions = containers.map { |c|
332
+ container_name = @mu_name+"-"+c['name'].upcase
344
333
  cpu_total += c['cpu']
345
334
  mem_total += c['memory']
346
335
 
@@ -362,6 +351,50 @@ module MU
362
351
  raise MuError, "Unable to find execution role from #{c["role"]}"
363
352
  end
364
353
  end
354
+
355
+ if c['loadbalancers'] != []
356
+ c['loadbalancers'].each {|lb|
357
+ found = @deploy.findLitterMate(name: lb['name'], type: "loadbalancer")
358
+ if found
359
+ MU.log "Mapping LB #{found.mu_name} to service #{c['name']}", MU::INFO
360
+ if found.cloud_desc.type != "classic"
361
+ elb_groups = MU::Cloud::AWS.elb2(region: @config['region'], credentials: @config['credentials']).describe_target_groups({
362
+ load_balancer_arn: found.cloud_desc.load_balancer_arn
363
+ })
364
+ matching_target_groups = []
365
+ elb_groups.target_groups.each { |tg|
366
+ if tg.port.to_i == lb['container_port'].to_i
367
+ matching_target_groups << {
368
+ arn: tg['target_group_arn'],
369
+ name: tg['target_group_name']
370
+ }
371
+ end
372
+ }
373
+ if matching_target_groups.length >= 1
374
+ MU.log "#{matching_target_groups.length} matching target groups found. Mapping #{container_name} to target group #{matching_target_groups.first['name']}", MU::INFO
375
+ lbs << {
376
+ container_name: container_name,
377
+ container_port: lb['container_port'],
378
+ target_group_arn: matching_target_groups.first[:arn]
379
+ }
380
+ else
381
+ raise MuError, "No matching target groups found"
382
+ end
383
+ elsif @config['flavor'] == "Fargate" && found.cloud_desc.type == "classic"
384
+ raise MuError, "Classic Load Balancers are not supported with Fargate."
385
+ else
386
+ MU.log "Mapping Classic LB #{found.mu_name} to service #{container_name}", MU::INFO
387
+ lbs << {
388
+ container_name: container_name,
389
+ container_port: lb['container_port'],
390
+ load_balancer_name: found.mu_name
391
+ }
392
+ end
393
+ else
394
+ raise MuError, "Unable to find loadbalancers from #{c["loadbalancers"].first['name']}"
395
+ end
396
+ }
397
+ end
365
398
 
366
399
  params = {
367
400
  name: @mu_name+"-"+c['name'].upcase,
@@ -451,13 +484,13 @@ module MU
451
484
  resp = MU::Cloud::AWS.ecs(region: @config['region'], credentials: @config['credentials']).register_task_definition(task_params)
452
485
 
453
486
  task_def = resp.task_definition.task_definition_arn
454
-
455
487
  service_params = {
456
488
  :cluster => @mu_name,
457
489
  :desired_count => @config['instance_count'], # XXX this makes no sense
458
490
  :service_name => service_name,
459
491
  :launch_type => launch_type,
460
- :task_definition => task_def
492
+ :task_definition => task_def,
493
+ :load_balancers => lbs
461
494
  }
462
495
  if @config['vpc']
463
496
  subnet_ids = []
@@ -651,52 +684,68 @@ MU.log c.name, MU::NOTICE, details: t
651
684
  return deploy_struct
652
685
  end
653
686
 
687
+ @@eks_versions = {}
688
+ @@eks_version_semaphore = Mutex.new
654
689
  # Use the AWS SSM API to fetch the current version of the Amazon Linux
655
690
  # ECS-optimized AMI, so we can use it as a default AMI for ECS deploys.
656
691
  # @param flavor [String]: ECS or EKS
657
- def self.getECSImageId(flavor = "ECS", region = MU.myRegion)
658
- if flavor == "ECS"
659
- resp = MU::Cloud::AWS.ssm(region: region).get_parameters(
692
+ # @param region [String]: Target AWS region
693
+ # @param version [String]: Version of Kubernetes, if +flavor+ is set to +EKS+
694
+ # @param gpu [Boolean]: Whether to request an image with GPU support
695
+ def self.getStandardImage(flavor = "ECS", region = MU.myRegion, version: nil, gpu: false)
696
+ resp = if flavor == "ECS"
697
+ MU::Cloud::AWS.ssm(region: region).get_parameters(
660
698
  names: ["/aws/service/#{flavor.downcase}/optimized-ami/amazon-linux/recommended"]
661
699
  )
662
- if resp and resp.parameters and resp.parameters.size > 0
663
- image_details = JSON.parse(resp.parameters.first.value)
664
- return image_details['image_id']
665
- end
666
- elsif flavor == "EKS"
667
- # XXX this is absurd, but these don't appear to be available from an API anywhere
668
- # Here's their Packer build, should just convert to Chef: https://github.com/awslabs/amazon-eks-ami
669
- amis = {
670
- "us-east-1" => "ami-0abcb9f9190e867ab",
671
- "us-east-2" => "ami-04ea7cb66af82ae4a",
672
- "us-west-2" => "ami-0923e4b35a30a5f53",
673
- "eu-west-1" => "ami-08716b70cac884aaa",
674
- "eu-west-2" => "ami-0c7388116d474ee10",
675
- "eu-west-3" => "ami-0560aea042fec8b12",
676
- "ap-northeast-1" => "ami-0bfedee6a7845c26d",
677
- "ap-northeast-2" => "ami-0a904348b703e620c",
678
- "ap-south-1" => "ami-09c3eb35bb3be46a4",
679
- "ap-southeast-1" => "ami-07b922b9b94d9a6d2",
680
- "ap-southeast-2" => "ami-0f0121e9e64ebd3dc"
700
+ else
701
+ @@eks_version_semaphore.synchronize {
702
+ if !@@eks_versions[region]
703
+ @@eks_versions[region] ||= []
704
+ versions = {}
705
+ resp = nil
706
+ next_token = nil
707
+ begin
708
+ resp = MU::Cloud::AWS.ssm(region: region).get_parameters_by_path(
709
+ path: "/aws/service/#{flavor.downcase}",
710
+ recursive: true,
711
+ next_token: next_token
712
+ )
713
+ resp.parameters.each { |p|
714
+ p.name.match(/\/aws\/service\/eks\/optimized-ami\/([^\/]+?)\//)
715
+ versions[Regexp.last_match[1]] = true
716
+ }
717
+ next_token = resp.next_token
718
+ end while !next_token.nil?
719
+ @@eks_versions[region] = versions.keys.sort { |a, b| MU.version_sort(a, b) }
720
+ end
681
721
  }
682
- return amis[region]
722
+ if !version or version == "latest"
723
+ version = @@eks_versions[region].last
724
+ end
725
+ MU::Cloud::AWS.ssm(region: region).get_parameters(
726
+ names: ["/aws/service/#{flavor.downcase}/optimized-ami/#{version}/amazon-linux-2#{gpu ? "-gpu" : ""}/recommended"]
727
+ )
683
728
  end
684
- nil
685
- end
686
729
 
687
- # Use the AWS SSM API to fetch the current version of the Amazon Linux
688
- # EKS-optimized AMI, so we can use it as a default AMI for EKS deploys.
689
- def self.getEKSImageId(region = MU.myRegion)
690
- resp = MU::Cloud::AWS.ssm(region: region).get_parameters(
691
- names: ["/aws/service/ekss/optimized-ami/amazon-linux/recommended"]
692
- )
693
730
  if resp and resp.parameters and resp.parameters.size > 0
694
731
  image_details = JSON.parse(resp.parameters.first.value)
695
732
  return image_details['image_id']
696
733
  end
734
+
697
735
  nil
698
736
  end
699
737
 
738
+ # Return the list of regions where we know EKS is supported.
739
+ def self.EKSRegions(credentials = nil)
740
+ eks_regions = []
741
+ MU::Cloud::AWS.listRegions(credentials: credentials).each { |r|
742
+ ami = getStandardImage("EKS", r)
743
+ eks_regions << r if ami
744
+ }
745
+
746
+ eks_regions
747
+ end
748
+
700
749
  # Does this resource type exist as a global (cloud-wide) artifact, or
701
750
  # is it localized to a region/zone?
702
751
  # @return [Boolean]
@@ -718,6 +767,7 @@ MU.log c.name, MU::NOTICE, details: t
718
767
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
719
768
  resp = MU::Cloud::AWS.ecs(credentials: credentials, region: region).list_clusters
720
769
 
770
+
721
771
  if resp and resp.cluster_arns and resp.cluster_arns.size > 0
722
772
  resp.cluster_arns.each { |arn|
723
773
  if arn.match(/:cluster\/(#{MU.deploy_id}[^:]+)$/)
@@ -744,8 +794,8 @@ MU.log c.name, MU::NOTICE, details: t
744
794
  cluster: cluster
745
795
  })
746
796
  if instances
747
- instances.container_instance_arns.each { |arn|
748
- uuid = arn.sub(/^.*?:container-instance\//, "")
797
+ instances.container_instance_arns.each { |instance_arn|
798
+ uuid = instance_arn.sub(/^.*?:container-instance\//, "")
749
799
  MU.log "Deregistering instance #{uuid} from ECS Cluster #{cluster}"
750
800
  if !noop
751
801
  resp = MU::Cloud::AWS.ecs(credentials: credentials, region: region).deregister_container_instance({
@@ -775,6 +825,7 @@ MU.log c.name, MU::NOTICE, details: t
775
825
  tasks = MU::Cloud::AWS.ecs(region: region, credentials: credentials).list_task_definitions(
776
826
  family_prefix: MU.deploy_id
777
827
  )
828
+
778
829
  if tasks and tasks.task_definition_arns
779
830
  tasks.task_definition_arns.each { |arn|
780
831
  MU.log "Deregistering Fargate task definition #{arn}"
@@ -788,8 +839,14 @@ MU.log c.name, MU::NOTICE, details: t
788
839
 
789
840
  return if !MU::Cloud::AWS::ContainerCluster.EKSRegions.include?(region)
790
841
 
842
+ resp = begin
843
+ MU::Cloud::AWS.eks(credentials: credentials, region: region).list_clusters
844
+ rescue Aws::EKS::Errors::AccessDeniedException
845
+ # EKS isn't actually live in this region, even though SSM lists
846
+ # base images for it
847
+ return
848
+ end
791
849
 
792
- resp = MU::Cloud::AWS.eks(credentials: credentials, region: region).list_clusters
793
850
 
794
851
  if resp and resp.clusters
795
852
  resp.clusters.each { |cluster|
@@ -865,17 +922,24 @@ MU.log c.name, MU::NOTICE, details: t
865
922
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
866
923
  def self.schema(config)
867
924
  toplevel_required = []
925
+
868
926
  schema = {
869
927
  "flavor" => {
870
- "enum" => ["ECS", "EKS", "Fargate"],
928
+ "enum" => ["ECS", "EKS", "Fargate", "Kubernetes"],
929
+ "type" => "string",
930
+ "description" => "The AWS container platform to deploy",
871
931
  "default" => "ECS"
872
932
  },
873
933
  "kubernetes" => {
874
- "default" => { "version" => "1.11" }
934
+ "default" => { "version" => "latest" }
935
+ },
936
+ "gpu" => {
937
+ "type" => "boolean",
938
+ "default" => false,
939
+ "description" => "Enable worker nodes with GPU capabilities"
875
940
  },
876
941
  "platform" => {
877
- "description" => "The platform to choose for worker nodes. Will default to Amazon Linux for ECS, CentOS 7 for everything else. Only valid for EKS and ECS flavors.",
878
- "default" => "centos7"
942
+ "description" => "The platform to choose for worker nodes."
879
943
  },
880
944
  "ami_id" => {
881
945
  "type" => "string",
@@ -1415,6 +1479,25 @@ MU.log c.name, MU::NOTICE, details: t
1415
1479
  "description" => "Per-driver configuration options. See also: https://docs.aws.amazon.com/sdkforruby/api/Aws/ECS/Types/ContainerDefinition.html#log_configuration-instance_method"
1416
1480
  }
1417
1481
  }
1482
+ },
1483
+ "loadbalancers" => {
1484
+ "type" => "array",
1485
+ "description" => "Array of loadbalancers to associate with this container servvice See also: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ECS/Client.html#create_service-instance_method",
1486
+ "default" => [],
1487
+ "items" => {
1488
+ "description" => "Load Balancers to associate with the container services",
1489
+ "type" => "object",
1490
+ "properties" => {
1491
+ "name" => {
1492
+ "type" => "string",
1493
+ "description" => "Name of the loadbalancer to associate"
1494
+ },
1495
+ "container_port" => {
1496
+ "type" => "integer",
1497
+ "description" => "container port to map to the loadbalancer"
1498
+ }
1499
+ }
1500
+ }
1418
1501
  }
1419
1502
  }
1420
1503
  }
@@ -1433,6 +1516,8 @@ MU.log c.name, MU::NOTICE, details: t
1433
1516
  cluster['size'] = MU::Cloud::AWS::Server.validateInstanceType(cluster["instance_type"], cluster["region"])
1434
1517
  ok = false if cluster['size'].nil?
1435
1518
 
1519
+ cluster["flavor"] = "EKS" if cluster["flavor"].match(/^Kubernetes$/i)
1520
+
1436
1521
  if cluster["flavor"] == "ECS" and cluster["kubernetes"] and !MU::Cloud::AWS.isGovCloud?(cluster["region"])
1437
1522
  cluster["flavor"] = "EKS"
1438
1523
  MU.log "Setting flavor of ContainerCluster '#{cluster['name']}' to EKS ('kubernetes' stanza was specified)", MU::NOTICE
@@ -1455,6 +1540,7 @@ MU.log c.name, MU::NOTICE, details: t
1455
1540
  end
1456
1541
 
1457
1542
  if cluster["flavor"] != "EKS" and cluster["containers"]
1543
+ cluster.delete("kubernetes")
1458
1544
  created_generic_loggroup = false
1459
1545
  cluster['containers'].each { |c|
1460
1546
  if c['log_configuration'] and
@@ -1485,14 +1571,14 @@ MU.log c.name, MU::NOTICE, details: t
1485
1571
  logdesc = {
1486
1572
  "name" => logname,
1487
1573
  "region" => cluster["region"],
1488
- "cloud" => cluster["cloud"]
1574
+ "cloud" => "AWS"
1489
1575
  }
1490
1576
  configurator.insertKitten(logdesc, "logs")
1491
1577
 
1492
1578
  if !c['role']
1493
1579
  roledesc = {
1494
1580
  "name" => rolename,
1495
- "cloud" => cluster["cloud"],
1581
+ "cloud" => "AWS",
1496
1582
  "can_assume" => [
1497
1583
  {
1498
1584
  "entity_id" => "ecs-tasks.amazonaws.com",
@@ -1542,19 +1628,28 @@ MU.log c.name, MU::NOTICE, details: t
1542
1628
  end
1543
1629
 
1544
1630
  if cluster["flavor"] == "EKS" and !cluster["vpc"]
1545
- if !MU::Cloud::AWS.hosted?
1546
- MU.log "EKS cluster #{cluster['name']} must declare a VPC", MU::ERR
1547
- ok = false
1631
+ if !MU::Cloud::AWS.hosted? or !MU::Cloud::AWS.myVPCObj
1632
+ siblings = configurator.haveLitterMate?(nil, "vpcs", has_multiple: true)
1633
+ if siblings.size == 1
1634
+ MU.log "EKS cluster #{cluster['name']} did not declare a VPC. Inserting into an available sibling VPC.", MU::WARN
1635
+ cluster["vpc"] = {
1636
+ "name" => siblings[0]['name'],
1637
+ "subnet_pref" => "all_private"
1638
+ }
1639
+ else
1640
+ MU.log "EKS cluster #{cluster['name']} must declare a VPC", MU::ERR
1641
+ ok = false
1642
+ end
1548
1643
  else
1549
1644
  cluster["vpc"] = {
1550
- "vpc_id" => MU.myVPC,
1645
+ "id" => MU.myVPC,
1551
1646
  "subnet_pref" => "all_private"
1552
1647
  }
1553
1648
  end
1554
1649
  end
1555
1650
 
1556
1651
  if ["ECS", "EKS"].include?(cluster["flavor"])
1557
- std_ami = getECSImageId(cluster["flavor"], cluster['region'])
1652
+ std_ami = getStandardImage(cluster["flavor"], cluster['region'], version: cluster['kubernetes']['version'], gpu: cluster['gpu'])
1558
1653
  cluster["host_image"] ||= std_ami
1559
1654
  if cluster["host_image"] != std_ami
1560
1655
  if cluster["flavor"] == "ECS"
@@ -1582,41 +1677,36 @@ MU.log c.name, MU::NOTICE, details: t
1582
1677
 
1583
1678
  end
1584
1679
 
1680
+ fwname = "container_cluster#{cluster['name']}"
1681
+
1585
1682
  cluster['ingress_rules'] ||= []
1586
- if cluster['flavor'] == "ECS"
1683
+ if ["ECS", "EKS"].include?(cluster["flavor"])
1587
1684
  cluster['ingress_rules'] << {
1588
- "sgs" => ["server_pool#{cluster['name']}workers"],
1589
- "port" => 443
1685
+ "sgs" => ["server_pool"+cluster["name"]+"workers"],
1686
+ "port" => 443,
1687
+ "proto" => "tcp",
1688
+ "ingress" => true,
1689
+ "comment" => "Allow worker nodes to access API"
1590
1690
  }
1691
+ ruleset = configurator.haveLitterMate?(fwname, "firewall_rules")
1692
+ if ruleset
1693
+ ruleset["rules"].concat(cluster['ingress_rules'])
1694
+ ruleset["rules"].uniq!
1695
+ end
1591
1696
  end
1592
- fwname = "container_cluster#{cluster['name']}"
1593
-
1594
- acl = {
1595
- "name" => fwname,
1596
- "credentials" => cluster["credentials"],
1597
- "rules" => cluster['ingress_rules'],
1598
- "region" => cluster['region'],
1599
- "optional_tags" => cluster['optional_tags']
1600
- }
1601
- acl["tags"] = cluster['tags'] if cluster['tags'] && !cluster['tags'].empty?
1602
- acl["vpc"] = cluster['vpc'].dup if cluster['vpc']
1603
-
1604
- ok = false if !configurator.insertKitten(acl, "firewall_rules")
1605
- cluster["add_firewall_rules"] = [] if cluster["add_firewall_rules"].nil?
1606
- cluster["add_firewall_rules"] << {"rule_name" => fwname}
1607
- cluster["dependencies"] << {
1608
- "name" => fwname,
1609
- "type" => "firewall_rule",
1610
- }
1611
1697
 
1612
1698
  if ["ECS", "EKS"].include?(cluster["flavor"])
1699
+ cluster["max_size"] ||= cluster["instance_count"]
1700
+ cluster["min_size"] ||= cluster["instance_count"]
1613
1701
 
1614
1702
  worker_pool = {
1615
1703
  "name" => cluster["name"]+"workers",
1704
+ "cloud" => "AWS",
1705
+ "skipinitialupdates" => (cluster["flavor"] == "EKS"),
1616
1706
  "credentials" => cluster["credentials"],
1617
1707
  "region" => cluster['region'],
1618
- "min_size" => cluster["instance_count"],
1619
- "max_size" => cluster["instance_count"],
1708
+ "min_size" => cluster["min_size"],
1709
+ "max_size" => cluster["max_size"],
1620
1710
  "wait_for_nodes" => cluster["instance_count"],
1621
1711
  "ssh_user" => cluster["host_ssh_user"],
1622
1712
  "role_strip_path" => true,
@@ -1629,7 +1719,7 @@ MU.log c.name, MU::NOTICE, details: t
1629
1719
  }
1630
1720
  if cluster["flavor"] == "EKS"
1631
1721
  worker_pool["ingress_rules"] = [
1632
- "sgs" => ["container_cluster#{cluster['name']}"],
1722
+ "sgs" => [fwname],
1633
1723
  "port_range" => "1-65535"
1634
1724
  ]
1635
1725
  worker_pool["application_attributes"] ||= {}
@@ -1681,6 +1771,7 @@ MU.log c.name, MU::NOTICE, details: t
1681
1771
  role = {
1682
1772
  "name" => cluster["name"]+"controlplane",
1683
1773
  "credentials" => cluster["credentials"],
1774
+ "cloud" => "AWS",
1684
1775
  "can_assume" => [
1685
1776
  { "entity_id" => "eks.amazonaws.com", "entity_type" => "service" }
1686
1777
  ],