https://github.com/marcuwynu23/terraform-cloudflare-d1
This Terraform project provisions a Cloudflare D1 serverless SQL database using the official Cloudflare Terraform provider.
https://github.com/marcuwynu23/terraform-cloudflare-d1
cloudflare-d1 cloudflare-provisioning d1 d1-database example provisioning serverless-database sql-database terraform terraform-cloudflare terraform-d1-provisioning terraform-project
Last synced: 9 days ago
JSON representation
This Terraform project provisions a Cloudflare D1 serverless SQL database using the official Cloudflare Terraform provider.
- Host: GitHub
- URL: https://github.com/marcuwynu23/terraform-cloudflare-d1
- Owner: marcuwynu23
- Created: 2026-05-13T01:17:50.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-05-13T01:39:23.000Z (about 1 month ago)
- Last Synced: 2026-05-13T03:24:19.276Z (about 1 month ago)
- Topics: cloudflare-d1, cloudflare-provisioning, d1, d1-database, example, provisioning, serverless-database, sql-database, terraform, terraform-cloudflare, terraform-d1-provisioning, terraform-project
- Language: HCL
- Homepage:
- Size: 13.7 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# terraform-cloudflare-d1
This Terraform project provisions a Cloudflare D1 serverless SQL database using the official Cloudflare Terraform provider.
## Features
- Provisions a Cloudflare D1 database via Infrastructure as Code
- Configurable database name, jurisdiction, and primary location hint
- Sensitive API token handling through Terraform variables
- Outputs database ID and name for downstream use (e.g., Worker bindings)
## Prerequisites
- [Terraform](https://developer.hashicorp.com/terraform/downloads) `>= 1.0`
- A [Cloudflare account](https://dash.cloudflare.com/sign-up)
- A Cloudflare API Token with **D1 Edit** permissions
- Your Cloudflare **Account ID**
### How to get your Cloudflare API Token
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/).
2. Go to **My Profile** → **API Tokens**, or open [this direct link](https://dash.cloudflare.com/profile/api-tokens).
3. Click **Create Token**.
4. Under **Custom token**, click **Get started**.
5. Give the token a descriptive name (e.g., `terraform-d1`).
6. Under **Permissions**, add:
- `Account` → `D1` → `Edit`
7. Under **Account Resources**, select the account you want this token scoped to (e.g., `Include` → ``).
8. (Optional) Set **TTL** and **IP Address Filtering** as needed.
9. Click **Continue to summary** → **Create Token**.
10. Copy the generated token immediately and store it securely — it won't be shown again.
> Use a scoped API token (D1 Edit only) rather than your Global API Key for least-privilege access.
### How to get your Cloudflare Account ID
**Option A — From the dashboard URL**
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/).
2. Select any domain/account from your home page.
3. Look at the URL — it will be in the form:
`https://dash.cloudflare.com//...`
4. Copy the `` segment.
**Option B — From the Account home page**
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/).
2. Click **Workers & Pages** (or any domain overview).
3. On the right sidebar, find **Account ID** and click the copy icon.
**Option C — Via the API**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/accounts" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json"
```
The `result[].id` field in the JSON response is your Account ID.
## Usage
### 1. Clone and configure
```bash
git clone https://github.com/marcuwynu23/terraform-cloudflare-d1.git
cd terraform-cloudflare-d1
cp terraform.tfvars.example terraform.tfvars
```
### 2. Set your values in `terraform.tfvars`
```hcl
cloudflare_api_token = "your-api-token-here"
cloudflare_account_id = "your-account-id-here"
database_name = "my-database"
```
### 3. Initialize Terraform
```bash
terraform init
```
### 4. Preview changes
```bash
terraform plan
```
### 5. Apply
```bash
terraform apply
```
### 6. Destroy (when no longer needed)
```bash
terraform destroy
```
## Variables
| Name | Description | Type | Default | Required |
| ----------------------- | ---------------------------------------- | -------- | ------------- | :------: |
| `cloudflare_api_token` | Cloudflare API Token with D1 permissions | `string` | n/a | yes |
| `cloudflare_account_id` | Cloudflare Account ID | `string` | n/a | yes |
| `database_name` | Name of the D1 database | `string` | `my-database` | no |
## Outputs
| Name | Description |
| ------------------ | ----------------------- |
| `d1_database_id` | UUID of the D1 database |
| `d1_database_name` | Name of the D1 database |
## Optional Configuration
The `cloudflare_d1_database` resource supports two optional arguments (commented in `main.tf`):
- `jurisdiction` — restrict data location. Valid values: `eu`, `fedramp`
- `primary_location_hint` — preferred region. Valid values: `wnam`, `enam`, `weur`, `eeur`, `apac`, `oc`
Uncomment and set them in `main.tf` as needed.
## Binding D1 to a Worker
After applying, use the output `d1_database_id` in your `wrangler.toml`:
```toml
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = ""
```
## Testing with the `examples/` folder
The [`examples/`](./examples) folder contains a Node.js script (`index.js`) that verifies the provisioned D1 database by running full CRUD operations through the Cloudflare REST API using the built-in `fetch`. Environment variables are loaded from `examples/.env` via [`dotenv`](https://www.npmjs.com/package/dotenv).
### Requirements
- Node.js `>= 18` (for native `fetch`)
### 1. Get the D1 database ID from Terraform
After `terraform apply`, capture the database UUID:
```bash
terraform output d1_database_id
```
### 2. Configure environment variables
```bash
cd examples
cp .env.example .env
```
Edit `examples/.env` and fill in the values:
```dotenv
CLOUDFLARE_API_TOKEN=your-api-token-here
CLOUDFLARE_ACCOUNT_ID=your-account-id-here
CLOUDFLARE_D1_DATABASE_ID=your-d1-database-id-here
```
> `examples/.env` is gitignored — `.env.example` is committed as a template.
### 3. Install dependencies and run
```bash
cd examples
npm install
node index.js
```
Or using the npm script:
```bash
npm start
```
### What the script does
1. Creates a `users` table if it does not exist
2. Inserts a demo user
3. Fetches the user by id
4. Updates the user
5. Lists all users
6. Deletes the demo user
Expected output (abbreviated):
```
→ Creating table 'users' if not exists...
→ Creating user: Alice
Created: { id: 1, name: 'Alice', ... }
→ Fetching user id=1
Fetched: { id: 1, ... }
→ Updating user id=1
Updated: { id: 1, name: 'Alice Updated', ... }
→ Listing users
All users: [ { ... } ]
→ Deleting user id=1
Deleted rows: 1
```
## Security Notes
- `terraform.tfvars` and `*.tfstate` files are gitignored — never commit secrets
- The API token variable is marked `sensitive` to prevent accidental log exposure
- Use a scoped API token (D1 Edit only) rather than a Global API Key
## References
- [Cloudflare D1 documentation](https://developers.cloudflare.com/d1/)
- [Cloudflare Terraform provider](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs)
- [cloudflare_d1_database resource](https://developers.cloudflare.com/api/terraform/resources/d1/subresources/database/)
## License
MIT