Skip to content

Commit 570b4e8

Browse files
committed
docs: add private networking user-facing documentation
1 parent c69e939 commit 570b4e8

3 files changed

Lines changed: 395 additions & 0 deletions

File tree

docs/docs.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@
129129
}
130130
]
131131
},
132+
{
133+
"group": "Private networking",
134+
"pages": [
135+
"private-networking/overview",
136+
"private-networking/aws-console-setup"
137+
]
138+
},
132139
{
133140
"group": "Realtime",
134141
"pages": [
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
---
2+
title: "Setting up PrivateLink in the AWS Console"
3+
sidebarTitle: "AWS Console setup"
4+
description: "Step-by-step guide for exposing a resource from your AWS account to Trigger.dev via PrivateLink."
5+
---
6+
7+
This guide walks through setting up the AWS side of a private connection: a Network Load Balancer (NLB), a target group pointing at the resource you want to expose, and a VPC Endpoint Service that authorizes Trigger.dev to consume it.
8+
9+
<Info>
10+
Prefer Terraform? Open the "Add connection" page in the Trigger.dev dashboard and use the
11+
Terraform wizard to generate a ready-to-apply script. The wizard creates everything described
12+
below and pre-fills our AWS account ID for you.
13+
</Info>
14+
15+
## Prerequisites
16+
17+
Before you start you'll need:
18+
19+
- An **AWS account** with permission to create VPC, EC2, and ELB resources
20+
- A **resource** in a VPC subnet that you want to expose (RDS instance, ElastiCache cluster, internal API, etc.)
21+
- The **Trigger.dev AWS account ID** — find this on the "Add connection" page in your Trigger.dev dashboard, in the "I have my details" or "Step-by-step guide" cards
22+
- A **VPC** that contains the resource, with at least one private subnet per Availability Zone you want to serve from
23+
24+
<Note>
25+
PrivateLink connections are zonal. If your resource lives in a single AZ, your connection will
26+
only be available from that AZ. For higher availability, ensure target groups can route to
27+
multiple AZs.
28+
</Note>
29+
30+
## Step 1: Create an internal Network Load Balancer
31+
32+
The NLB is what PrivateLink exposes to Trigger.dev. It must be **internal** (not internet-facing).
33+
34+
<Steps>
35+
<Step title="Open the EC2 console">
36+
Go to **EC2 → Load Balancers → Create load balancer** and choose **Network Load Balancer**.
37+
</Step>
38+
<Step title="Configure the basics">
39+
- **Name**: something descriptive, e.g. `trigger-postgres-nlb`
40+
- **Scheme**: **Internal**
41+
- **IP address type**: IPv4
42+
</Step>
43+
<Step title="Choose VPC and subnets">
44+
Pick the VPC where your resource lives. Select one private subnet per AZ that should serve traffic.
45+
Each subnet you select adds an availability zone to the endpoint.
46+
</Step>
47+
<Step title="Skip the listener for now">
48+
You'll add a listener after creating the target group. You can leave the default placeholder
49+
listener and update it later, or remove it.
50+
</Step>
51+
<Step title="Create the load balancer">
52+
Click **Create load balancer**. Provisioning takes 1–2 minutes.
53+
</Step>
54+
</Steps>
55+
56+
## Step 2: Create a target group pointing at your resource
57+
58+
The target group is how the NLB knows where to forward traffic.
59+
60+
<Steps>
61+
<Step title="Open the target groups page">
62+
Go to **EC2 → Target Groups → Create target group**.
63+
</Step>
64+
<Step title="Choose a target type">
65+
- **IP addresses** for RDS, ElastiCache, or any resource you can reach by IP
66+
- **Instances** for EC2 instances you own
67+
- **Application Load Balancer** if your resource sits behind an ALB
68+
- **Lambda** for Lambda-backed services
69+
70+
For most database use cases, **IP addresses** is correct.
71+
72+
</Step>
73+
<Step title="Configure the target group">
74+
- **Name**: e.g. `trigger-postgres-tg`
75+
- **Protocol**: TCP
76+
- **Port**: the port your resource listens on (5432 for Postgres, 6379 for Redis, 3306 for MySQL, etc.)
77+
- **VPC**: same VPC as the NLB
78+
- **Health check protocol**: TCP
79+
</Step>
80+
<Step title="Register your targets">
81+
Add the IP addresses of the resource. For RDS, look up the writer endpoint's IPs (`dig <endpoint>` from inside the VPC).
82+
For ElastiCache, use the primary endpoint IPs.
83+
84+
<Warning>
85+
RDS and ElastiCache endpoints' IP addresses can change after failover or maintenance. For long-lived
86+
connections, consider running a small Lambda or sidecar that periodically resolves the DNS name and
87+
updates the target group, or use a [DNS-resolved](https://aws.amazon.com/blogs/networking-and-content-delivery/hostname-as-target-for-network-load-balancers/)
88+
target if your setup supports it.
89+
</Warning>
90+
91+
</Step>
92+
<Step title="Create the target group">
93+
Click **Create target group**.
94+
</Step>
95+
</Steps>
96+
97+
## Step 3: Add a listener on the NLB
98+
99+
<Steps>
100+
<Step title="Open the NLB you created">
101+
Go to **EC2 → Load Balancers**, select your NLB, and switch to the **Listeners** tab.
102+
</Step>
103+
<Step title="Add a TCP listener">
104+
- **Protocol**: TCP
105+
- **Port**: same as your target group port (5432, 6379, etc.)
106+
- **Default action**: forward to the target group you just created
107+
</Step>
108+
<Step title="Save">
109+
Click **Add**. The listener becomes active immediately.
110+
</Step>
111+
</Steps>
112+
113+
<Tip>
114+
Test connectivity from a bastion host or another instance in the same VPC before continuing —
115+
e.g. `psql -h <nlb-dns-name> -p 5432 -U user -d db`. If the NLB can't reach your resource, the
116+
PrivateLink connection won't either.
117+
</Tip>
118+
119+
## Step 4: Create a VPC Endpoint Service
120+
121+
This is the resource that PrivateLink consumers connect to.
122+
123+
<Steps>
124+
<Step title="Open the VPC console">
125+
Go to **VPC → Endpoint services → Create endpoint service**.
126+
</Step>
127+
<Step title="Configure the endpoint service">
128+
- **Name**: optional, but useful for identification, e.g. `trigger-postgres-endpoint`
129+
- **Load balancer type**: Network
130+
- **Available load balancers**: select the NLB you created
131+
- **Require acceptance for endpoint**: **No** (recommended)
132+
133+
<Note>
134+
If you set "Require acceptance" to **Yes**, every connection request from Trigger.dev will
135+
sit in a pending state until you manually approve it. Setting it to **No** lets connections
136+
come up automatically once the principal is allow-listed.
137+
</Note>
138+
139+
</Step>
140+
<Step title="Skip private DNS">
141+
Leave the "Private DNS name" option disabled. Trigger.dev tasks dial the endpoint by IP via
142+
injected environment variables, so private DNS isn't needed.
143+
</Step>
144+
<Step title="Create the endpoint service">
145+
Click **Create**. Note the **Service name** — it looks like `com.amazonaws.vpce.us-east-1.vpce-svc-0123abcd...`.
146+
You'll paste this into the Trigger.dev dashboard.
147+
</Step>
148+
</Steps>
149+
150+
## Step 5: Authorize the Trigger.dev AWS account
151+
152+
By default, no one can connect to your endpoint service. You need to explicitly allow Trigger.dev's AWS account.
153+
154+
<Steps>
155+
<Step title="Open your endpoint service">
156+
Go to **VPC → Endpoint services**, select the service you just created.
157+
</Step>
158+
<Step title="Open the Allow principals tab">
159+
Click the **Allow principals** tab, then **Allow principals**.
160+
</Step>
161+
<Step title="Add Trigger.dev's account">
162+
Paste the principal ARN in this format, replacing `<account-id>` with the Trigger.dev AWS
163+
account ID shown in your dashboard:
164+
165+
```text
166+
arn:aws:iam::<account-id>:root
167+
```
168+
169+
<Warning>
170+
You will find the correct AWS account ID in the **Add connection** page of the Trigger.dev
171+
dashboard. Do not assume an account ID — it differs between Trigger.dev environments.
172+
</Warning>
173+
174+
</Step>
175+
<Step title="Click Allow principals">
176+
The principal is now authorized to create a VPC Endpoint targeting your service.
177+
</Step>
178+
</Steps>
179+
180+
## Step 6: Add the connection in Trigger.dev
181+
182+
<Steps>
183+
<Step title="Open the dashboard">
184+
In Trigger.dev, go to **Organization Settings → Private Connections** and click **Add
185+
connection**.
186+
</Step>
187+
<Step title="Pick the I have my details card">
188+
Then fill in:
189+
190+
- **Friendly name**: a short identifier — this becomes the env var name. For `my-postgres` you'll get `TRIGGER_PRIVATE_LINK_MY_POSTGRES`.
191+
- **VPC Endpoint Service name**: paste the `com.amazonaws.vpce.<region>.vpce-svc-...` value from Step 4.
192+
- **Target region**: the AWS region your endpoint service lives in.
193+
194+
</Step>
195+
<Step title="Submit">
196+
Submit the form. The connection's status moves through **Pending → Provisioning → Active**.
197+
Provisioning typically takes 30–90 seconds.
198+
</Step>
199+
<Step title="Verify">
200+
Once **Active**, the dashboard shows the assigned IPs. These are now available in your tasks
201+
via `process.env.TRIGGER_PRIVATE_LINK_<NAME>`.
202+
</Step>
203+
</Steps>
204+
205+
## Troubleshooting
206+
207+
<Expandable title="Status stays at Pending or Provisioning for several minutes">
208+
- Confirm Trigger.dev's AWS account ID is in your endpoint service's **Allow principals** list.
209+
- Confirm the endpoint service is **Available** in the AWS console.
210+
- Confirm "Require acceptance" is set to **No** on the endpoint service. If it's set to **Yes**,
211+
the request is sitting in your pending queue and you must approve it manually.
212+
</Expandable>
213+
214+
<Expandable title="Status is Active but my task can't connect">
215+
- Confirm the NLB has a target registered and the target's health check is passing.
216+
- Confirm the listener port matches the port your task code is dialing.
217+
- Confirm the security group on your resource allows inbound traffic from the NLB or the VPC's
218+
private IP range.
219+
- Try connecting from inside the VPC first (e.g., a bastion host) to rule out resource-side
220+
issues.
221+
</Expandable>
222+
223+
<Expandable title="Connection works but is slow">
224+
- Cross-region connections add ~10–30ms RTT depending on the regions involved. If your tasks run
225+
in a different region than your resource, expect higher latency.
226+
- The NLB and target group's health checks influence connection setup time. Tighter health check
227+
intervals reduce failover time after a backend goes unhealthy.
228+
</Expandable>
229+
230+
<Expandable title="I want to remove a connection">
231+
Delete the connection from **Organization Settings → Private Connections** in the Trigger.dev
232+
dashboard. We'll tear down our VPC Endpoint and remove the network policy automatically. You can
233+
then delete your VPC Endpoint Service, NLB, and target group on the AWS side.
234+
</Expandable>

0 commit comments

Comments
 (0)