Networking
Infrastructure

Networking

Private networking between VMs and deployments. Organization VPCs, regional subnets, firewall rules, exposed ports, and deployment references for service discovery.

Every VM in your organization shares a private network. Services talk to each other over internal IPs with no extra configuration. When you need finer control, firewall rules, exposed ports, and deployment references give you precise networking between deployments.

Private network

When you provision your first VM, JuhJuh automatically creates a private network for your organization. Every subsequent VM joins this network. Services running on different VMs can connect to each other using internal IP addresses, the same way services on a local network would.

Each region where you run VMs gets its own subnet. Subnets are allocated automatically. You do not need to plan CIDR blocks or configure routing between regions.

graph LR
    subgraph Organization VPC
        subgraph Region A
            VM1[VM: app-server]
            VM2[VM: worker-server]
        end
        subgraph Region B
            VM3[VM: db-server]
        end
    end
    VM1 <-->|internal IP| VM2
    VM1 <-->|internal IP| VM3

Key points:

  • One private network per organization, created automatically on first VM provision
  • Each region gets its own subnet (auto-allocated)
  • All VMs in the organization can reach each other over internal IPs
  • No manual network setup, VPN configuration, or peering required

Firewall rules

Firewall rules control which ports on your VMs accept traffic and from where. Every rule targets a single port and specifies whether the port is open to the public internet or restricted to your private network.

Access levels

Access Behavior
public Port is reachable from the internet. Default when no access level is set
internal Port is reachable only from within your organization's private network

Defining rules in the JuhJuh File

Firewall rules can be defined at the root level (applied to all VMs) or on individual resources and services.

Root-level rules apply to every VM in the deployment:

firewall:
  - port: 80
    label: HTTP
    description: Public web traffic
  - port: 443
    label: HTTPS
    description: Public web traffic (TLS)
  - port: 5432
    access: internal
    label: PostgreSQL
    description: Database, private network only

Resource-level rules attach to a specific managed resource:

resources:
  postgres:
    type: postgres
    firewall:
      - port: 5432
        access: internal
        label: PostgreSQL

Rule fields

Field Required Description
port Yes Port number (integer)
protocol No tcp (default) or udp
access No public (default) or internal
allowedSources No List of CIDR ranges allowed to connect. Default: ["0.0.0.0/0"] for public. Legacy alias: source_ranges
label No Short name shown in the infrastructure diagram
description No Longer description for documentation

Restricting source ranges

For public ports that should only accept traffic from specific IPs (like a monitoring service or a partner API), set allowedSources:

firewall:
  - port: 9090
    label: Metrics
    allowedSources:
      - "203.0.113.0/24"
      - "198.51.100.5/32"

Infrastructure diagram

Public firewall rules appear in the infrastructure diagram on the PaaS dashboard. JuhJuh draws connection lines from the internet zone to the service or proxy that accepts the traffic. Internal rules stay within the private network zone. This gives your team a visual map of what is exposed and what is not.

Exposed ports

When a deployment runs a service that other deployments need to connect to, you expose specific ports on the organization network with a named alias. This is how one deployment discovers another.

deployments:
  database:
    vm: db-server
    resources: [postgres]
    network: app-network
    expose:
      - port: 5432
        alias: postgres
        protocol: tcp
Field Required Description
port Yes Port number being exposed
alias Yes Unique name for this service endpoint. Used in deployment references
protocol No tcp (default) or udp

Aliases must be unique within a deployment. You can expose multiple ports from the same deployment, each with a different alias.

Deployment references

Once a deployment exposes a port, other deployments can reference it using the ${deployment.<name>.<attribute>} syntax. JuhJuh resolves these references to actual IP addresses and port numbers at deploy time.

Available attributes

Attribute Returns Example
host Internal IP address of the deployment's VM 10.0.1.5
status Current deployment status HEALTHY
network Network name assigned to the deployment app-network
port.<alias> Port number for an exposed alias 5432
endpoint.<alias> Full host:port string 10.0.1.5:5432

Wiring services together

A common pattern: one deployment runs your database, another runs the application. The application deployment references the database's exposed port:

deployments:
  database:
    vm: db-server
    network: app-network
    expose:
      - port: 5432
        alias: postgres

  app:
    vm: app-server
    network: app-network
    dependsOn:
      - deployment: database
        condition: healthy

envGroups:
  app-env:
    clear:
      DATABASE_HOST: "${deployment.database.host}"
      DATABASE_PORT: "${deployment.database.port.postgres}"
      DATABASE_URL: "postgres://user:pass@${deployment.database.endpoint.postgres}/mydb"

JuhJuh resolves ${deployment.database.endpoint.postgres} to something like 10.0.1.5:5432 when deploying the app. The dependsOn field ensures the database is healthy before the app starts.

Requirements for deployment references:

  1. The target deployment must be listed in the referencing deployment's dependsOn field
  2. Port and endpoint references require the target deployment to expose that alias
  3. The target deployment must be provisioned and reporting a status before references resolve

Named networks

For deployments that need to communicate with each other, define a named network in the networks section of your JuhJuh File and assign it to each deployment.

networks:
  app-network:
    scope: organization
    driver: bridge
    subnet: auto

deployments:
  database:
    vm: db-server
    network: app-network
    expose:
      - port: 5432
        alias: postgres

  app:
    vm: app-server
    network: app-network

Network fields

Field Default Description
scope organization Network scope. All deployments in the organization can join
driver bridge Network driver
subnet auto Subnet allocation. Use auto for automatic CIDR assignment, or specify a range like 10.0.0.0/16

Deployments on the same named network can communicate with each other. Use expose to make specific ports discoverable across the network.

Config-level network settings

You can also set network properties in the config section. This applies a default network to all services in the orchestration output:

config:
  network:
    name: my-app-network
    driver: bridge

This is useful when all your services should share a single network without repeating the network name in every deployment.

Dashboard management

The PaaS dashboard shows your organization's network status:

  • Infrastructure diagram. A visual map of your VMs, deployments, firewall rules, and network connections. Public ports show internet-facing connection lines. Internal ports stay within the private network zone.
  • VM details. Each VM displays its static IP, internal IP, and the region subnet it belongs to.
  • Deployment details. Each deployment shows its exposed ports, network attachment, and the resolved deployment references.

Firewall rules can be added during VM creation through the dashboard wizard or defined in the JuhJuh File. Both paths produce the same result.

Full example

A two-VM setup with a database and an application server, connected over a private network:

name: my-app

networks:
  internal:
    scope: organization
    driver: bridge
    subnet: auto

firewall:
  - port: 80
    label: HTTP
  - port: 443
    label: HTTPS
  - port: 5432
    access: internal
    label: PostgreSQL

resources:
  postgres:
    type: postgres
    plan: standard
    config:
      max_connections: 200

vms:
  db-server:
    cpu: 2
    memory_gb: 8
    disk_gb: 100
  app-server:
    cpu: 4
    memory_gb: 16
    disk_gb: 50

deployments:
  database:
    vm: db-server
    resources: [postgres]
    network: internal
    expose:
      - port: 5432
        alias: postgres

  app:
    vm: app-server
    image: registry.example.com/my-app
    tag: v1.0.0
    network: internal
    services: [web, worker]
    dependsOn:
      - deployment: database
        condition: healthy

envGroups:
  app-env:
    clear:
      DATABASE_URL: "postgres://app:secret@${deployment.database.endpoint.postgres}/mydb"

services:
  web:
    type: web
    port: 8000
    env_from: [app-env]
  worker:
    type: worker
    env_from: [app-env]

This configuration:

  • Creates two VMs in your organization's private network
  • Opens HTTP and HTTPS publicly, keeps the database port internal
  • Exposes the database on the organization network with the alias postgres
  • Wires the application to the database using deployment references
  • Ensures the database is healthy before the application starts
  • Deployments: ship container images to VMs with network attachment and exposed ports
  • VMs: provision the machines that join your private network
  • JuhJuh File: define networks, firewall rules, and deployment references in code
  • Infrastructure Overview: see how networking fits into the full infrastructure stack
  • Vault: inject secrets into deployments alongside network configuration
  • CLI: provision and manage infrastructure from your terminal