Architecture Examples
Ready-to-use OpenTofu configurations for production architectures: VMs with persistent data disks, containerized microservices, load-balanced clusters, and WireGuard VPNs.
Production Deployment Patterns
The following complete configurations are verified for compatibility with OpenTofu and the microsrv-cloud/microsrv provider.
Pattern 1. Virtual Machine with Secondary Data Disk
Ideal for stateful databases (PostgreSQL, ClickHouse), log aggregators, or applications needing detached storage pools.
terraform {
required_version = ">= 1.6.0"
required_providers {
microsrv = {
source = "microsrv-cloud/microsrv"
}
}
}
provider "microsrv" {}
data "microsrv_region" "central" {
code = "ru-yndx-central"
}
data "microsrv_flavor" "std" {
code = "std.1c2g"
}
data "microsrv_image" "ubuntu" {
code = "ubuntu-noble"
}
resource "microsrv_project" "app" {
name = "app-production"
}
resource "microsrv_ssh_key" "ops" {
name = "ops-key"
public_key = var.ssh_public_key
}
resource "microsrv_vpc" "net" {
project_id = microsrv_project.app.id
region_id = data.microsrv_region.central.id
cidr = "10.42.0.0/24"
}
resource "microsrv_network_interface" "eth0" {
project_id = microsrv_project.app.id
vpc_id = microsrv_vpc.net.id
}
# Root OS disk (20 GiB)
resource "microsrv_volume" "boot" {
project_id = microsrv_project.app.id
region_id = data.microsrv_region.central.id
size_mib = 20480
clone_from = data.microsrv_image.ubuntu.code
}
# Dedicated persistent data disk (50 GiB)
resource "microsrv_volume" "data" {
project_id = microsrv_project.app.id
region_id = data.microsrv_region.central.id
size_mib = 51200
}
resource "microsrv_vm" "db" {
project_id = microsrv_project.app.id
region_id = data.microsrv_region.central.id
flavor_id = data.microsrv_flavor.std.id
class = "shared"
name = "postgres-db"
network_interface_ids = [microsrv_network_interface.eth0.id]
ssh_key_ids = [microsrv_ssh_key.ops.id]
boot_volume_id = microsrv_volume.boot.id
volume_ids = [microsrv_volume.data.id] # Secondary block device exposed as /dev/vdb
}
# Edge SSH gateway route
resource "microsrv_gateway_route" "ssh" {
project_id = microsrv_project.app.id
compute_id = microsrv_vm.db.id
protocol = "ssh"
}
variable "ssh_public_key" {
type = string
}
output "ssh_connect" {
value = "ssh postgres-db@msrv.space"
}
Pattern 2. Nginx Container with HTTP Edge Gateway
Launches an isolated OCI workload inside the Google gVisor sandbox with Stateful OverlayFS storage and automatic ingress routing.
terraform {
required_version = ">= 1.6.0"
required_providers {
microsrv = {
source = "microsrv-cloud/microsrv"
}
}
}
provider "microsrv" {}
data "microsrv_region" "central" {
code = "ru-yndx-central"
}
# Micro flavors (512 MiB RAM) are available for container workloads
data "microsrv_flavor" "micro" {
code = "micro.1c512m"
}
resource "microsrv_project" "web" {
name = "web-service"
}
resource "microsrv_vpc" "net" {
project_id = microsrv_project.web.id
region_id = data.microsrv_region.central.id
cidr = "10.44.0.0/24"
}
resource "microsrv_network_interface" "eth0" {
project_id = microsrv_project.web.id
vpc_id = microsrv_vpc.net.id
}
# Volume for cache and access logs
resource "microsrv_volume" "storage" {
project_id = microsrv_project.web.id
region_id = data.microsrv_region.central.id
size_mib = 10240
}
# Pull official Nginx image
resource "microsrv_container_image" "nginx" {
project_id = microsrv_project.web.id
region_id = data.microsrv_region.central.id
ref = "nginx:1.27-alpine"
}
resource "microsrv_container" "app" {
project_id = microsrv_project.web.id
region_id = data.microsrv_region.central.id
flavor_id = data.microsrv_flavor.micro.id
class = "shared"
image_id = microsrv_container_image.nginx.id
name = "nginx-frontend"
command = ["nginx", "-g"]
args = ["daemon off;"]
env = { "NGINX_PORT" = "80" }
restart_policy = "always"
volume_ids = [microsrv_volume.storage.id]
network_interface_ids = [microsrv_network_interface.eth0.id]
}
# Edge HTTP gateway routing
resource "microsrv_gateway_route" "http" {
project_id = microsrv_project.web.id
compute_id = microsrv_container.app.id
protocol = "http"
target_port = 80
comment = "Public web route"
}
output "container_id" {
value = microsrv_container.app.id
}
Pattern 3. Clustered Backends Behind an L4 Load Balancer
Provisions redundant virtual machine nodes behind a high-availability TCP load balancer with an explicit Virtual IP (VIP) inside your VPC.
terraform {
required_version = ">= 1.6.0"
required_providers {
microsrv = {
source = "microsrv-cloud/microsrv"
}
}
}
provider "microsrv" {}
data "microsrv_region" "central" {
code = "ru-yndx-central"
}
data "microsrv_flavor" "std" {
code = "std.1c2g"
}
data "microsrv_image" "ubuntu" {
code = "ubuntu-noble"
}
resource "microsrv_project" "ha" {
name = "ha-cluster"
}
resource "microsrv_ssh_key" "admin" {
name = "admin-key"
public_key = var.ssh_public_key
}
resource "microsrv_vpc" "net" {
project_id = microsrv_project.ha.id
region_id = data.microsrv_region.central.id
cidr = "10.45.0.0/24"
}
# Create network interfaces and boot disks for nodes: node-a and node-b
resource "microsrv_network_interface" "nic" {
for_each = toset(["node-a", "node-b"])
project_id = microsrv_project.ha.id
vpc_id = microsrv_vpc.net.id
}
resource "microsrv_volume" "boot" {
for_each = toset(["node-a", "node-b"])
project_id = microsrv_project.ha.id
region_id = data.microsrv_region.central.id
size_mib = 20480
clone_from = data.microsrv_image.ubuntu.code
}
resource "microsrv_vm" "nodes" {
for_each = toset(["node-a", "node-b"])
project_id = microsrv_project.ha.id
region_id = data.microsrv_region.central.id
flavor_id = data.microsrv_flavor.std.id
class = "shared"
name = each.key
network_interface_ids = [microsrv_network_interface.nic[each.key].id]
ssh_key_ids = [microsrv_ssh_key.admin.id]
boot_volume_id = microsrv_volume.boot[each.key].id
}
# L4 balancer with internal VIP 10.45.0.10
resource "microsrv_load_balancer" "lb" {
project_id = microsrv_project.ha.id
vpc_id = microsrv_vpc.net.id
vip = "10.45.0.10"
listeners = [
{
protocol = "tcp"
listen_port = 80
target_port = 80
algorithm = "round_robin"
},
{
protocol = "tcp"
listen_port = 22
target_port = 22
algorithm = "source_ip"
}
]
backends = [for vm in microsrv_vm.nodes : vm.id]
health_check = {
protocol = "tcp"
port = 80
interval_ms = 1000
timeout_ms = 500
}
}
variable "ssh_public_key" {
type = string
}
output "lb_vip" {
value = microsrv_load_balancer.lb.vip
}
Pattern 4. Remote Engineer Access via WireGuard VPN
Enables direct workstation connectivity into your cloud VPC over an encrypted tunnel.
terraform {
required_version = ">= 1.6.0"
required_providers {
microsrv = {
source = "microsrv-cloud/microsrv"
}
}
}
provider "microsrv" {}
data "microsrv_region" "central" {
code = "ru-yndx-central"
}
# Generate local WireGuard keypair:
# wg genkey | tee privatekey | wg pubkey > publickey
variable "wireguard_public_key" {
type = string
description = "Base64-encoded X25519 public key of the local client"
}
resource "microsrv_project" "vpn" {
name = "vpn-access"
}
resource "microsrv_vpc" "net" {
project_id = microsrv_project.vpn.id
region_id = data.microsrv_region.central.id
cidr = "10.46.0.0/24"
}
resource "microsrv_network_interface" "wg_nic" {
project_id = microsrv_project.vpn.id
vpc_id = microsrv_vpc.net.id
}
resource "microsrv_wireguard_peer" "laptop" {
project_id = microsrv_project.vpn.id
network_interface_id = microsrv_network_interface.wg_nic.id
public_key = var.wireguard_public_key
comment = "Developer MacBook"
}
# Connection parameters for local wg0.conf
output "wg_config_params" {
value = microsrv_wireguard_peer.laptop.status
}
After applying with tofu apply, the status output carries:
allocated_ip— Assigned client tunnel IPendpoint_addr— Gateway public endpointserver_public_key— Server public key for your localwg0.conf