Test-Driven Infrastructure with Pulumi and Jest

Arnold LovasArnold Lovas
3 min read

A smoke-tested VPS is a happy VPS

Modern infrastructure development doesn’t have to involve mountains of YAML or some arcane DSL. If you think like a Node.js developer, then infrastructure as code is just another module — and like every other module, it can (and should) be tested.

Pulumi + Jest = Infrastructure you actually validate

Creating a Hetzner VPS with TypeScript is straightforward:

const vps = new Server(serverName, {
    name: serverName,
    serverType: "cx22",
    image: "ubuntu-22.04",
    location: "nbg1",
    sshKeys: [sshKey.name],
});

Then comes the firewall — with a single open port:

const firewall = new Firewall(firewallResourceName, {
    name: firewallResourceName,
    rules: [
        {
            direction: "in",
            protocol: "tcp",
            port: "22",
            sourceIps: ["0.0.0.0/0", "::/0"],
            description: "Allow SSH from anywhere",
        },
    ],
});

The entire infra update process follows a Node-style workflow:

"scripts": {
    "preview:prod:critical:vps": "pulumi preview --cwd critical/vps --stack prod",
    "prod:critical:vps": "pulumi up --cwd critical/vps --stack prod --yes",
    "test": "jest"
}

Testing: not just for applications

Running jest gives you immediate feedback on whether the infrastructure is actually functioning. We’re not just testing whether “the script ran,” but whether the result is alive and accessible.

Terminal output:

> test
> jest

 PASS  critical/vps/vps.test.ts (14.711 s)
  Hetzner VPS basic checks
    ✓ server is running and has a public IP (3 ms)
  Expected open ports
    ✓ port 22 should be open (124 ms)
  Expected closed ports
    ✓ port 21 should NOT be open (1148 ms)
    ✓ port 23 should NOT be open (1029 ms)
    ✓ port 25 should NOT be open (1037 ms)
    ✓ port 80 should NOT be open (1037 ms)
    ✓ port 443 should NOT be open (1034 ms)
    ✓ port 3306 should NOT be open (1037 ms)
    ✓ port 5432 should NOT be open (1036 ms)
    ✓ port 6379 should NOT be open (1035 ms)
    ✓ port 11211 should NOT be open (1035 ms)
    ✓ port 8080 should NOT be open (1035 ms)
    ✓ port 9000 should NOT be open (1034 ms)
    ✓ port 9100 should NOT be open (1036 ms)
    ✓ port 9200 should NOT be open (1070 ms)

Test Suites: 1 passed, 1 total  
Tests:       15 passed, 15 total  
Snapshots:   0 total  
Time:        14.739 s, estimated 16 s  
Ran all test suites.

Why does this matter?

Because a pulumi up is not a guarantee that your server is alive, reachable, or secure. With this approach:

  • Smoke tests confirm that the VPS is created and has a public IP
  • Positive port checks ensure the intended ports are accessible
  • Negative port checks verify that everything else stays closed

The whole setup gives you feedback within 15 seconds: the server is alive, nothing unnecessary is exposed, and you’re good to deploy.


If your infrastructure is just another Node module, feel free to treat it like one. Here, npm run test doesn’t just validate code — it validates the entire environment your app is supposed to run on.

0
Subscribe to my newsletter

Read articles from Arnold Lovas directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Arnold Lovas
Arnold Lovas

Senior full-stack dev with an AI twist. I build weirdly useful things on my own infrastructure — often before coffee.