fmt code
Some checks are pending
CI / Terraform Format & Validate (push) Waiting to run
CI / TruffleHog Secrets Scan (push) Successful in 12s

This commit is contained in:
Mauritz Uphoff 2025-06-17 11:30:56 +02:00
parent 3c3f64cdfa
commit fa94df6ae5
11 changed files with 152 additions and 51 deletions

View file

@ -1,6 +1,26 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/random" {
version = "3.6.3"
constraints = "3.6.3"
hashes = [
"h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=",
"zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451",
"zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8",
"zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe",
"zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1",
"zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36",
"zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30",
"zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615",
"zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad",
"zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556",
"zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0",
]
}
provider "registry.terraform.io/stackitcloud/stackit" {
version = "0.55.0"
constraints = "0.55.0"

View file

@ -15,6 +15,10 @@ terraform {
source = "stackitcloud/stackit"
version = "0.55.0"
}
random = {
source = "hashicorp/random"
version = "3.6.3"
}
}
}

View file

@ -1,5 +1,5 @@
variable "stackit_project_id" {
type = string
type = string
/*default = "XXXXX-XXXX-XXXX-XXXX-XXXXXXX"*/
default = "d75e6aab-b616-4b42-ae3b-aaf161ad626d"
}
@ -14,7 +14,7 @@ variable "stackit_service_account_key_path" {
default = "./keys/stackit-sa.json"
}
variable "debian_image" {
variable "debian_image_id" {
type = string
default = "b7aedfad-3be7-46e0-9ece-19fd50e2d83e"
}
@ -23,3 +23,18 @@ resource "stackit_key_pair" "admin_keypair" {
name = "admin-keypair"
public_key = chomp(file("~/.ssh/id_rsa.pub"))
}
locals {
user_data_master = templatefile("cloud-init.yaml", {
type = "MASTER"
priority = "255"
vip = stackit_network_interface.vip01.ipv4
})
user_data_backup = templatefile("cloud-init.yaml", {
type = "BACKUP"
priority = "254"
vip = stackit_network_interface.vip01.ipv4
})
}

View file

@ -1,4 +1,3 @@
# Create vNET Network
resource "stackit_network" "default" {
project_id = var.stackit_project_id
ipv4_prefix = "10.1.2.0/24"
@ -6,7 +5,6 @@ resource "stackit_network" "default" {
ipv4_nameservers = ["9.9.9.9", "1.1.1.1"]
}
# Security Group
resource "stackit_security_group" "active-passive" {
project_id = var.stackit_project_id
name = "ha-active-passive"

View file

@ -5,31 +5,26 @@ resource "stackit_server" "example01" {
boot_volume = {
size = 64
source_type = "image"
source_id = var.debian_image
source_id = var.debian_image_id
performance_class = "storage_premium_perf6"
delete_on_termination = true
}
machine_type = "c1.4"
availability_zone = "eu01-1"
keypair_name = stackit_key_pair.admin_keypair.name
depends_on = [stackit_network_interface.example01]
machine_type = "c1.4"
availability_zone = "eu01-1"
user_data = local.user_data_master
keypair_name = stackit_key_pair.admin_keypair.name
network_interfaces = [stackit_network_interface.example01.network_interface_id]
}
resource "stackit_network_interface" "example01" {
project_id = var.stackit_project_id
network_id = stackit_network.default.network_id
project_id = var.stackit_project_id
network_id = stackit_network.default.network_id
# security = false
allowed_addresses = [format("%s/%s", stackit_network_interface.vip01.ipv4, "32")]
security_group_ids = [stackit_security_group.active-passive.security_group_id]
}
resource "stackit_server_network_interface_attach" "example01-nic-attachment" {
project_id = var.stackit_project_id
server_id = stackit_server.example01.server_id
network_interface_id = stackit_network_interface.example01.network_interface_id
}
resource "stackit_public_ip" "example01-wan" {
project_id = var.stackit_project_id
network_interface_id = stackit_network_interface.example01.network_interface_id
depends_on = [stackit_server_network_interface_attach.example01-nic-attachment]
}

View file

@ -5,14 +5,18 @@ resource "stackit_server" "example02" {
boot_volume = {
size = 64
source_type = "image"
source_id = var.debian_image
source_id = var.debian_image_id
performance_class = "storage_premium_perf6"
delete_on_termination = true
}
machine_type = "c1.4"
availability_zone = "eu01-2"
user_data = local.user_data_backup
keypair_name = stackit_key_pair.admin_keypair.name
depends_on = [stackit_network_interface.example02]
network_interfaces = [
stackit_network_interface.example02.network_interface_id
]
}
resource "stackit_network_interface" "example02" {
@ -22,14 +26,7 @@ resource "stackit_network_interface" "example02" {
security_group_ids = [stackit_security_group.active-passive.security_group_id]
}
resource "stackit_server_network_interface_attach" "example02-nic-attachment" {
project_id = var.stackit_project_id
server_id = stackit_server.example02.server_id
network_interface_id = stackit_network_interface.example02.network_interface_id
}
resource "stackit_public_ip" "example02-wan" {
project_id = var.stackit_project_id
network_interface_id = stackit_network_interface.example02.network_interface_id
depends_on = [stackit_server_network_interface_attach.example02-nic-attachment]
}

View file

@ -4,19 +4,11 @@ resource "stackit_network_interface" "vip01" {
security = false
}
locals {
x = stackit_network_interface.vip01.ipv4
}
resource "stackit_public_ip" "vip01-wan" {
project_id = var.stackit_project_id
network_interface_id = stackit_network_interface.vip01.network_interface_id
}
output "example01-wan-ip" {
value = stackit_public_ip.example01-wan.ip
}
output "example02-wan-ip" {
value = stackit_public_ip.example02-wan.ip
}
output "vip01-wan-ip" {
value = stackit_public_ip.vip01-wan.ip
}

32
06-outputs.tf Normal file
View file

@ -0,0 +1,32 @@
output "example01-wan-ip" {
value = stackit_public_ip.example01-wan.ip
}
output "example01-master-server-id" {
value = stackit_server.example01.server_id
}
output "example02-wan-ip" {
value = stackit_public_ip.example02-wan.ip
}
output "example02-backup-server-id" {
value = stackit_server.example02.server_id
}
output "vip01-wan-ip" {
value = stackit_public_ip.vip01-wan.ip
}
output "vip01-lan-ip" {
value = stackit_network_interface.vip01.ipv4
}
output "vip01-network-interface" {
value = stackit_network_interface.vip01.network_interface_id
}
output "default-network-id" {
value = stackit_network.default.network_id
}

View file

@ -1,24 +1,54 @@
# Basic High Availability (HA) Setup Using VRRP
This guide provides step-by-step instructions for setting up a basic active/passive Virtual Router Redundancy Protocol (VRRP) high availability (HA) cluster using the STACKIT CLI. This configuration ensures one virtual machine (VM) acts as the active primary node while the other remains on standby as a failover.
This guide provides a comprehensive, step-by-step process for setting up a Basic High Availability (HA) cluster using the Virtual Router Redundancy Protocol (VRRP) with the STACKIT CLI. In this HA configuration, one virtual machine (VM) functions as the active primary node while the secondary remains on standby, ready to take over in the event of a failure.
> See [STACKIT Cli-Guide](STACKIT-CLI-GUIDE.md) to perform setup via CLI instead of terraform!
> For setup instructions using the STACKIT CLI instead of Terraform, please refer to the [STACKIT CLI Guide](STACKIT-CLI-GUIDE.md).
## Overview of Core Components
- Two virtual machines in an active/passive configuration.
- VRRP synchronization between the nodes.
- Security group rules for VRRP and ICMP traffic.
- A dedicated internal virtual IP (vIP) bound to a shared NIC port.
- Public IP binding for external access to HA endpoint.
- **Active/Passive VM Configuration**: Ensures redundancy, with one active node and a standby failover node.
- **VRRP Synchronization**: Maintains state information between nodes, enabling seamless failover.
- **Security Group Rules**: Configured to allow VRRP and ICMP traffic.
- **Virtual IP (vIP)**: A dedicated internal IP address bound to a shared network interface card (NIC) port for seamless failover.
- **Public IP Binding**: Enables external access to the HA endpoint.
Diagrams:
### Diagrams
- HA Traffic Flow:
- **HA Traffic Flow**:
![](docs/ha.svg)
![HA Traffic Flow Diagram](docs/ha.svg)
- vIP Binding Concept:
- **vIP Binding Concept**:
![](docs/vip.svg)
![vIP Binding Diagram](docs/vip.svg)
## Testing the Setup
After completing the setup, use the [test-setup.sh](test-setup.sh) script to verify that the Apache server is operational on each machine. Executing this script should yield the following results:
```bash
Performing curl on IP: 193.148.177.243
<center><h1>example01</h1>
Performing curl on IP: 193.148.161.92
<center><h1>example02</h1>
Performing curl on IP: 193.148.169.230
<center><h1>example01</h1>
```
The output indicates a successfully functional VRRP setup.
### Failover Testing
To test failover, stop the master VM and perform another `curl` request to the vIP WAN IP:
```bash
vip01_wan_ip=$(terraform output -raw vip01-wan-ip)
curl $vip01_wan_ip
<center><h1>example02</h1>
```
The response confirms that the failover from the master to the backup has occurred
successfully, demonstrating the effectiveness of the HA setup.

View file

@ -64,7 +64,7 @@ write_files:
auth_pass 12345
}
virtual_ipaddress {
10.0.0.123/24
${vip}/24
}
}
path: /etc/keepalived/keepalived.conf

18
test-setup.sh Normal file
View file

@ -0,0 +1,18 @@
#!/bin/bash
example01_wan_ip=$(terraform output -raw example01-wan-ip)
example02_wan_ip=$(terraform output -raw example02-wan-ip)
vip01_wan_ip=$(terraform output -raw vip01-wan-ip)
curl_ip() {
local ip=$1
echo "Performing curl on IP: $ip"
curl http://$ip
echo -e "\n" # For better readability in output
}
curl_ip $example01_wan_ip
curl_ip $example02_wan_ip
curl_ip $vip01_wan_ip
echo "Curl operations completed."