You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

648 lines
24 KiB

  1. data "openstack_images_image_v2" "vm_image" {
  2. count = var.image_uuid == "" ? 1 : 0
  3. most_recent = true
  4. name = var.image
  5. }
  6. data "openstack_images_image_v2" "gfs_image" {
  7. count = var.image_gfs_uuid == "" ? var.image_uuid == "" ? 1 : 0 : 0
  8. most_recent = true
  9. name = var.image_gfs == "" ? var.image : var.image_gfs
  10. }
  11. data "openstack_images_image_v2" "image_master" {
  12. count = var.image_master_uuid == "" ? var.image_uuid == "" ? 1 : 0 : 0
  13. name = var.image_master == "" ? var.image : var.image_master
  14. }
  15. resource "openstack_compute_keypair_v2" "k8s" {
  16. name = "kubernetes-${var.cluster_name}"
  17. public_key = chomp(file(var.public_key_path))
  18. }
  19. resource "openstack_networking_secgroup_v2" "k8s_master" {
  20. name = "${var.cluster_name}-k8s-master"
  21. description = "${var.cluster_name} - Kubernetes Master"
  22. delete_default_rules = true
  23. }
  24. resource "openstack_networking_secgroup_v2" "k8s_master_extra" {
  25. count = "%{if var.extra_sec_groups}1%{else}0%{endif}"
  26. name = "${var.cluster_name}-k8s-master-${var.extra_sec_groups_name}"
  27. description = "${var.cluster_name} - Kubernetes Master nodes - rules not managed by terraform"
  28. delete_default_rules = true
  29. }
  30. resource "openstack_networking_secgroup_rule_v2" "k8s_master" {
  31. count = length(var.master_allowed_remote_ips)
  32. direction = "ingress"
  33. ethertype = "IPv4"
  34. protocol = "tcp"
  35. port_range_min = "6443"
  36. port_range_max = "6443"
  37. remote_ip_prefix = var.master_allowed_remote_ips[count.index]
  38. security_group_id = openstack_networking_secgroup_v2.k8s_master.id
  39. }
  40. resource "openstack_networking_secgroup_rule_v2" "k8s_master_ports" {
  41. count = length(var.master_allowed_ports)
  42. direction = "ingress"
  43. ethertype = "IPv4"
  44. protocol = lookup(var.master_allowed_ports[count.index], "protocol", "tcp")
  45. port_range_min = lookup(var.master_allowed_ports[count.index], "port_range_min")
  46. port_range_max = lookup(var.master_allowed_ports[count.index], "port_range_max")
  47. remote_ip_prefix = lookup(var.master_allowed_ports[count.index], "remote_ip_prefix", "0.0.0.0/0")
  48. security_group_id = openstack_networking_secgroup_v2.k8s_master.id
  49. }
  50. resource "openstack_networking_secgroup_v2" "bastion" {
  51. name = "${var.cluster_name}-bastion"
  52. count = var.number_of_bastions != "" ? 1 : 0
  53. description = "${var.cluster_name} - Bastion Server"
  54. delete_default_rules = true
  55. }
  56. resource "openstack_networking_secgroup_rule_v2" "bastion" {
  57. count = var.number_of_bastions != "" ? length(var.bastion_allowed_remote_ips) : 0
  58. direction = "ingress"
  59. ethertype = "IPv4"
  60. protocol = "tcp"
  61. port_range_min = "22"
  62. port_range_max = "22"
  63. remote_ip_prefix = var.bastion_allowed_remote_ips[count.index]
  64. security_group_id = openstack_networking_secgroup_v2.bastion[0].id
  65. }
  66. resource "openstack_networking_secgroup_v2" "k8s" {
  67. name = "${var.cluster_name}-k8s"
  68. description = "${var.cluster_name} - Kubernetes"
  69. delete_default_rules = true
  70. }
  71. resource "openstack_networking_secgroup_rule_v2" "k8s" {
  72. direction = "ingress"
  73. ethertype = "IPv4"
  74. remote_group_id = openstack_networking_secgroup_v2.k8s.id
  75. security_group_id = openstack_networking_secgroup_v2.k8s.id
  76. }
  77. resource "openstack_networking_secgroup_rule_v2" "k8s_allowed_remote_ips" {
  78. count = length(var.k8s_allowed_remote_ips)
  79. direction = "ingress"
  80. ethertype = "IPv4"
  81. protocol = "tcp"
  82. port_range_min = "22"
  83. port_range_max = "22"
  84. remote_ip_prefix = var.k8s_allowed_remote_ips[count.index]
  85. security_group_id = openstack_networking_secgroup_v2.k8s.id
  86. }
  87. resource "openstack_networking_secgroup_rule_v2" "egress" {
  88. count = length(var.k8s_allowed_egress_ips)
  89. direction = "egress"
  90. ethertype = "IPv4"
  91. remote_ip_prefix = var.k8s_allowed_egress_ips[count.index]
  92. security_group_id = openstack_networking_secgroup_v2.k8s.id
  93. }
  94. resource "openstack_networking_secgroup_v2" "worker" {
  95. name = "${var.cluster_name}-k8s-worker"
  96. description = "${var.cluster_name} - Kubernetes worker nodes"
  97. delete_default_rules = true
  98. }
  99. resource "openstack_networking_secgroup_v2" "worker_extra" {
  100. count = "%{if var.extra_sec_groups}1%{else}0%{endif}"
  101. name = "${var.cluster_name}-k8s-worker-${var.extra_sec_groups_name}"
  102. description = "${var.cluster_name} - Kubernetes worker nodes - rules not managed by terraform"
  103. delete_default_rules = true
  104. }
  105. resource "openstack_networking_secgroup_rule_v2" "worker" {
  106. count = length(var.worker_allowed_ports)
  107. direction = "ingress"
  108. ethertype = "IPv4"
  109. protocol = lookup(var.worker_allowed_ports[count.index], "protocol", "tcp")
  110. port_range_min = lookup(var.worker_allowed_ports[count.index], "port_range_min")
  111. port_range_max = lookup(var.worker_allowed_ports[count.index], "port_range_max")
  112. remote_ip_prefix = lookup(var.worker_allowed_ports[count.index], "remote_ip_prefix", "0.0.0.0/0")
  113. security_group_id = openstack_networking_secgroup_v2.worker.id
  114. }
  115. resource "openstack_compute_servergroup_v2" "k8s_master" {
  116. count = "%{if var.use_server_groups}1%{else}0%{endif}"
  117. name = "k8s-master-srvgrp"
  118. policies = ["anti-affinity"]
  119. }
  120. resource "openstack_compute_servergroup_v2" "k8s_node" {
  121. count = "%{if var.use_server_groups}1%{else}0%{endif}"
  122. name = "k8s-node-srvgrp"
  123. policies = ["anti-affinity"]
  124. }
  125. resource "openstack_compute_servergroup_v2" "k8s_etcd" {
  126. count = "%{if var.use_server_groups}1%{else}0%{endif}"
  127. name = "k8s-etcd-srvgrp"
  128. policies = ["anti-affinity"]
  129. }
  130. locals {
  131. # master groups
  132. master_sec_groups = compact([
  133. openstack_networking_secgroup_v2.k8s_master.name,
  134. openstack_networking_secgroup_v2.k8s.name,
  135. var.extra_sec_groups ?openstack_networking_secgroup_v2.k8s_master_extra[0].name : "",
  136. ])
  137. # worker groups
  138. worker_sec_groups = compact([
  139. openstack_networking_secgroup_v2.k8s.name,
  140. openstack_networking_secgroup_v2.worker.name,
  141. var.extra_sec_groups ? openstack_networking_secgroup_v2.worker_extra[0].name : "",
  142. ])
  143. # Image uuid
  144. image_to_use_node = var.image_uuid != "" ? var.image_uuid : data.openstack_images_image_v2.vm_image[0].id
  145. # Image_gfs uuid
  146. image_to_use_gfs = var.image_gfs_uuid != "" ? var.image_gfs_uuid : var.image_uuid != "" ? var.image_uuid : data.openstack_images_image_v2.gfs_image[0].id
  147. # image_master uuidimage_gfs_uuid
  148. image_to_use_master = var.image_master_uuid != "" ? var.image_master_uuid : var.image_uuid != "" ? var.image_uuid : data.openstack_images_image_v2.image_master[0].id
  149. }
  150. resource "openstack_compute_instance_v2" "bastion" {
  151. name = "${var.cluster_name}-bastion-${count.index + 1}"
  152. count = var.number_of_bastions
  153. image_id = var.bastion_root_volume_size_in_gb == 0 ? local.image_to_use_node : null
  154. flavor_id = var.flavor_bastion
  155. key_pair = openstack_compute_keypair_v2.k8s.name
  156. dynamic "block_device" {
  157. for_each = var.bastion_root_volume_size_in_gb > 0 ? [local.image_to_use_node] : []
  158. content {
  159. uuid = local.image_to_use_node
  160. source_type = "image"
  161. volume_size = var.bastion_root_volume_size_in_gb
  162. boot_index = 0
  163. destination_type = "volume"
  164. delete_on_termination = true
  165. }
  166. }
  167. network {
  168. name = var.network_name
  169. }
  170. security_groups = [openstack_networking_secgroup_v2.k8s.name,
  171. element(openstack_networking_secgroup_v2.bastion.*.name, count.index),
  172. ]
  173. metadata = {
  174. ssh_user = var.ssh_user
  175. kubespray_groups = "bastion"
  176. depends_on = var.network_id
  177. use_access_ip = var.use_access_ip
  178. }
  179. provisioner "local-exec" {
  180. command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${var.bastion_fips[0]}/ > group_vars/no-floating.yml"
  181. }
  182. }
  183. resource "openstack_compute_instance_v2" "k8s_master" {
  184. name = "${var.cluster_name}-k8s-master-${count.index + 1}"
  185. count = var.number_of_k8s_masters
  186. availability_zone = element(var.az_list, count.index)
  187. image_id = var.master_root_volume_size_in_gb == 0 ? local.image_to_use_master : null
  188. flavor_id = var.flavor_k8s_master
  189. key_pair = openstack_compute_keypair_v2.k8s.name
  190. dynamic "block_device" {
  191. for_each = var.master_root_volume_size_in_gb > 0 ? [local.image_to_use_master] : []
  192. content {
  193. uuid = local.image_to_use_master
  194. source_type = "image"
  195. volume_size = var.master_root_volume_size_in_gb
  196. volume_type = var.master_volume_type
  197. boot_index = 0
  198. destination_type = "volume"
  199. delete_on_termination = true
  200. }
  201. }
  202. network {
  203. name = var.network_name
  204. }
  205. security_groups = local.master_sec_groups
  206. dynamic "scheduler_hints" {
  207. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
  208. content {
  209. group = openstack_compute_servergroup_v2.k8s_master[0].id
  210. }
  211. }
  212. metadata = {
  213. ssh_user = var.ssh_user
  214. kubespray_groups = "etcd,kube_control_plane,${var.supplementary_master_groups},k8s-cluster"
  215. depends_on = var.network_id
  216. use_access_ip = var.use_access_ip
  217. }
  218. provisioner "local-exec" {
  219. command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > group_vars/no-floating.yml"
  220. }
  221. }
  222. resource "openstack_compute_instance_v2" "k8s_master_no_etcd" {
  223. name = "${var.cluster_name}-k8s-master-ne-${count.index + 1}"
  224. count = var.number_of_k8s_masters_no_etcd
  225. availability_zone = element(var.az_list, count.index)
  226. image_id = var.master_root_volume_size_in_gb == 0 ? local.image_to_use_master : null
  227. flavor_id = var.flavor_k8s_master
  228. key_pair = openstack_compute_keypair_v2.k8s.name
  229. dynamic "block_device" {
  230. for_each = var.master_root_volume_size_in_gb > 0 ? [local.image_to_use_master] : []
  231. content {
  232. uuid = local.image_to_use_master
  233. source_type = "image"
  234. volume_size = var.master_root_volume_size_in_gb
  235. volume_type = var.master_volume_type
  236. boot_index = 0
  237. destination_type = "volume"
  238. delete_on_termination = true
  239. }
  240. }
  241. network {
  242. name = var.network_name
  243. }
  244. security_groups = local.master_sec_groups
  245. dynamic "scheduler_hints" {
  246. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
  247. content {
  248. group = openstack_compute_servergroup_v2.k8s_master[0].id
  249. }
  250. }
  251. metadata = {
  252. ssh_user = var.ssh_user
  253. kubespray_groups = "kube_control_plane,${var.supplementary_master_groups},k8s-cluster"
  254. depends_on = var.network_id
  255. use_access_ip = var.use_access_ip
  256. }
  257. provisioner "local-exec" {
  258. command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > group_vars/no-floating.yml"
  259. }
  260. }
  261. resource "openstack_compute_instance_v2" "etcd" {
  262. name = "${var.cluster_name}-etcd-${count.index + 1}"
  263. count = var.number_of_etcd
  264. availability_zone = element(var.az_list, count.index)
  265. image_id = var.etcd_root_volume_size_in_gb == 0 ? local.image_to_use_master : null
  266. flavor_id = var.flavor_etcd
  267. key_pair = openstack_compute_keypair_v2.k8s.name
  268. dynamic "block_device" {
  269. for_each = var.etcd_root_volume_size_in_gb > 0 ? [local.image_to_use_master] : []
  270. content {
  271. uuid = local.image_to_use_master
  272. source_type = "image"
  273. volume_size = var.etcd_root_volume_size_in_gb
  274. boot_index = 0
  275. destination_type = "volume"
  276. delete_on_termination = true
  277. }
  278. }
  279. network {
  280. name = var.network_name
  281. }
  282. security_groups = [openstack_networking_secgroup_v2.k8s.name]
  283. dynamic "scheduler_hints" {
  284. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_etcd[0]] : []
  285. content {
  286. group = openstack_compute_servergroup_v2.k8s_etcd[0].id
  287. }
  288. }
  289. metadata = {
  290. ssh_user = var.ssh_user
  291. kubespray_groups = "etcd,no-floating"
  292. depends_on = var.network_id
  293. use_access_ip = var.use_access_ip
  294. }
  295. }
  296. resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip" {
  297. name = "${var.cluster_name}-k8s-master-nf-${count.index + 1}"
  298. count = var.number_of_k8s_masters_no_floating_ip
  299. availability_zone = element(var.az_list, count.index)
  300. image_id = var.master_root_volume_size_in_gb == 0 ? local.image_to_use_master : null
  301. flavor_id = var.flavor_k8s_master
  302. key_pair = openstack_compute_keypair_v2.k8s.name
  303. dynamic "block_device" {
  304. for_each = var.master_root_volume_size_in_gb > 0 ? [local.image_to_use_master] : []
  305. content {
  306. uuid = local.image_to_use_master
  307. source_type = "image"
  308. volume_size = var.master_root_volume_size_in_gb
  309. volume_type = var.master_volume_type
  310. boot_index = 0
  311. destination_type = "volume"
  312. delete_on_termination = true
  313. }
  314. }
  315. network {
  316. name = var.network_name
  317. }
  318. security_groups = local.master_sec_groups
  319. dynamic "scheduler_hints" {
  320. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
  321. content {
  322. group = openstack_compute_servergroup_v2.k8s_master[0].id
  323. }
  324. }
  325. metadata = {
  326. ssh_user = var.ssh_user
  327. kubespray_groups = "etcd,kube_control_plane,${var.supplementary_master_groups},k8s-cluster,no-floating"
  328. depends_on = var.network_id
  329. use_access_ip = var.use_access_ip
  330. }
  331. }
  332. resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_no_etcd" {
  333. name = "${var.cluster_name}-k8s-master-ne-nf-${count.index + 1}"
  334. count = var.number_of_k8s_masters_no_floating_ip_no_etcd
  335. availability_zone = element(var.az_list, count.index)
  336. image_id = var.master_root_volume_size_in_gb == 0 ? local.image_to_use_master : null
  337. flavor_id = var.flavor_k8s_master
  338. key_pair = openstack_compute_keypair_v2.k8s.name
  339. dynamic "block_device" {
  340. for_each = var.master_root_volume_size_in_gb > 0 ? [local.image_to_use_master] : []
  341. content {
  342. uuid = local.image_to_use_master
  343. source_type = "image"
  344. volume_size = var.master_root_volume_size_in_gb
  345. volume_type = var.master_volume_type
  346. boot_index = 0
  347. destination_type = "volume"
  348. delete_on_termination = true
  349. }
  350. }
  351. network {
  352. name = var.network_name
  353. }
  354. security_groups = local.master_sec_groups
  355. dynamic "scheduler_hints" {
  356. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
  357. content {
  358. group = openstack_compute_servergroup_v2.k8s_master[0].id
  359. }
  360. }
  361. metadata = {
  362. ssh_user = var.ssh_user
  363. kubespray_groups = "kube_control_plane,${var.supplementary_master_groups},k8s-cluster,no-floating"
  364. depends_on = var.network_id
  365. use_access_ip = var.use_access_ip
  366. }
  367. }
  368. resource "openstack_compute_instance_v2" "k8s_node" {
  369. name = "${var.cluster_name}-k8s-node-${count.index + 1}"
  370. count = var.number_of_k8s_nodes
  371. availability_zone = element(var.az_list_node, count.index)
  372. image_id = var.node_root_volume_size_in_gb == 0 ? local.image_to_use_node : null
  373. flavor_id = var.flavor_k8s_node
  374. key_pair = openstack_compute_keypair_v2.k8s.name
  375. dynamic "block_device" {
  376. for_each = var.node_root_volume_size_in_gb > 0 ? [local.image_to_use_node] : []
  377. content {
  378. uuid = local.image_to_use_node
  379. source_type = "image"
  380. volume_size = var.node_root_volume_size_in_gb
  381. boot_index = 0
  382. destination_type = "volume"
  383. delete_on_termination = true
  384. }
  385. }
  386. network {
  387. name = var.network_name
  388. }
  389. security_groups = local.worker_sec_groups
  390. dynamic "scheduler_hints" {
  391. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
  392. content {
  393. group = openstack_compute_servergroup_v2.k8s_node[0].id
  394. }
  395. }
  396. metadata = {
  397. ssh_user = var.ssh_user
  398. kubespray_groups = "kube-node,k8s-cluster,${var.supplementary_node_groups}"
  399. depends_on = var.network_id
  400. use_access_ip = var.use_access_ip
  401. }
  402. provisioner "local-exec" {
  403. command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(concat(var.bastion_fips, var.k8s_node_fips), 0)}/ > group_vars/no-floating.yml"
  404. }
  405. }
  406. resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip" {
  407. name = "${var.cluster_name}-k8s-node-nf-${count.index + 1}"
  408. count = var.number_of_k8s_nodes_no_floating_ip
  409. availability_zone = element(var.az_list_node, count.index)
  410. image_id = var.node_root_volume_size_in_gb == 0 ? local.image_to_use_node : null
  411. flavor_id = var.flavor_k8s_node
  412. key_pair = openstack_compute_keypair_v2.k8s.name
  413. dynamic "block_device" {
  414. for_each = var.node_root_volume_size_in_gb > 0 ? [local.image_to_use_node] : []
  415. content {
  416. uuid = local.image_to_use_node
  417. source_type = "image"
  418. volume_size = var.node_root_volume_size_in_gb
  419. boot_index = 0
  420. destination_type = "volume"
  421. delete_on_termination = true
  422. }
  423. }
  424. network {
  425. name = var.network_name
  426. }
  427. security_groups = local.worker_sec_groups
  428. dynamic "scheduler_hints" {
  429. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
  430. content {
  431. group = openstack_compute_servergroup_v2.k8s_node[0].id
  432. }
  433. }
  434. metadata = {
  435. ssh_user = var.ssh_user
  436. kubespray_groups = "kube-node,k8s-cluster,no-floating,${var.supplementary_node_groups}"
  437. depends_on = var.network_id
  438. use_access_ip = var.use_access_ip
  439. }
  440. }
  441. resource "openstack_compute_instance_v2" "k8s_nodes" {
  442. for_each = var.number_of_k8s_nodes == 0 && var.number_of_k8s_nodes_no_floating_ip == 0 ? var.k8s_nodes : {}
  443. name = "${var.cluster_name}-k8s-node-${each.key}"
  444. availability_zone = each.value.az
  445. image_id = var.node_root_volume_size_in_gb == 0 ? local.image_to_use_node : null
  446. flavor_id = each.value.flavor
  447. key_pair = openstack_compute_keypair_v2.k8s.name
  448. dynamic "block_device" {
  449. for_each = var.node_root_volume_size_in_gb > 0 ? [local.image_to_use_node] : []
  450. content {
  451. uuid = local.image_to_use_node
  452. source_type = "image"
  453. volume_size = var.node_root_volume_size_in_gb
  454. boot_index = 0
  455. destination_type = "volume"
  456. delete_on_termination = true
  457. }
  458. }
  459. network {
  460. name = var.network_name
  461. }
  462. security_groups = local.worker_sec_groups
  463. dynamic "scheduler_hints" {
  464. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
  465. content {
  466. group = openstack_compute_servergroup_v2.k8s_node[0].id
  467. }
  468. }
  469. metadata = {
  470. ssh_user = var.ssh_user
  471. kubespray_groups = "kube-node,k8s-cluster,%{if each.value.floating_ip == false}no-floating,%{endif}${var.supplementary_node_groups}"
  472. depends_on = var.network_id
  473. use_access_ip = var.use_access_ip
  474. }
  475. provisioner "local-exec" {
  476. command = "%{if each.value.floating_ip}sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(concat(var.bastion_fips, [for key, value in var.k8s_nodes_fips : value.address]), 0)}/ > group_vars/no-floating.yml%{else}true%{endif}"
  477. }
  478. }
  479. resource "openstack_compute_instance_v2" "glusterfs_node_no_floating_ip" {
  480. name = "${var.cluster_name}-gfs-node-nf-${count.index + 1}"
  481. count = var.number_of_gfs_nodes_no_floating_ip
  482. availability_zone = element(var.az_list, count.index)
  483. image_name = var.gfs_root_volume_size_in_gb == 0 ? local.image_to_use_gfs : null
  484. flavor_id = var.flavor_gfs_node
  485. key_pair = openstack_compute_keypair_v2.k8s.name
  486. dynamic "block_device" {
  487. for_each = var.gfs_root_volume_size_in_gb > 0 ? [local.image_to_use_gfs] : []
  488. content {
  489. uuid = local.image_to_use_gfs
  490. source_type = "image"
  491. volume_size = var.gfs_root_volume_size_in_gb
  492. boot_index = 0
  493. destination_type = "volume"
  494. delete_on_termination = true
  495. }
  496. }
  497. network {
  498. name = var.network_name
  499. }
  500. security_groups = [openstack_networking_secgroup_v2.k8s.name]
  501. dynamic "scheduler_hints" {
  502. for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
  503. content {
  504. group = openstack_compute_servergroup_v2.k8s_node[0].id
  505. }
  506. }
  507. metadata = {
  508. ssh_user = var.ssh_user_gfs
  509. kubespray_groups = "gfs-cluster,network-storage,no-floating"
  510. depends_on = var.network_id
  511. use_access_ip = var.use_access_ip
  512. }
  513. }
  514. resource "openstack_compute_floatingip_associate_v2" "bastion" {
  515. count = var.number_of_bastions
  516. floating_ip = var.bastion_fips[count.index]
  517. instance_id = element(openstack_compute_instance_v2.bastion.*.id, count.index)
  518. wait_until_associated = var.wait_for_floatingip
  519. }
  520. resource "openstack_compute_floatingip_associate_v2" "k8s_master" {
  521. count = var.number_of_k8s_masters
  522. instance_id = element(openstack_compute_instance_v2.k8s_master.*.id, count.index)
  523. floating_ip = var.k8s_master_fips[count.index]
  524. wait_until_associated = var.wait_for_floatingip
  525. }
  526. resource "openstack_compute_floatingip_associate_v2" "k8s_master_no_etcd" {
  527. count = var.master_root_volume_size_in_gb == 0 ? var.number_of_k8s_masters_no_etcd : 0
  528. instance_id = element(openstack_compute_instance_v2.k8s_master_no_etcd.*.id, count.index)
  529. floating_ip = var.k8s_master_no_etcd_fips[count.index]
  530. }
  531. resource "openstack_compute_floatingip_associate_v2" "k8s_node" {
  532. count = var.node_root_volume_size_in_gb == 0 ? var.number_of_k8s_nodes : 0
  533. floating_ip = var.k8s_node_fips[count.index]
  534. instance_id = element(openstack_compute_instance_v2.k8s_node[*].id, count.index)
  535. wait_until_associated = var.wait_for_floatingip
  536. }
  537. resource "openstack_compute_floatingip_associate_v2" "k8s_nodes" {
  538. for_each = var.number_of_k8s_nodes == 0 && var.number_of_k8s_nodes_no_floating_ip == 0 ? { for key, value in var.k8s_nodes : key => value if value.floating_ip } : {}
  539. floating_ip = var.k8s_nodes_fips[each.key].address
  540. instance_id = openstack_compute_instance_v2.k8s_nodes[each.key].id
  541. wait_until_associated = var.wait_for_floatingip
  542. }
  543. resource "openstack_blockstorage_volume_v2" "glusterfs_volume" {
  544. name = "${var.cluster_name}-glusterfs_volume-${count.index + 1}"
  545. count = var.gfs_root_volume_size_in_gb == 0 ? var.number_of_gfs_nodes_no_floating_ip : 0
  546. description = "Non-ephemeral volume for GlusterFS"
  547. size = var.gfs_volume_size_in_gb
  548. }
  549. resource "openstack_compute_volume_attach_v2" "glusterfs_volume" {
  550. count = var.gfs_root_volume_size_in_gb == 0 ? var.number_of_gfs_nodes_no_floating_ip : 0
  551. instance_id = element(openstack_compute_instance_v2.glusterfs_node_no_floating_ip.*.id, count.index)
  552. volume_id = element(openstack_blockstorage_volume_v2.glusterfs_volume.*.id, count.index)
  553. }