Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dbp 995 add ha ionos vms #37

Merged
merged 6 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions modules/ionos-ha-vms/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!-- BEGIN_TF_DOCS -->

## Providers

| Name | Version |
|------|---------|
| <a name="provider_ionoscloud"></a> [ionoscloud](#provider\_ionoscloud) | 6.4.18 |
| <a name="provider_opentelekomcloud"></a> [opentelekomcloud](#provider\_opentelekomcloud) | n/a |
## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_conventions_coordinates"></a> [conventions\_coordinates](#module\_conventions\_coordinates) | ../conventions-coordinates | n/a |
| <a name="module_ha_backup_vms"></a> [ha\_backup\_vms](#module\_ha\_backup\_vms) | ../ionos-basic-vm/ | n/a |
| <a name="module_ha_main_vm"></a> [ha\_main\_vm](#module\_ha\_main\_vm) | ../ionos-basic-vm/ | n/a |
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_coordinates"></a> [coordinates](#input\_coordinates) | n/a | `map(any)` | n/a | yes |
| <a name="input_cpu_family"></a> [cpu\_family](#input\_cpu\_family) | n/a | `string` | n/a | yes |
| <a name="input_datacenter"></a> [datacenter](#input\_datacenter) | n/a | `string` | n/a | yes |
| <a name="input_datacenter_location"></a> [datacenter\_location](#input\_datacenter\_location) | n/a | `string` | n/a | yes |
| <a name="input_domain_base"></a> [domain\_base](#input\_domain\_base) | Domains will be <name>[-<index>].<domain\_base> | `string` | n/a | yes |
| <a name="input_domain_without_top_level"></a> [domain\_without\_top\_level](#input\_domain\_without\_top\_level) | domain without top level | `string` | n/a | yes |
| <a name="input_image"></a> [image](#input\_image) | image of the vm | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | name of the ha cluster, used for names the components and the domain | `string` | n/a | yes |
| <a name="input_server_cpu"></a> [server\_cpu](#input\_server\_cpu) | cpus of the vm servers | `number` | n/a | yes |
| <a name="input_server_memory"></a> [server\_memory](#input\_server\_memory) | memory of the vm servers | `number` | n/a | yes |
| <a name="input_top_level_domain"></a> [top\_level\_domain](#input\_top\_level\_domain) | Top-level domain mapping for environments | `map(any)` | n/a | yes |
| <a name="input_volume_size"></a> [volume\_size](#input\_volume\_size) | volume size for vm | `number` | n/a | yes |
| <a name="input_create_second_volume"></a> [create\_second\_volume](#input\_create\_second\_volume) | n/a | `bool` | `true` | no |
| <a name="input_ha_node_count"></a> [ha\_node\_count](#input\_ha\_node\_count) | Number of VMs/Nodes in the HA Cluster | `number` | `2` | no |
| <a name="input_initial_public_key"></a> [initial\_public\_key](#input\_initial\_public\_key) | The public key of the initial user created via the cloud init script. | `string` | `""` | no |
| <a name="input_initial_uid"></a> [initial\_uid](#input\_initial\_uid) | The uid of the initial user created via the cloud init script. | `string` | `""` | no |
| <a name="input_initial_user"></a> [initial\_user](#input\_initial\_user) | The initial user to be created via the cloud init script. | `string` | `""` | no |
| <a name="input_permanent_vm"></a> [permanent\_vm](#input\_permanent\_vm) | Create a permanent VM that mustn't be deleted, if false then a VM that can be deleted and that ignores changes to ram and cpu is created | `bool` | `true` | no |
| <a name="input_port_ranges"></a> [port\_ranges](#input\_port\_ranges) | port rangs to open in the IONOS firewall provided as objects in a list [{protocol = ???, name = ???, port\_start = ???, port\_end, source\_ip = ???}], source\_ip is optional. | `list` | `[]` | no |
| <a name="input_ports"></a> [ports](#input\_ports) | ports to open in the IONOS firewall provided as objects in a list [{protocol = ???, name = ???, port = ???, source\_ip = ???}], source\_ip is optional. | `list` | `[]` | no |
| <a name="input_second_volume_disk_type"></a> [second\_volume\_disk\_type](#input\_second\_volume\_disk\_type) | n/a | `string` | `"HDD"` | no |
| <a name="input_second_volume_size"></a> [second\_volume\_size](#input\_second\_volume\_size) | size of the second volume | `string` | `100` | no |
| <a name="input_user_data_script"></a> [user\_data\_script](#input\_user\_data\_script) | Decide which user-data.sh script to use | `string` | `"user-data-cloud-init.tpl"` | no |
## Outputs

| Name | Description |
|------|-------------|
| <a name="output_ha_common_address"></a> [ha\_common\_address](#output\_ha\_common\_address) | n/a |
| <a name="output_ha_dns_name"></a> [ha\_dns\_name](#output\_ha\_dns\_name) | n/a |
| <a name="output_ha_internal_lan_id"></a> [ha\_internal\_lan\_id](#output\_ha\_internal\_lan\_id) | n/a |
| <a name="output_ha_public_lan_id"></a> [ha\_public\_lan\_id](#output\_ha\_public\_lan\_id) | n/a |
| <a name="output_ha_vms_server_id"></a> [ha\_vms\_server\_id](#output\_ha\_vms\_server\_id) | n/a |
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13 |
| <a name="requirement_ionoscloud"></a> [ionoscloud](#requirement\_ionoscloud) | 6.4.18 |
## Resources

| Name | Type |
|------|------|
| [ionoscloud_ipblock.floating_ip](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/6.4.18/docs/resources/ipblock) | resource |
| [ionoscloud_ipblock.node_ips](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/6.4.18/docs/resources/ipblock) | resource |
| [ionoscloud_ipfailover.failover](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/6.4.18/docs/resources/ipfailover) | resource |
| [ionoscloud_lan.lan_internal](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/6.4.18/docs/resources/lan) | resource |
| [ionoscloud_lan.lan_public](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/6.4.18/docs/resources/lan) | resource |
| [ionoscloud_nic.private_nic_backup_vms](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/6.4.18/docs/resources/nic) | resource |
| [ionoscloud_nic.private_nic_main_vm](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/6.4.18/docs/resources/nic) | resource |
| [opentelekomcloud_dns_recordset_v2.a_records](https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest/docs/resources/dns_recordset_v2) | resource |
| [opentelekomcloud_dns_zone_v2.dns_zone](https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest/docs/data-sources/dns_zone_v2) | data source |
<!-- END_TF_DOCS -->
3 changes: 3 additions & 0 deletions modules/ionos-ha-vms/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "opentelekomcloud_dns_zone_v2" "dns_zone" {
name = module.conventions_coordinates.dns_zone_name
}
3 changes: 3 additions & 0 deletions modules/ionos-ha-vms/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
locals {
availability_zones = ["ZONE_1", "ZONE_2"]
}
141 changes: 141 additions & 0 deletions modules/ionos-ha-vms/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
module "conventions_coordinates" {
source = "../conventions-coordinates"
coordinates = var.coordinates
domain_without_top_level = var.domain_without_top_level
top_level_domain = var.top_level_domain
}

# This VM has to be created seperatly because:
# It has to exist when the failover is created (defined as master)
# The other VM(s) can only be created after the Failover IP is configured,
# otherwise you get an error because the IP is already in use by the first VM
module "ha_main_vm" {
source = "../ionos-basic-vm/"
coordinates = var.coordinates
fulldomainname = "${var.name}-0.${var.domain_base}"
datacenter = var.datacenter
datacenter_location = var.datacenter_location
create_lan = false
lan_id = ionoscloud_lan.lan_public.id
cpu_family = var.cpu_family
availability_zone = local.availability_zones[0]
image = var.image
server_name = "${var.name}-0"
ports = var.ports
port_ranges = var.port_ranges
create_ip_pool = false
public_ip = ionoscloud_ipblock.node_ips.ips[0]
additional_ips = [ionoscloud_ipblock.floating_ip.ips[0]]
basic_vm_server_memory = var.server_memory
basic_vm_server_cpu = var.server_cpu
basic_vm_volume_size = var.volume_size
domain_without_top_level = var.domain_without_top_level
top_level_domain = var.top_level_domain
basic_vm_create_second_volume = var.create_second_volume
basic_vm_second_volume_disk_type = var.second_volume_disk_type
basic_vm_second_volume_size = var.second_volume_size
permanent_vm = var.permanent_vm
user_data_script = var.user_data_script

depends_on = [ ionoscloud_lan.lan_public ]

initial_user = var.initial_user
initial_uid = var.initial_uid
initial_public_key = var.initial_public_key
}

resource "ionoscloud_nic" "private_nic_main_vm" {
count = var.ha_node_count - 1
datacenter_id = var.datacenter
server_id = module.ha_main_vm.basic_vm_server_id
lan = ionoscloud_lan.lan_internal.id
dhcp = true
firewall_active = false
}

module "ha_backup_vms" {
count = var.ha_node_count - 1
source = "../ionos-basic-vm/"
coordinates = var.coordinates
fulldomainname = "${var.name}-${count.index+1}.${var.domain_base}"
datacenter = var.datacenter
datacenter_location = var.datacenter_location
create_lan = false
lan_id = ionoscloud_lan.lan_public.id
cpu_family = var.cpu_family
availability_zone = local.availability_zones[(count.index+1)%2]
image = var.image
server_name = "${var.name}-${count.index+1}"
ports = var.ports
port_ranges = var.port_ranges
create_ip_pool = false
public_ip = ionoscloud_ipblock.node_ips.ips[count.index+1]
additional_ips = [ionoscloud_ipblock.floating_ip.ips[0]]
basic_vm_server_memory = var.server_memory
basic_vm_server_cpu = var.server_cpu
basic_vm_volume_size = var.volume_size
domain_without_top_level = var.domain_without_top_level
top_level_domain = var.top_level_domain
basic_vm_create_second_volume = var.create_second_volume
basic_vm_second_volume_disk_type = var.second_volume_disk_type
basic_vm_second_volume_size = var.second_volume_size
permanent_vm = var.permanent_vm
user_data_script = var.user_data_script

depends_on = [ ionoscloud_lan.lan_public, ionoscloud_ipfailover.failover ]

initial_user = var.initial_user
initial_uid = var.initial_uid
initial_public_key = var.initial_public_key
}

resource "ionoscloud_nic" "private_nic_backup_vms" {
count = var.ha_node_count - 1
datacenter_id = var.datacenter
server_id = module.ha_backup_vms[count.index].basic_vm_server_id
lan = ionoscloud_lan.lan_internal.id
dhcp = true
firewall_active = false
}

resource "ionoscloud_ipblock" "floating_ip" {
name = "${module.conventions_coordinates.global_identifier}-${var.name}"
location = var.datacenter_location
size = 1
}

resource "ionoscloud_ipblock" "node_ips" {
name = "${module.conventions_coordinates.global_identifier}-${var.name}-nodes"
location = var.datacenter_location
size = var.ha_node_count
}

resource "ionoscloud_lan" "lan_public" {
datacenter_id = var.datacenter
public = true
name = "${var.name}-public"
}

resource "ionoscloud_lan" "lan_internal" {
datacenter_id = var.datacenter
public = false
name = "${var.name}-private"
}

resource "ionoscloud_ipfailover" "failover" {
datacenter_id = var.datacenter
lan_id = ionoscloud_lan.lan_public.id
ip = ionoscloud_ipblock.floating_ip.ips[0]
nicuuid = module.ha_main_vm.basic_vm_server_nicuuid[0]
}

resource "opentelekomcloud_dns_recordset_v2" "a_records" {
zone_id = data.opentelekomcloud_dns_zone_v2.dns_zone.id
name = "${var.name}.${var.domain_base}"
ttl = 3600
type = "A"
records = [ionoscloud_ipblock.floating_ip.ips[0]]
lifecycle {
ignore_changes = [zone_id]
}
}
19 changes: 19 additions & 0 deletions modules/ionos-ha-vms/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "ha_internal_lan_id" {
value = ionoscloud_lan.lan_internal.id
}

output "ha_public_lan_id" {
value = ionoscloud_lan.lan_public.id
}

output "ha_dns_name" {
value = opentelekomcloud_dns_recordset_v2.a_records.name
}

output "ha_common_address" {
value = ionoscloud_ipblock.floating_ip.ips[0]
}

output "ha_vms_server_id" {
value = concat([module.ha_main_vm.basic_vm_server_id],module.ha_backup_vms[*].basic_vm_server_id)
}
119 changes: 119 additions & 0 deletions modules/ionos-ha-vms/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
variable "datacenter" {
type = string
}

variable "datacenter_location" {
type = string
}

variable "server_memory" {
type = number
description = "memory of the vm servers"
}

variable "server_cpu" {
type = number
description = "cpus of the vm servers"
}

variable "volume_size" {
type = number
description = "volume size for vm"
}

variable "create_second_volume" {
type = bool
default = true
}

variable "second_volume_disk_type" {
type = string
default = "HDD"
}

variable "cpu_family" {
type = string
}

variable "coordinates" {
type = map(any)
}

variable "top_level_domain" {
type = map(any)
description = "Top-level domain mapping for environments"
}

variable "domain_without_top_level" {
type = string
description = "domain without top level"
}

variable "image" {
type = string
description = "image of the vm"
}

variable "name" {
type = string
description = "name of the ha cluster, used for names the components and the domain"
}

variable "second_volume_size" {
type = string
description = "size of the second volume"
default = 100
}

variable "ports" {
type = list
description = "ports to open in the IONOS firewall provided as objects in a list [{protocol = ???, name = ???, port = ???, source_ip = ???}], source_ip is optional."
default = []
}

variable "port_ranges" {
type = list
description = "port rangs to open in the IONOS firewall provided as objects in a list [{protocol = ???, name = ???, port_start = ???, port_end, source_ip = ???}], source_ip is optional."
default = []
}

variable "permanent_vm" {
type = bool
description = "Create a permanent VM that mustn't be deleted, if false then a VM that can be deleted and that ignores changes to ram and cpu is created"
default = true
}

variable "user_data_script" {
type = string
description = "Decide which user-data.sh script to use"
default = "user-data-cloud-init.tpl"
}

variable "ha_node_count" {
type = number
description = "Number of VMs/Nodes in the HA Cluster"
default = 2
}

variable "domain_base" {
type = string
description = "Domains will be <name>[-<index>].<domain_base>"
}

variable "initial_user" {
type = string
description = "The initial user to be created via the cloud init script."
default = ""
}

variable "initial_uid" {
type = string
description = "The uid of the initial user created via the cloud init script."
default = ""
}

variable "initial_public_key" {
type = string
description = "The public key of the initial user created via the cloud init script."
default = ""
}
12 changes: 12 additions & 0 deletions modules/ionos-ha-vms/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
terraform {
required_providers {
ionoscloud = {
source = "ionos-cloud/ionoscloud"
version = "6.4.18"
}
opentelekomcloud = {
source = "opentelekomcloud/opentelekomcloud"
}
}
required_version = ">= 0.13"
}