Skip to content

Commit

Permalink
Rewrite terraform to support dynamic number of nodes
Browse files Browse the repository at this point in the history
Change the data structure to accept data of nodes using maps.
This will allow to add a variable number of masters (1,3) in the future.
Added a new dependency on rodaine/hclencoder, to render terraform data
in HCL instead of JSON, to avoid a bug in JSON parsing:
hashicorp/terraform#15549
  • Loading branch information
Yolanda Robla authored and stbenjam committed May 29, 2019
1 parent 0d7c4bb commit 08fbaed
Show file tree
Hide file tree
Showing 32 changed files with 799 additions and 229 deletions.
8 changes: 8 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 4 additions & 14 deletions data/data/baremetal/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,9 @@ module "masters" {
root_gb = "${var.master_configuration["root_gb"]}"
root_disk = "${var.master_configuration["root_disk"]}"

master_0 = "${var.master_0}"
properties_0 = "${var.properties_0}"
root_device_0 = "${var.root_device_0}"
driver_info_0 = "${var.driver_info_0}"

master_1 = "${var.master_1}"
properties_1 = "${var.properties_1}"
root_device_1 = "${var.root_device_1}"
driver_info_1 = "${var.driver_info_1}"

master_2 = "${var.master_2}"
properties_2 = "${var.properties_2}"
root_device_2 = "${var.root_device_2}"
driver_info_2 = "${var.driver_info_2}"
master_nodes = "${var.master_nodes}"
properties = "${var.properties}"
root_devices = "${var.root_devices}"
driver_infos = "${var.driver_infos}"
}

82 changes: 11 additions & 71 deletions data/data/baremetal/masters/main.tf
Original file line number Diff line number Diff line change
@@ -1,91 +1,31 @@
# FIXME: This Terraform HCL file defines the 3 master nodes. It uses the original ironic_nodes.json format,
# flattened because Terraform v0.11 does not support nested data structures. Maps may only be key/value
# pairs. We could use terraform's resource `count` provider to have just one resource declaration, but
# the data would have to be structured differently.

resource "ironic_node_v1" "openshift-master-0" {
name = "${var.master_0["name"]}"
resource "ironic_node_v1" "openshift-master" {
count = "${length(keys(var.master_nodes))}"
name = "${lookup(var.master_nodes[format("openshift-master-%d", count.index)], "name")}"

target_provision_state = "active"
user_data = "${var.ignition}"
root_device = "${var.root_device_0}"
driver = "${var.master_0["driver"]}"
driver_info = "${var.driver_info_0}"

ports = [
{
address = "${var.master_0["port_address"]}"
pxe_enabled = "true"
},
]

properties = "${var.properties_0}"

instance_info = {
image_source = "${var.image_source}"
image_checksum = "${var.image_checksum}"
root_gb = "${var.root_gb}"
}

management_interface = "${var.master_0["management_interface"]}"
power_interface = "${var.master_0["power_interface"]}"
vendor_interface = "${var.master_0["vendor_interface"]}"
}

resource "ironic_node_v1" "openshift-master-1" {
name = "${var.master_1["name"]}"

target_provision_state = "active"
user_data = "${var.ignition}"
root_device = "${var.root_device_1}"
driver = "${var.master_1["driver"]}"
driver_info = "${var.driver_info_1}"
root_device = "${var.root_devices[format("openshift-master-%d", count.index)]}"
driver = "${lookup(var.master_nodes[format("openshift-master-%d", count.index)], "driver")}"
driver_info = "${var.driver_infos[format("openshift-master-%d", count.index)]}"

ports = [
{
address = "${var.master_1["port_address"]}"
address = "${lookup(var.master_nodes[format("openshift-master-%d", count.index)], "port_address")}"
pxe_enabled = "true"
},
]

properties = "${var.properties_1}"
properties = "${var.properties[format("openshift-master-%d", count.index)]}"

instance_info = {
image_source = "${var.image_source}"
image_checksum = "${var.image_checksum}"
root_gb = "${var.root_gb}"
}

management_interface = "${var.master_1["management_interface"]}"
power_interface = "${var.master_1["power_interface"]}"
vendor_interface = "${var.master_1["vendor_interface"]}"
}

resource "ironic_node_v1" "openshift-master-2" {
name = "${var.master_2["name"]}"

target_provision_state = "active"
user_data = "${var.ignition}"
root_device = "${var.root_device_2}"
driver = "${var.master_2["driver"]}"
driver_info = "${var.driver_info_2}"

ports = [
{
address = "${var.master_2["port_address"]}"
pxe_enabled = "true"
},
]

properties = "${var.properties_2}"

instance_info = {
image_source = "${var.image_source}"
image_checksum = "${var.image_checksum}"
root_gb = "${var.root_gb}"
}
management_interface = "${lookup(var.master_nodes[format("openshift-master-%d", count.index)], "management_interface")}"
power_interface = "${lookup(var.master_nodes[format("openshift-master-%d", count.index)], "power_interface")}"
vendor_interface = "${lookup(var.master_nodes[format("openshift-master-%d", count.index)], "vendor_interface")}"

management_interface = "${var.master_2["management_interface"]}"
power_interface = "${var.master_2["power_interface"]}"
vendor_interface = "${var.master_2["vendor_interface"]}"
}
57 changes: 8 additions & 49 deletions data/data/baremetal/masters/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,64 +23,23 @@ variable "ignition" {
description = "The content of the master ignition file"
}

variable "master_0" {
variable "master_nodes" {
type = "map"
description = "Master 0 bare metal node details"
description = "Master bare metal node details"
}

variable "properties_0" {
variable "properties" {
type = "map"
description = "Master 0 bare metal properties"
description = "Master bare metal properties"
}

variable "root_device_0" {
variable "root_devices" {
type = "map"
description = "Master 0 root device configuration"
description = "Master root device configuration"
}

variable "driver_info_0" {
variable "driver_infos" {
type = "map"
description = "Master 0 driver info"
description = "Master driver info"
}

variable "master_1" {
type = "map"
description = "Master 1 bare metal node details"
}

variable "properties_1" {
type = "map"
description = "Master 1 bare metal properties"
}

variable "root_device_1" {
type = "map"
description = "Master 1 root device configuration"
}

variable "driver_info_1" {
type = "map"
description = "Master 1 driver info"
}

variable "master_2" {
type = "map"
description = "Master 2 bare metal node details"
}

variable "properties_2" {
type = "map"
description = "Master 2 bare metal properties"
}

variable "root_device_2" {
type = "map"
description = "Master 2 root device configuration"
}

variable "driver_info_2" {
type = "map"
description = "Master 2 driver info"
}


58 changes: 8 additions & 50 deletions data/data/baremetal/variables-baremetal.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,64 +28,22 @@ variable "master_configuration" {
description = "Configuration information for masters such as image location"
}

variable "master_0" {
variable "master_nodes" {
type = "map"
description = "Master 0 bare metal node details"
description = "Master bare metal node details"
}

variable "properties_0" {
variable "properties" {
type = "map"
description = "Master 0 bare metal properties"
description = "Master bare metal properties"
}

variable "root_device_0" {
variable "root_devices" {
type = "map"
description = "Master 0 root device configuration"
description = "Master root device configurations"
}

variable "driver_info_0" {
variable "driver_infos" {
type = "map"
description = "Master 0 driver info"
description = "Master driver infos"
}

variable "master_1" {
type = "map"
description = "Master 1 bare metal node details"
}

variable "properties_1" {
type = "map"
description = "Master 1 bare metal properties"
}

variable "root_device_1" {
type = "map"
description = "Master 1 root device configuration"
}

variable "driver_info_1" {
type = "map"
description = "Master 1 driver info"
}

variable "master_2" {
type = "map"
description = "Master 2 bare metal node details"
}

variable "properties_2" {
type = "map"
description = "Master 2 bare metal properties"
}

variable "root_device_2" {
type = "map"
description = "Master 2 root device configuration"
}

variable "driver_info_2" {
type = "map"
description = "Master 2 driver info"
}


54 changes: 17 additions & 37 deletions pkg/tfvars/baremetal/baremetal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,30 @@
package baremetal

import (
"encoding/json"
"github.com/openshift-metalkube/kni-installer/pkg/types/baremetal"

libvirttfvars "github.com/openshift-metalkube/kni-installer/pkg/tfvars/libvirt"
"github.com/pkg/errors"
"github.com/rodaine/hclencoder"
)

type config struct {
LibvirtURI string `json:"libvirt_uri,omitempty"`
IronicURI string `json:"ironic_uri,omitempty"`
Image string `json:"os_image,omitempty"`
BareMetalBridge string `json:"baremetal_bridge,omitempty"`
OverCloudBridge string `json:"overcloud_bridge,omitempty"`
LibvirtURI string `hcl:"libvirt_uri,omitempty"`
IronicURI string `hcl:"ironic_uri,omitempty"`
Image string `hcl:"os_image,omitempty"`
BareMetalBridge string `hcl:"baremetal_bridge,omitempty"`
OverCloudBridge string `hcl:"overcloud_bridge,omitempty"`

// Data required for masters deployment - several maps per master, because of terraform's
// limitation that maps cannot be strings
Master0 interface{} `json:"master_0"`
Properties0 interface{} `json:"properties_0"`
RootDevice0 interface{} `json:"root_device_0"`
DriverInfo0 interface{} `json:"driver_info_0"`

Master1 interface{} `json:"master_1"`
Properties1 interface{} `json:"properties_1"`
RootDevice1 interface{} `json:"root_device_1"`
DriverInfo1 interface{} `json:"driver_info_1"`

Master2 interface{} `json:"master_2"`
Properties2 interface{} `json:"properties_2"`
RootDevice2 interface{} `json:"root_device_2"`
DriverInfo2 interface{} `json:"driver_info_2"`
MasterNodes interface{} `hcl:"master_nodes"`
Properties interface{} `hcl:"properties"`
RootDevices interface{} `hcl:"root_devices"`
DriverInfos interface{} `hcl:"driver_infos"`

MasterConfiguration baremetal.MasterConfiguration `json:"master_configuration"`
MasterConfiguration map[string]interface{} `hcl:"master_configuration"`
}

// TFVars generates bare metal specific Terraform variables.
func TFVars(libvirtURI, ironicURI, osImage, baremetalBridge, overcloudBridge string, nodes map[string]interface{}, configuration baremetal.MasterConfiguration) ([]byte, error) {
func TFVars(libvirtURI, ironicURI, osImage, baremetalBridge, overcloudBridge string, nodes map[string]interface{}, configuration map[string]interface{}) ([]byte, error) {
osImage, err := libvirttfvars.CachedImage(osImage)
if err != nil {
return nil, errors.Wrap(err, "failed to use cached libvirt image")
Expand All @@ -49,20 +37,12 @@ func TFVars(libvirtURI, ironicURI, osImage, baremetalBridge, overcloudBridge str
Image: osImage,
BareMetalBridge: baremetalBridge,
OverCloudBridge: overcloudBridge,
Master0: nodes["master_0"],
Properties0: nodes["properties_0"],
RootDevice0: nodes["root_device_0"],
DriverInfo0: nodes["driver_info_0"],
Master1: nodes["master_1"],
Properties1: nodes["properties_1"],
RootDevice1: nodes["root_device_1"],
DriverInfo1: nodes["driver_info_1"],
Master2: nodes["master_2"],
Properties2: nodes["properties_2"],
RootDevice2: nodes["root_device_2"],
DriverInfo2: nodes["driver_info_2"],
MasterNodes: nodes["master_nodes"],
Properties: nodes["properties"],
RootDevices: nodes["root_devices"],
DriverInfos: nodes["driver_infos"],
MasterConfiguration: configuration,
}

return json.MarshalIndent(cfg, "", " ")
return hclencoder.Encode(cfg)
}
9 changes: 1 addition & 8 deletions pkg/types/baremetal/platform.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package baremetal

type MasterConfiguration struct {
ImageSource string `json:"image_source,omitempty"`
ImageChecksum string `json:"image_checksum,omitempty"`
RootGb string `json:"root_gb,omitempty"`
RootDisk string `json:"root_disk,omitempty"`
}

// Platform stores all the global configuration that all
// machinesets use.
type Platform struct {
Expand All @@ -27,7 +20,7 @@ type Platform struct {

// MasterConfiguration contains the information needed to provision
// a master.
MasterConfiguration MasterConfiguration `json:"master_configuration"`
MasterConfiguration map[string]interface{} `json:"master_configuration"`

// DefaultMachinePlatform is the default configuration used when
// installing on bare metal for machine pools which do not define their own
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 08fbaed

Please sign in to comment.