@golivekit/provision
v1.1.0
Published
Interactive CLI for provisioning GoLiveKit infrastructure via Terraform
Maintainers
Readme

Provision infrastructure for your GoLiveKit app - a Next.js AI driven starter kit.
Prerequisites
| Tool | Install |
|---|---|
| Node.js ≥ 22 | brew install node |
| Terraform ≥ 1.7 | brew install terraform |
| A cloud provider account & API token | see provider section below |
Quick start
# Provision a server — prompts guide you through every step
npx @golivekit/provision
# Provision to a custom output directory with a custom cloud-init template
npx @golivekit/provision --out ./infra --cloud-init ./my-init.yaml
# Preview the Terraform plan without applying
npx @golivekit/provision plan --out ./infra
# Tear down the provisioned infrastructure
npx @golivekit/provision destroy --out ./infraapply is the default subcommand and can be omitted. --out defaults to ./provision-out.
The CLI will:
- Ask which cloud provider to use
- Load live provider options for locations, server types, and images
- Ask for token or credentials, SSH key handling, server name, backup mode, and IPv4 or IPv6
- Stage a provider workspace in your chosen output directory
- Generate
terraform.tfvarsautomatically - Run
terraform init, show the plan, ask for confirmation, then apply
Provider setup
DigitalOcean
- Create an API token at https://cloud.digitalocean.com/account/api/tokens
- Run
npx @golivekit/provisionand paste the token when prompted - Select an existing local public key or let the CLI generate a new one
Useful region slugs: fra1 (Frankfurt), ams3 (Amsterdam), nyc3 (New York), sfo3 (San Francisco), sgp1 (Singapore)
Hetzner Cloud
- Create a project & API token at https://console.hetzner.cloud
- Run
npx @golivekit/provisionand paste the token when prompted - Select an existing local public key or let the CLI generate a new one
Useful locations: nbg1 (Nuremberg), fsn1 (Falkenstein), hel1 (Helsinki), ash (Ashburn VA), sin (Singapore)
AWS EC2
1. Create an IAM user
- Open IAM → Users → Create user at https://console.aws.amazon.com/iam/home#/users/create
- Set a username (e.g.
provision) and click Next - Choose Attach policies directly, then click Create policy
2. Create the IAM policy
In the policy editor switch to JSON and paste:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PricingReadOnly",
"Effect": "Allow",
"Action": ["pricing:GetProducts"],
"Resource": "*"
},
{
"Sid": "STSValidate",
"Effect": "Allow",
"Action": ["sts:GetCallerIdentity"],
"Resource": "*"
},
{
"Sid": "EC2Describe",
"Effect": "Allow",
"Action": ["ec2:Describe*"],
"Resource": "*"
},
{
"Sid": "EC2Mutate",
"Effect": "Allow",
"Action": [
"ec2:ImportKeyPair",
"ec2:DeleteKeyPair",
"ec2:CreateSecurityGroup",
"ec2:DeleteSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RunInstances",
"ec2:TerminateInstances",
"ec2:StopInstances",
"ec2:StartInstances",
"ec2:ModifyInstanceAttribute",
"ec2:AllocateAddress",
"ec2:ReleaseAddress",
"ec2:AssociateAddress",
"ec2:DisassociateAddress",
"ec2:AssociateVpcCidrBlock",
"ec2:DisassociateVpcCidrBlock",
"ec2:ModifySubnetAttribute",
"ec2:CreateTags"
],
"Resource": "*"
},
{
"Sid": "BackupsOptional",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:DeleteRole",
"iam:GetRole",
"iam:PassRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:ListRolePolicies",
"iam:ListAttachedRolePolicies",
"backup:CreateBackupVault",
"backup:DeleteBackupVault",
"backup:DescribeBackupVault",
"backup:CreateBackupPlan",
"backup:DeleteBackupPlan",
"backup:GetBackupPlan",
"backup:CreateBackupSelection",
"backup:DeleteBackupSelection",
"backup:GetBackupSelection"
],
"Resource": "*"
}
]
}The
BackupsOptionalblock is only needed if you enable daily backup snapshots during setup. You can omit it otherwise.
Name the policy (e.g. ProvisionEC2Policy) and click Create policy.
3. Attach the policy and get credentials
- Back in the user creation flow, refresh the policy list, select
ProvisionEC2Policy, and complete user creation - Open the user → Security credentials → Create access key
- Choose Other, give it a description, and download the key
4. Run the CLI
npx @golivekit/provisionPaste the Access Key ID and Secret Access Key when prompted. No AWS CLI required.
What gets installed on the server
The bundled cloud-init template (terraform/modules/cloud-init/server-init.yaml.tpl) runs on first boot:
- Docker CE + Docker Compose plugin
- UFW firewall — opens ports 22, 80, 443 only
- fail2ban — brute-force SSH protection
- 2 GB swapfile at
/swapfilewith conservative kernel tuning (vm.swappiness=10) deployuser — passwordless sudo, added to thedockergroup/opt/appdirectory — ready for your docker-compose deployment, including a placeholder.compose.env
Terraform state
By default state is stored locally in <out>/<provider>/terraform.tfstate.
For team use, migrate to a remote backend (Terraform Cloud, S3, etc.):
# <out>/<provider>/main.tf
terraform {
backend "s3" {
bucket = "my-tf-state"
key = "golivekit/prod.tfstate"
region = "eu-central-1"
}
}Local development
git clone [email protected]:golivekit/provision.git
cd provision
pnpm install
pnpm build
node ./dist/index.jsTerraform source files live in terraform/. Update those files when you need to change the bundled provider defaults or cloud-init template. At runtime the CLI copies the provider defaults into <out>/<provider>/ and runs Terraform there, so terraform.tfvars, state, and plan files stay project-scoped and portable.
Repository layout
.
├── package.json
├── tsconfig.json
├── terraform/ ← Bundled Terraform defaults published with the package
│ ├── modules/
│ │ └── cloud-init/
│ │ └── server-init.yaml.tpl
│ └── providers/
│ ├── aws/
│ ├── digitalocean/
│ └── hetzner/
├── src/
│ ├── index.ts ← entry point (apply / plan / destroy)
│ ├── providers/
│ │ ├── digitalocean.ts
│ │ ├── hetzner.ts
│ │ └── aws.ts
│ └── ... ← ui, prompts, ssh, terraform, tfvars helpers
└── .gitignore ← secrets & state are git-ignoredRelease
Releases are fully automated via Semantic Release. Push to main with Conventional Commits and the CI will determine the version, publish to npm, create a GitHub release, and update CHANGELOG.md automatically.
| Commit prefix | Release type |
|---|---|
| fix: ... | patch (1.0.0 → 1.0.1) |
| feat: ... | minor (1.0.0 → 1.1.0) |
| feat!: ... / BREAKING CHANGE: | major (1.0.0 → 2.0.0) |
git commit -m "feat: add support for new provider"
git push origin main