VPN as Code: Deploy and Manage OpenVPN Access Server with Terraform, Helm and Puppet
By Rohit Kalbag
Your team can rebuild a staging cluster from a Git repo. Can it rebuild the VPN that gets everyone into it? For many teams the answer is no. The VPN is a hand-built server, configured through a console, and understood by one person.
VPN as code means treating remote-access infrastructure like any other service: provisioned from version-controlled templates, deployed with the same tooling as your workloads, and kept consistent by declared state instead of console clicks. This series shows how to do that with OpenVPN Access Server, using the official Terraform template, the official Helm chart and the Puppet module.
Why treat your VPN like code
Treating the VPN like the rest of your infrastructure pays off in four ways.
- Rebuild instead of repair. When a server is defined in code, replacing it is a command, not a rescue mission.
- Review before it changes. A VPN change becomes a pull request that a teammate can read, not a console click nobody sees.
- No quiet drift. Declared state makes the difference between what you intended and what is running visible.
- One spec, your runtime. The same environment definition works on VMs or on Kubernetes, so you choose the runtime you already operate.
One environment, three stages
Every post builds the same environment, platform-dev access, from one desired-state spec, so you can compare the tools on identical work.
|
Spec item |
Value |
|---|---|
|
DNS name |
|
|
Admin account |
|
|
Test user |
|
|
One server setting |
|
The three stages follow a lifecycle:
- Day 0, provision. Deploy OpenVPN Access Server with Terraform: a portable five-part pattern with an AWS worked example, covering cloud-init bootstrap, a static address, TLS and secrets handling.
- Day 1, run. Run OpenVPN Access Server on Kubernetes with Helm: values, persistence, a
postStartsacliscript, and the limits of container deployments. - Day 2, keep consistent. Manage Access Server configuration with Puppet and sacli: declarative config, users and properties, restart handling, and drift detection.
Which path should you take?
Terraform and Helm are alternative runtimes for the same spec, not layers on one instance. Puppet applies to a host-based server. This table shows the fit.
|
If you... |
Start with |
Why |
|---|---|---|
|
Run VMs and want a server up in about three commands |
Terraform |
One VM, cloud-init install, optional static IP and Let's Encrypt |
|
Already operate a Kubernetes cluster |
Helm |
Access Server as a workload, with config applied through |
|
Manage a fleet of hosts with Puppet |
Puppet |
Config, users and properties as declared state |
What the series is candid about
We would rather you hear the limits from us before you automate. Each post ends with its own caveats and fixes. The headline items:
- Terraform: the admin password is stored in plaintext in state and user data, SSH is open by default, there is a single instance with no high availability, and upgrades are manual because the package is held.
- Helm: the pod must run privileged on Kubernetes 1.31.3 and later, the default rollout strategy causes downtime, and failover mode, Layer 2 bridging and fixed license keys are unsupported in container deployments.
- Puppet:
saclidoes no validation, changing configuration does not restart the service, and all values must be strings.
FAQ
What does "VPN as code" mean?
Provisioning, deploying and configuring a VPN from version-controlled templates and declared state, so the environment is reproducible and reviewable like any other infrastructure.
Can I deploy OpenVPN Access Server with Terraform?
Yes. OpenVPN publishes a Terraform template for AWS, and the first post generalizes it into a pattern you can reproduce on other providers.
Does Access Server run on Kubernetes?
Yes, through the official Helm chart, which requires Kubernetes 1.20 or later and Helm 3.0 or later. The second post lists the limits of container deployments.
Is there a Puppet module for Access Server?
Yes. The puppet-openvpnas module manages configuration, users and user properties through sacli and is licensed BSD-2-Clause.
Which tool should I start with?
Start with the runtime you already operate: Terraform for VMs, Helm for Kubernetes. Add Puppet if you manage hosts with it.
Can I try Access Server before committing?
Yes, with our free plan. Try it on a test environment, then follow the series.
Is it worth it for a small team?
It can be. Even a single server benefits from a repeatable rebuild and a reviewed change history. If you rarely change the server, start with the Terraform post and stop there.
Do I need all three tools?
No. Terraform and Helm are alternative runtimes, so most teams pick one. Puppet is optional and applies to host-based servers.
What are the benefits of running Access Server as code?
You can rebuild a server instead of repairing it, review changes in a pull request before they reach users, see drift before it causes an outage, and keep one spec across environments. The series also says plainly where the tools fall short.
Why manage a VPN as code instead of through the Admin UI?
The Admin UI is good for exploring, but it is a poor system of record. Changes made by hand are not reviewed, not versioned and easy to forget, so the next server you build behaves differently. Code gives you a reviewable history and a server you can rebuild.
Get started
Pick the stage that matches your stack and start there. When you are ready, try Access Server with our free plan or read the official tutorials.