AWS CloudFormation
Deploy the Broch appliance into your own AWS account with a CloudFormation stack.
Choose your identity provider and launch
The launch chooser opens the template for your identity provider in the AWS console: Microsoft Entra ID, Okta, Auth0 or any OIDC provider. The template lives in broch-io/broch-deploy, and its README explains the parameters.
Before You Deploy
Section titled “Before You Deploy”- An AWS identity that can create EC2, IAM, RDS, Route 53, Secrets Manager, Elastic IP and Lambda resources, including
iam:PassRolefor the roles the stack creates. - A public subnet for the instance: a route to an internet gateway, with auto-assign public IPv4 turned on. The default VPC’s subnets qualify. A new RDS database, the default, also needs subnets in two or more Availability Zones of the same VPC. Three or more make an RDS capacity shortage less likely, and the instance’s subnet can be one of them.
- A DNS zone you control on Route 53, Cloudflare, DigitalOcean or Google Cloud DNS (experimental). Route 53 needs a public hosted zone in the same AWS account, and no credential: the stack’s own role updates it. Broch serves
broch.{your-domain}and every tunnel URL under*.broch.{your-domain}, with a certificate it issues and renews itself. Or bring your own certificate covering both names; renewing it is then up to you. CloudFormation limits a parameter to 4,096 bytes: an ECDSA certificate’s base64 chain usually fits, an RSA chain usually doesn’t (check withbase64 -w0 fullchain.pem | wc -c). - An identity provider app: a web (confidential) client with the redirect URI
https://broch.{your-domain}/auth/callback. Note its client ID and secret, a role your first admin holds, and your provider’s own values: domain (Auth0, Okta), API Identifier (Auth0), tenant ID (Entra ID) or issuer URL (generic OIDC). See Auth0, Entra ID, Okta or Generic OIDC. - A master key:
openssl rand -base64 48. Keep it in your own secret store and supply the same value on every redeploy. - An email address for your Let’s Encrypt account, required even with your own certificate.
- Connecting to your own PostgreSQL? It must accept connections from the instance before you deploy, or the stack rolls back. With
ExistingServer, the server must be in this VPC or a peered one; the stack opens its security group to the instance. WithExistingDatabasein the same or a peered VPC, allow the instance subnet’s CIDR. Outside the VPC, allocate an Elastic IP first, allow-list it, and enter its allocation ID and address under Existing Elastic IP - optional; it must be unassociated, and you can’t change it later. The template’s Prerequisites have the detail.
Deploy
Section titled “Deploy”Launch the stack, choose your region, and fill in the console’s sections. Leave the sections for options you didn’t choose at their defaults.
| Section | What it asks |
|---|---|
| Start here - domain and encryption | Your DNS zone ({your-domain}), the subdomain (default broch, giving broch.{your-domain}) and your master key. |
| DNS and HTTPS - choose how they work | Your DNS provider, then its own section: the hosted zone ID for Route 53 (needed even with your own certificate), or the provider’s API credential for automatic certificates. Certificates Auto, or Byo with your certificate chain and key, base64-encoded, under Your own HTTPS certificate - only for Byo mode. Your Let’s Encrypt email. Create DNS records automatically? Auto by default, so the appliance creates and maintains the A records. Choose Manual only when a load balancer or NAT sits in front of the instance, or you manage DNS yourself. |
| Database - choose one mode | NewServer (a private, encrypted RDS PostgreSQL, the default), ExistingDatabase (a connection string), ExistingServer (a database and role created on a Postgres server you run) or Local (Postgres on the instance; you manage backups). Then that mode’s section. NewServer needs DbSubnetIds under New RDS database - only for NewServer mode; its size, DbInstanceClass, defaults to db.t4g.micro. An ExistingDatabase connection string can’t contain a single quote: wrap a password in double quotes instead (Password="a;b"). Local needs DataVolumeAz, the instance subnet’s Availability Zone. |
| Your provider’s sign-in, such as Auth0 sign-in | Client ID and secret, and AuthAdminRoles (default broch_admin): a comma-separated list, one of which your first admin holds. Plus your provider’s own fields, all required: AuthDomain for Auth0 and Okta, AuthTenantId and AuthInstance for Entra ID, AuthAuthority for any other OIDC provider, and for Auth0 AuthAudience, the Identifier of your Auth0 API. |
| AWS network and instance | VpcId, InstanceSubnetId (in that VPC) and InstanceType (default t4g.small, Arm). For an x86 instance type, replace arm64 with amd64 in the default UbuntuAmi path under Image and version - advanced. |
| Image and version - advanced | BrochVersion, a pinned release by default. |
Tick the IAM acknowledgement (the stack creates IAM roles), then create the stack. A misconfigured combination, such as a DNS provider with no credential, fails before anything is built.
First boot takes 3–10 minutes, and the stack rolls back if Broch never reports healthy. With NewServer, the instance starts only once RDS is ready, so the whole stack takes longer.
If creation fails on BrochDB with no Availability Zones with sufficient capacity, the stack rolls back and stays in ROLLBACK_COMPLETE, holding its name. Delete it, then create it again with another DbInstanceClass, such as db.t4g.small or db.t3.micro, or with subnets in more Availability Zones.
To deploy from the command line or your own checkout instead, follow the template’s Build & deploy.
After It Deploys
Section titled “After It Deploys”-
Find the public IP in the stack’s Outputs (
PublicIp, withDnsHintandSsmCommand). -
Check DNS. The appliance creates and maintains the A records for
broch.{your-domain}and*.broch.{your-domain}, pointing at the public IP. With Manual A records or your own certificate, it creates none; add them yourself, DNS-only rather than proxied:A broch.{your-domain} → <public-ip>A *.broch.{your-domain} → <public-ip>Check that both names resolve to the public IP (
teststands in for any tunnel name):Terminal window nslookup broch.{your-domain}nslookup test.broch.{your-domain}The server is ready when
https://broch.{your-domain}/healthzreturns 200. -
Sign in at
https://broch.{your-domain}with an account holding an admin role. Setup offers the free trial or a purchase. The trial is free until the 1st of the month, at least 15 days, with a card upfront, first charged on that 1st. There’s no license key to get beforehand. See Licensing & Billing. -
Grant access. Share is deny-by-default: add a Share Policy for your developers’ IdP role.
-
Invite developers. Send them Sharing Local Services to install the CLI and open their first tunnel.
What You Get
Section titled “What You Get”- The Broch appliance on one EC2 instance. Architecture describes how it fits together.
- An Elastic IP that survives instance replacement, with ports 80 and 443 open and SSH closed.
- PostgreSQL in the mode you chose.
- Secrets Manager entries for the deploy-time secrets.
- A wildcard certificate, issued and renewed automatically unless you brought your own.
- No charge from Broch to deploy; your cloud provider bills the VM and database. After the trial, Broch Share is priced per active user (pricing).
Upgrades, secret rotation, backup and teardown: Operating the Appliance.
Next: Share Policies.