diff --git a/modules/ionos-basic-vm/main.tf b/modules/ionos-basic-vm/main.tf
index efce938..5dae667 100644
--- a/modules/ionos-basic-vm/main.tf
+++ b/modules/ionos-basic-vm/main.tf
@@ -15,7 +15,7 @@ resource "ionoscloud_lan" "basic_vm_server_lan" {
resource "opentelekomcloud_dns_recordset_v2" "a_records" {
zone_id = data.opentelekomcloud_dns_zone_v2.dns_zone.id
name = "${var.fulldomainname}"
- ttl = 3600
+ ttl = 300
type = "A"
records = [local.public_ip]
diff --git a/modules/ionos-ha-vms/README.md b/modules/ionos-ha-vms/README.md
new file mode 100644
index 0000000..064381c
--- /dev/null
+++ b/modules/ionos-ha-vms/README.md
@@ -0,0 +1,71 @@
+
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [ionoscloud](#provider\_ionoscloud) | 6.4.18 |
+| [opentelekomcloud](#provider\_opentelekomcloud) | n/a |
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [conventions\_coordinates](#module\_conventions\_coordinates) | ../conventions-coordinates | n/a |
+| [ha\_backup\_vms](#module\_ha\_backup\_vms) | ../ionos-basic-vm/ | n/a |
+| [ha\_main\_vm](#module\_ha\_main\_vm) | ../ionos-basic-vm/ | n/a |
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [coordinates](#input\_coordinates) | n/a | `map(any)` | n/a | yes |
+| [cpu\_family](#input\_cpu\_family) | n/a | `string` | n/a | yes |
+| [datacenter](#input\_datacenter) | n/a | `string` | n/a | yes |
+| [datacenter\_location](#input\_datacenter\_location) | n/a | `string` | n/a | yes |
+| [domain\_base](#input\_domain\_base) | Domains will be [-]. | `string` | n/a | yes |
+| [domain\_without\_top\_level](#input\_domain\_without\_top\_level) | domain without top level | `string` | n/a | yes |
+| [image](#input\_image) | image of the vm | `string` | n/a | yes |
+| [name](#input\_name) | name of the ha cluster, used for names the components and the domain | `string` | n/a | yes |
+| [server\_cpu](#input\_server\_cpu) | cpus of the vm servers | `number` | n/a | yes |
+| [server\_memory](#input\_server\_memory) | memory of the vm servers | `number` | n/a | yes |
+| [top\_level\_domain](#input\_top\_level\_domain) | Top-level domain mapping for environments | `map(any)` | n/a | yes |
+| [volume\_size](#input\_volume\_size) | volume size for vm | `number` | n/a | yes |
+| [create\_second\_volume](#input\_create\_second\_volume) | n/a | `bool` | `true` | no |
+| [ha\_node\_count](#input\_ha\_node\_count) | Number of VMs/Nodes in the HA Cluster | `number` | `2` | no |
+| [initial\_public\_key](#input\_initial\_public\_key) | The public key of the initial user created via the cloud init script. | `string` | `""` | no |
+| [initial\_uid](#input\_initial\_uid) | The uid of the initial user created via the cloud init script. | `string` | `""` | no |
+| [initial\_user](#input\_initial\_user) | The initial user to be created via the cloud init script. | `string` | `""` | no |
+| [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 |
+| [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 |
+| [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 |
+| [second\_volume\_disk\_type](#input\_second\_volume\_disk\_type) | n/a | `string` | `"HDD"` | no |
+| [second\_volume\_size](#input\_second\_volume\_size) | size of the second volume | `string` | `100` | no |
+| [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 |
+|------|-------------|
+| [ha\_common\_address](#output\_ha\_common\_address) | n/a |
+| [ha\_dns\_name](#output\_ha\_dns\_name) | n/a |
+| [ha\_internal\_lan\_id](#output\_ha\_internal\_lan\_id) | n/a |
+| [ha\_public\_lan\_id](#output\_ha\_public\_lan\_id) | n/a |
+| [ha\_vms\_server\_id](#output\_ha\_vms\_server\_id) | n/a |
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.13 |
+| [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 |
+
\ No newline at end of file
diff --git a/modules/ionos-ha-vms/data.tf b/modules/ionos-ha-vms/data.tf
new file mode 100644
index 0000000..ea8abba
--- /dev/null
+++ b/modules/ionos-ha-vms/data.tf
@@ -0,0 +1,3 @@
+data "opentelekomcloud_dns_zone_v2" "dns_zone" {
+ name = module.conventions_coordinates.dns_zone_name
+}
\ No newline at end of file
diff --git a/modules/ionos-ha-vms/locals.tf b/modules/ionos-ha-vms/locals.tf
new file mode 100644
index 0000000..5f88ba6
--- /dev/null
+++ b/modules/ionos-ha-vms/locals.tf
@@ -0,0 +1,3 @@
+locals {
+ availability_zones = ["ZONE_1", "ZONE_2"]
+}
\ No newline at end of file
diff --git a/modules/ionos-ha-vms/main.tf b/modules/ionos-ha-vms/main.tf
new file mode 100644
index 0000000..24fc343
--- /dev/null
+++ b/modules/ionos-ha-vms/main.tf
@@ -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]
+ }
+}
diff --git a/modules/ionos-ha-vms/outputs.tf b/modules/ionos-ha-vms/outputs.tf
new file mode 100644
index 0000000..a1e0f01
--- /dev/null
+++ b/modules/ionos-ha-vms/outputs.tf
@@ -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)
+}
diff --git a/modules/ionos-ha-vms/variables.tf b/modules/ionos-ha-vms/variables.tf
new file mode 100644
index 0000000..2b691ce
--- /dev/null
+++ b/modules/ionos-ha-vms/variables.tf
@@ -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 [-]."
+}
+
+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 = ""
+}
diff --git a/modules/ionos-ha-vms/versions.tf b/modules/ionos-ha-vms/versions.tf
new file mode 100644
index 0000000..38a887c
--- /dev/null
+++ b/modules/ionos-ha-vms/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ ionoscloud = {
+ source = "ionos-cloud/ionoscloud"
+ version = "6.4.18"
+ }
+ opentelekomcloud = {
+ source = "opentelekomcloud/opentelekomcloud"
+ }
+ }
+ required_version = ">= 0.13"
+}