Terraform Provider
The DataRecs Terraform provider (terraform-provider-datarecs) manages 14 resource types and one data source. It is not yet published to the Terraform/OpenTofu registry — install it locally via dev_overrides until that changes.
Installing (dev_overrides)
Section titled “Installing (dev_overrides)”Clone terraform-datarecs-config, build the binary, and point Terraform at it directly — no required_providers block or registry lookup involved while using dev_overrides:
git clone https://github.com/datarecs/terraform-datarecs-configcd terraform-datarecs-configgo build -o terraform-provider-datarecsprovider_installation { dev_overrides { "registry.terraform.io/datarecs/datarecs" = "/absolute/path/to/terraform-datarecs-config" } direct {}}With dev_overrides active, Terraform uses the local binary for any config referencing datarecs/datarecs and skips version/lock-file checks entirely — omit required_providers, or it will be ignored anyway. tofu plan/tofu apply will print a warning noting the override is in effect; that’s expected.
Provider configuration
Section titled “Provider configuration”provider "datarecs" { api_key = var.datarecs_api_key host = "https://api.datarecs.io" # optional — this is already the default}| Parameter | Description | Default |
|---|---|---|
api_key | A DataRecs API key. Also settable via DATARECS_API_KEY. | Required |
host | The DataRecs API base URL. Also settable via DATARECS_HOST. | https://api.datarecs.io |
Resources
Section titled “Resources”All 14 resources below are generated directly from the provider’s schema (go generate ./... → tfplugindocs), so this list can’t silently drift out of sync with the code. Each shows required attributes, notable optional ones, and any RequiresReplace (in-place update not supported — Terraform destroys and recreates) caveat.
datarecs_workspace
Section titled “datarecs_workspace”resource "datarecs_workspace" "production" { name = "production"}Required: name. Optional: description, metadata (map), settings (map). Read-only: id, slug, version.
datarecs_api_key
Section titled “datarecs_api_key”resource "datarecs_api_key" "ci" { name = "ci-pipeline" scopes = [datarecs_workspace.production.id] permissions = ["view_job", "run_job", "view_job_results"]}Required: name. Optional: description, metadata, scopes (workspace IDs, or ["*"] for tenant-wide), permissions (lowercase snake_case strings, e.g. view_job/run_job — not the TypeScript enum’s PascalCase member names), expiry_time. scopes and permissions both RequiresReplace — narrowing/widening access means a new key. See Managing API Keys for the full permission model and the 6 permissions that can never be granted to a key.
datarecs_connection
Section titled “datarecs_connection”resource "datarecs_connection" "warehouse" { name = "warehouse-postgres" type = "postgres" workspace_id = datarecs_workspace.production.id credentials = { host = "warehouse.internal" port = "5432" database = "analytics" username = var.db_username password = var.db_password }}Required: name, type, credentials (map, sensitive), workspace_id. Optional: description, metadata, workspace_ids (sharing; defaults to [workspace_id]). Read-only: id, config, version. type and workspace_id RequiresReplace; credentials updates in place (how you rotate a password). See Creating a Connection for the credentials shape per connector type.
datarecs_job
Section titled “datarecs_job”resource "datarecs_job" "daily_check" { name = "daily-balance-check" workspace_id = datarecs_workspace.production.id dimensions = ["region"] measures = [{ name = "amount", aggregation = "SUM" }] connections = [ { connection_id = datarecs_connection.source_a.id source_schema = "public" source_table = "orders" column_mapping = { region = "region" } }, { connection_id = datarecs_connection.source_b.id source_schema = "public" source_table = "orders" column_mapping = { region = "region" } } ] stages = [ { dimensions = ["region"] tolerances = [{ measure_name = "amount", type = "ABSOLUTE", value = 0.01 }] } ]}Required: name, workspace_id, dimensions, measures ({name, aggregation}), connections ({connection_id, source_schema, source_table, column_mapping}, optional filters/source_database), stages ({dimensions, tolerances}). Optional: stage_execution_strategy, max_stage_concurrency, notification_emails, email_detail_level, max_email_rows. See Configuring a Reconciliation Job for every field.
datarecs_job_schedule
Section titled “datarecs_job_schedule”resource "datarecs_job_schedule" "nightly" { job_id = datarecs_job.daily_check.id workspace_id = datarecs_workspace.production.id cron_expression = "0 2 * * *" timezone = "UTC"}Required: job_id, workspace_id, cron_expression (5-field cron). Optional: enabled (default true), timezone (default UTC).
datarecs_job_group
Section titled “datarecs_job_group”resource "datarecs_job_group" "finance" { name = "finance-reconciliations" workspace_id = datarecs_workspace.production.id job_ids = [datarecs_job.daily_check.id]}Required: name, workspace_id, job_ids. Optional: description.
datarecs_webhook_endpoint
Section titled “datarecs_webhook_endpoint”resource "datarecs_webhook_endpoint" "slack" { url = "https://hooks.example.com/datarecs" description = "Slack failure alerts" rate_limit_rps = 10}Required: url (HTTPS). Optional: description, enabled, rate_limit_rps (default 50), payload_format (standard/slack/teams/custom), payload_template, header_template, content_type. Read-only: id, signing_secret (sensitive, populated only on creation), version. See Using Webhooks and Customising Webhook Payloads.
datarecs_webhook_subscription
Section titled “datarecs_webhook_subscription”resource "datarecs_webhook_subscription" "run_complete" { endpoint_id = datarecs_webhook_endpoint.slack.id event_types = ["reconciliation.run.completed", "reconciliation.run.errored"]}Required: endpoint_id, event_types (unprefixed dotted strings; ["*"] for all; supports prefix patterns like "reconciliation.*"). Optional: enabled, filters (map).
datarecs_webhook_secret
Section titled “datarecs_webhook_secret”resource "datarecs_webhook_secret" "slack_token" { endpoint_id = datarecs_webhook_endpoint.slack.id name = "slack_token" value = var.slack_token}Required: endpoint_id (RequiresReplace), name (RequiresReplace, must match ^[A-Za-z_][A-Za-z0-9_]*$), value (sensitive — referenced from payload/header templates as {{ secrets.<name> }}). The plaintext value is never persisted to Terraform state — only its SHA-256 digest (value_sha256) is, which is what drives rotation detection. Rotate by changing value.
datarecs_email_settings
Section titled “datarecs_email_settings”resource "datarecs_email_settings" "tenant" { email_detail_level = "STAGE_SUMMARY" allow_workspace_override = true}A singleton — exactly one per tenant. Required: email_detail_level (DISABLED/STATUS_ONLY/STAGE_SUMMARY/FULL_DATA), allow_workspace_override. Optional: max_email_rows (default 25, max 1000), template_footer_text, template_legal_disclaimer. No import support.
datarecs_email_recipient_rule
Section titled “datarecs_email_recipient_rule”resource "datarecs_email_recipient_rule" "team_domain" { rule_type = "DOMAIN" pattern = "*@acme.com"}Required: rule_type (EXACT/DOMAIN/WILDCARD), pattern. Optional: description. Rules are immutable server-side — changing rule_type, pattern, or description destroys and recreates. No import support.
datarecs_encryption_key (BYOK)
Section titled “datarecs_encryption_key (BYOK)”resource "datarecs_encryption_key" "byok" { gcp_project_id = var.gcp_project_id keyring_name = "datarecs-tenant-keyring" key_name = "datarecs-tenant-key"}Required: gcp_project_id, keyring_name, key_name. Read-only: encryption_mode, kms_key_uri, migration_status, tenant_service_account. See Bring your own key.
datarecs_storage_bucket (BYOS)
Section titled “datarecs_storage_bucket (BYOS)”resource "datarecs_storage_bucket" "byos" { gcp_project_id = var.gcp_project_id bucket_name = "acme-datarecs-artifacts" bucket_region = "us-central1"}Required: gcp_project_id, bucket_name, bucket_region. Read-only: migration_status, storage_mode, storage_provider, tenant_service_account. See Bring your own storage.
datarecs_oidc_connector
Section titled “datarecs_oidc_connector”resource "datarecs_oidc_connector" "github_actions" { name = "github-actions" issuer_url = "https://token.actions.githubusercontent.com" audience = "https://api.datarecs.io/${data.datarecs_tenant_info.current.tenant_id}" permissions = ["view_job", "run_job"]
claim_conditions = [ { claim_name = "repository" operator = "equals" expected_value = "acme/data-pipelines" } ]}Required: name, issuer_url, audience, permissions, claim_conditions (at least one; each {claim_name, operator, expected_value}, operator one of equals/starts_with/ends_with/contains/matches). Read-only: status, created_at, updated_at. Enables keyless CI/CD authentication via OIDC federation — no long-lived API key stored in your CI provider.
Data source: datarecs_tenant_info
Section titled “Data source: datarecs_tenant_info”data "datarecs_tenant_info" "current" {}
output "tenant_id" { value = data.datarecs_tenant_info.current.tenant_id}Read-only: id, tenant_id, gcp_project_id, tenant_service_account. Useful for building an OIDC connector’s audience (above) or referencing your tenant’s service account without hardcoding it.
Importing existing resources
Section titled “Importing existing resources”| Resource | Import support |
|---|---|
datarecs_workspace, datarecs_api_key, datarecs_connection, datarecs_job, datarecs_job_schedule, datarecs_job_group, datarecs_webhook_endpoint, datarecs_webhook_subscription, datarecs_webhook_secret, datarecs_encryption_key, datarecs_storage_bucket, datarecs_oidc_connector | Yes |
datarecs_email_settings, datarecs_email_recipient_rule | No — create these as new Terraform-managed resources |
tofu import datarecs_workspace.production <workspace-id>tofu import datarecs_connection.warehouse <connection-id>tofu import datarecs_webhook_endpoint.slack <endpoint-id>Environment variables
Section titled “Environment variables”| Variable | Description |
|---|---|
DATARECS_API_KEY | API key (alternative to the provider’s api_key argument) |
DATARECS_HOST | API host (alternative to the provider’s host argument). This is the provider’s own variable — the CLI’s equivalent is DATARECS_API_URL, a different name for a different tool. |