Skip to content

Commit eaf5516

Browse files
thomasgauvinOxyjunDaniFoldihyperlint-ai[bot]
authored andcommitted
thomasgauvin: add docs for hyperdrive to connect to private databases (#16766)
* thomasgauvin: add docs for hyperdrive to connect to private databases * thomasgauvin: nit on hyperdrive for private databases * thomasgauvin: more nits * thomasgauvin: adjust as per feedback * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/partials/hyperdrive/use-postgresjs-to-make-query.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx Co-authored-by: Jun Lee <[email protected]> * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx Co-authored-by: Dániel Földi <[email protected]> * Update src/content/partials/hyperdrive/create-hyperdrive-binding.mdx Co-authored-by: Jun Lee <[email protected]> * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx Co-authored-by: Jun Lee <[email protected]> * thomasgauvin: add notes for context and information, and beta label * thomasgauvin: add terraform configuration to hyperdrive private database docs * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx Co-authored-by: Jun Lee <[email protected]> * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx * Update src/content/docs/hyperdrive/configuration/connect-to-private-database.mdx Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com> --------- Co-authored-by: Jun Lee <[email protected]> Co-authored-by: Dániel Földi <[email protected]> Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com>
1 parent f30e0c1 commit eaf5516

File tree

5 files changed

+229
-64
lines changed

5 files changed

+229
-64
lines changed

src/content/docs/hyperdrive/configuration/connect-to-postgres.mdx

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ sidebar:
55
order: 3
66
---
77

8-
import { TabItem, Tabs } from "~/components";
8+
import { TabItem, Tabs, Render } from "~/components";
99

1010
Hyperdrive supports PostgreSQL and PostgreSQL-compatible databases, [popular drivers](#supported-drivers) and Object Relational Mapper (ORM) libraries that use those drivers.
1111

@@ -86,50 +86,7 @@ The following examples show you how to:
8686

8787
The following Workers code shows you how to use [Postgres.js](https://github.com/porsager/postgres) with Hyperdrive.
8888

89-
Install the Postgres.js driver:
90-
91-
```sh
92-
npm install postgres
93-
```
94-
95-
Create a new `sql` instance and pass the Hyperdrive parameters:
96-
97-
<Tabs> <TabItem label="postgres-js">
98-
99-
```ts
100-
import postgres from "postgres";
101-
102-
export interface Env {
103-
// If you set another name in wrangler.toml as the value for 'binding',
104-
// replace "HYPERDRIVE" with the variable name you defined.
105-
HYPERDRIVE: Hyperdrive;
106-
}
107-
108-
export default {
109-
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
110-
// NOTE: if `prepare: false` is passed when connecting, performance will
111-
// be slower but still correctly supported.
112-
const sql = postgres(env.HYPERDRIVE.connectionString);
113-
114-
try {
115-
// A very simple test query
116-
const result = await sql`select * from pg_tables`;
117-
118-
// Clean up the client, ensuring we don't kill the worker before that is
119-
// completed.
120-
ctx.waitUntil(sql.end());
121-
122-
// Return result rows as JSON
123-
return Response.json({ result: result });
124-
} catch (e) {
125-
console.log(e);
126-
return Response.json({ error: e.message }, { status: 500 });
127-
}
128-
},
129-
} satisfies ExportedHandler<Env>;
130-
```
131-
132-
</TabItem> </Tabs>
89+
<Render file="use-postgresjs-to-make-query" product="hyperdrive" />
13390

13491
### node-postgres / pg
13592

@@ -149,8 +106,6 @@ node_compat = true
149106

150107
Create a new `Client` instance and pass the Hyperdrive parameters:
151108

152-
<Tabs> <TabItem label="node-postgres">
153-
154109
```ts
155110
import { Client } from "pg";
156111

@@ -187,8 +142,6 @@ export default {
187142
} satisfies ExportedHandler<Env>;
188143
```
189144

190-
</TabItem> </Tabs>
191-
192145
## Identify connections from Hyperdrive
193146

194147
To identify active connections to your Postgres database server from Hyperdrive:
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
pcx_content_type: concept
3+
title: Connect to a private database using Tunnel
4+
sidebar:
5+
order: 4
6+
badge:
7+
text: Beta
8+
---
9+
10+
import { TabItem, Tabs, Render } from "~/components";
11+
12+
Hyperdrive can securely connect to your private databases using [Cloudflare Tunnel](/cloudflare-one/connections/connect-networks/) and [Cloudflare Access](/cloudflare-one/policies/access/).
13+
14+
## How it works
15+
16+
When your database is isolated within a private network (such as a [virtual private cloud](https://www.cloudflare.com/learning/cloud/what-is-a-virtual-private-cloud) or an on-premise network), you must enable a secure connection from your network to Cloudflare.
17+
18+
- [Cloudflare Tunnel](/cloudflare-one/connections/connect-networks/) is used to establish the secure tunnel connection.
19+
- [Cloudflare Access](/cloudflare-one/policies/access/) is used to restrict access to your tunnel such that only specific Hyperdrive configurations can access it.
20+
21+
<Render file="tutorials-before-you-start" product="workers" />
22+
23+
## Prerequisites
24+
25+
- A database in your private network, [configured to use TLS/SSL](/hyperdrive/configuration/connect-to-postgres/#supported-tls-ssl-modes).
26+
- A hostname on your Cloudflare account, which will be used to route requests to your database.
27+
28+
## 1. Create a tunnel in your private network
29+
30+
### 1.1. Create a tunnel
31+
32+
First, create a [Cloudflare Tunnel](/cloudflare-one/connections/connect-networks/) in your private network to establish a secure connection between your network and Cloudflare. Your network must be configured such that the tunnel has permissions to egress to the Cloudflare network and access the database within your network.
33+
34+
<Render file="tunnel/create-tunnel" product="cloudflare-one" />
35+
36+
### 1.2. Connect your database using a public hostname
37+
38+
Your tunnel must be configured to use a public hostname so that Hyperdrive can route requests to it. If you don't have a hostname on Cloudflare yet, you will need to [register a new hostname](/registrar/get-started/register-domain/) or [add a zone](/dns/zone-setups/) to Cloudflare to proceed.
39+
40+
1. In the **Public Hostnames** tab, choose a **Domain** and specify any subdomain or path information. This will be used in your Hyperdrive configuration to route to this tunnel.
41+
42+
2. In the **Service** section, specify **Type** `TCP` and the URL and configured port of your database, such as `localhost:5432`. This address will be used by the tunnel to route requests to your database.
43+
44+
3. Select **Save tunnel**.
45+
46+
:::note
47+
If you are setting up the tunnel through the CLI instead ([locally-managed tunnel](/cloudflare-one/connections/connect-networks/configure-tunnels/local-management/)), you will have to complete these steps manually. Follow the Cloudflare Zero Trust documentation to [add a public hostname to your tunnel](/cloudflare-one/connections/connect-networks/routing-to-tunnel/dns/) and [configure the public hostname to route to the address of your database](/cloudflare-one/connections/connect-networks/configure-tunnels/local-management/configuration-file/).
48+
:::
49+
50+
## 2. Create a service token
51+
52+
The service token will be used to restrict requests to the tunnel, and is needed for the next step.
53+
54+
1. In [Zero Trust](https://one.dash.cloudflare.com), go to **Access** > **Service Auth** > **Service Tokens**.
55+
56+
2. Select **Create Service Token**.
57+
58+
3. Name the service token. The name allows you to easily identify events related to the token in the logs and to revoke the token individually.
59+
60+
4. Set a **Service Token Duration** of `Non-expiring`. This prevents the service token from expiring, ensuring it can be used throughout the life of the Hyperdrive configuration.
61+
62+
5. Select **Generate token**. You will see the generated Client ID and Client Secret for the service token, as well as their respective request headers.
63+
64+
6. Copy the Access Client ID and Access Client Secret. These will be used when creating the Hyperdrive configuration.
65+
66+
:::caution
67+
This is the only time Cloudflare Access will display the Client Secret. If you lose the Client Secret, you must regenerate the service token.
68+
:::
69+
70+
## 3. Create an Access application to secure the tunnel
71+
72+
[Cloudflare Access](/cloudflare-one/policies/access/) will be used to verify that requests to the tunnel originate from Hyperdrive using the service token created above.
73+
74+
1. In [Zero Trust](https://one.dash.cloudflare.com), go to **Access** > **Applications**.
75+
76+
2. Select **Add an application**.
77+
78+
3. Select **Self-hosted**.
79+
80+
4. In **Application Configuration** > **Application name**, enter any name for the application.
81+
82+
5. In **Application Configuration** > **Session Duration**, select `No duration, expires immediately`.
83+
84+
6. In **Application Configuration** > **Application domain**, enter the subdomain and domain that was previously set for the tunnel application.
85+
86+
7. In **Application Appearance**, disable the `Enable App in App Launcher` setting.
87+
88+
8. In **Identity providers**, disable the `Accept all available identity providers` setting and select `Deselect all` identity providers.
89+
90+
9. Select **Next**.
91+
92+
10. Enter a name in the **Policy name** and set the **Action** to `Service Auth`.
93+
94+
11. In **Configure rules**, create an **Include** rule. Specify a **Selector** of `Service Token` and the **Value** of the service token you created in step [2. Create a service token](#2-create-a-service-token).
95+
96+
12. Select **Next**.
97+
98+
13. Select **Add application** to create the Access application.
99+
100+
## 4. Create a Hyperdrive configuration
101+
102+
To create a Hyperdrive configuration for your private database, you'll need to specify the Access application and Cloudflare Tunnel information upon creation.
103+
104+
<Tabs> <TabItem label="Wrangler">
105+
106+
```sh
107+
# wrangler v3.65 and above required
108+
npx wrangler hyperdrive create <NAME-OF-HYPERDRIVE-CONFIGURATION-FOR-DB-VIA-TUNNEL> --host=<HOSTNAME-FOR-THE-TUNNEL> --user=<USERNAME-FOR-YOUR-DATABASE> --password=<PASSWORD-FOR-YOUR-DATABASE> --database=<DATABASE-TO-CONNECT-TO> --access-client-id=<YOUR-ACCESS-CLIENT-ID> --access-client-secret=<YOUR-SERVICE-TOKEN-CLIENT-SECRET>
109+
```
110+
111+
</TabItem> <TabItem label="Terraform">
112+
113+
```terraform
114+
resource "cloudflare_hyperdrive_config" "<TERRAFORM_VARIABLE_NAME_FOR_CONFIGURATION>" {
115+
account_id = "<YOUR_ACCOUNT_ID>"
116+
name = "<NAME_OF_HYPERDRIVE_CONFIGURATION>"
117+
origin = {
118+
host = "<HOSTNAME_OF_TUNNEL>"
119+
database = "<NAME_OF_DATABASE>"
120+
user = "<NAME_OF_DATABASE_USER>"
121+
password = "<DATABASE_PASSWORD>"
122+
scheme = "postgres"
123+
access_client_id = "<ACCESS_CLIENT_ID>"
124+
access_client_secret = "<ACCESS_CLIENT_SECRET>"
125+
}
126+
caching = {
127+
disabled = false
128+
}
129+
}
130+
```
131+
132+
</TabItem> </Tabs>
133+
134+
This will create a Hyperdrive configuration using the usual database information (database name, database host, database user, and database password).
135+
136+
In addition, it will also set the Access Client ID and the Access Client Secret of the Service Token. When Hyperdrive makes requests to the tunnel, requests will be intercepted by Access and validated using the credentials of the Service Token.
137+
138+
:::note
139+
When creating the Hyperdrive configuration for the private database, you must enter the `access-client-id` and the `access-client-id`, and omit the `port`. Hyperdrive will route database messages to the public hostname of the tunnel, and the tunnel will rely on its service configuration (as configured in [1.2. Connect your database using a public hostname](#12-connect-your-database-using-a-public-hostname)) to route requests to the database within your private network.
140+
:::
141+
142+
## 5. Query your Hyperdrive configuration from a Worker (optional)
143+
144+
To test your Hyperdrive configuration to the database using Cloudflare Tunnel and Access, use the Hyperdrive configuration ID in your Worker and deploy it.
145+
146+
### Create a Hyperdrive binding
147+
148+
<Render file="create-hyperdrive-binding" product="hyperdrive" />
149+
150+
### Query your database using Postgres.js
151+
152+
Use Postgres.js to send a test query to validate that the connection has been successful.
153+
154+
<Render file="use-postgresjs-to-make-query" product="hyperdrive" />
155+
156+
Now, deploy your Worker:
157+
158+
```bash
159+
npx wrangler deploy
160+
```
161+
162+
If you successfully receive the list of `pg_tables` from your database when you access your deployed Worker, your Hyperdrive has now been configured to securely connect to a private database using [Cloudflare Tunnel](/cloudflare-one/connections/connect-networks/) and [Cloudflare Access](/cloudflare-one/policies/access/).

src/content/docs/hyperdrive/get-started.mdx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,21 +159,7 @@ Hyperdrive will attempt to connect to your database with the provided credential
159159

160160
## 4. Bind your Worker to Hyperdrive
161161

162-
You must create a binding for your Worker to connect to your Hyperdrive configuration. [Bindings](/workers/runtime-apis/bindings/) allow your Workers to access resources, like D1, on the Cloudflare developer platform. You create bindings by updating your `wrangler.toml` file.
163-
164-
To bind your Hyperdrive configuration to your Worker, add the following to the end of your `wrangler.toml` file:
165-
166-
```toml
167-
[[hyperdrive]]
168-
binding = "HYPERDRIVE"
169-
id = "<YOUR_DATABASE_ID>" # the ID associated with the Hyperdrive you just created
170-
```
171-
172-
Specifically:
173-
174-
- The value (string) you set for the `name` (binding name) will be used to reference this database in your Worker. In this tutorial, name your binding `HYPERDRIVE`.
175-
- The binding must be [a valid JavaScript variable name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#variables). For example, `binding = "hyperdrive"` or `binding = "productionDB"` would both be valid names for the binding.
176-
- Your binding is available in your Worker at `env.<BINDING_NAME>`.
162+
<Render file="create-hyperdrive-binding" product="hyperdrive" />
177163

178164
## 5. Run a query against your database
179165

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
{}
3+
4+
---
5+
6+
You must create a binding for your Worker to connect to your Hyperdrive configuration. [Bindings](/workers/runtime-apis/bindings/) allow your Workers to access resources, like D1, on the Cloudflare developer platform. You create bindings by updating your `wrangler.toml` file.
7+
8+
To bind your Hyperdrive configuration to your Worker, add the following to the end of your `wrangler.toml` file:
9+
10+
```toml
11+
[[hyperdrive]]
12+
binding = "HYPERDRIVE"
13+
id = "<YOUR_DATABASE_ID>" # the ID associated with the Hyperdrive you just created
14+
```
15+
16+
Specifically:
17+
18+
- The value (string) you set for the `name` (binding name) will be used to reference this database in your Worker. In this tutorial, name your binding `HYPERDRIVE`.
19+
- The binding must be [a valid JavaScript variable name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#variables). For example, `binding = "hyperdrive"` or `binding = "productionDB"` would both be valid names for the binding.
20+
- Your binding is available in your Worker at `env.<BINDING_NAME>`.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
{}
3+
---
4+
5+
Install the Postgres.js driver:
6+
7+
```sh
8+
npm install postgres
9+
```
10+
11+
Create a new `sql` instance and pass the Hyperdrive parameters:
12+
13+
```ts
14+
import postgres from "postgres";
15+
16+
export interface Env {
17+
// If you set another name in wrangler.toml as the value for 'binding',
18+
// replace "HYPERDRIVE" with the variable name you defined.
19+
HYPERDRIVE: Hyperdrive;
20+
}
21+
22+
export default {
23+
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
24+
// NOTE: if `prepare: false` is passed when connecting, performance will
25+
// be slower but still correctly supported.
26+
const sql = postgres(env.HYPERDRIVE.connectionString);
27+
28+
try {
29+
// A very simple test query
30+
const result = await sql`select * from pg_tables LIMIT 10`;
31+
32+
// Clean up the client, ensuring we don't kill the worker before that is
33+
// completed.
34+
ctx.waitUntil(sql.end());
35+
36+
// Return result rows as JSON
37+
return Response.json({ result: result });
38+
} catch (e) {
39+
console.log(e);
40+
return Response.json({ error: e.message }, { status: 500 });
41+
}
42+
},
43+
} satisfies ExportedHandler<Env>;
44+
```

0 commit comments

Comments
 (0)