Getting Started With Fivetran for Terraform
This guide walks you through installing the Fivetran Terraform provider, configuring authentication, and creating your first connection as infrastructure as code using the fivetran_connection_v2 resource.
fivetran_connection_v2 and fivetran_connection_v2_pause_state are in alpha.
Prerequisites
- Terraform CLI v1.0 or later installed
- A Fivetran account
- A Fivetran API key and secret pair (see Authenticate)
- Credentials and configuration details for a BigQuery destination and PostgreSQL source
Configure the provider
Create a main.tf file and declare the Fivetran provider:
terraform {
required_providers {
fivetran = {
source = "fivetran/fivetran"
version = "~> 1.9.40"
}
}
}
provider "fivetran" {}
The ~> 1.9.40 constraint allows patch releases from version 1.9.40 onward but does not automatically upgrade to version 1.10 or later.
Run the following command to download the provider:
terraform init
Authenticate
The provider authenticates using your Fivetran API key and secret. Never commit credentials directly in .tf files.
You can use one of the following API key types:
- A scoped API key, which is tied to your Fivetran user account and inherits your RBAC permissions, so you can only access resources within your permission scope.
- A service account API key, which uses a dedicated Fivetran account for programmatic API access.
The Terraform provider requires the API key and API secret as separate values. A Base64-encoded API key is intended for direct API or CLI authentication and cannot be used as either provider value.
Make sure your API key and secret inherit sufficient permissions to manage the resources you intend to provision.
Option 1: Use provider environment variables
Export the provider-specific environment variables:
export FIVETRAN_APIKEY="your-api-key"
export FIVETRAN_APISECRET="your-api-secret"
With the empty provider block shown above, the provider automatically reads FIVETRAN_APIKEY and FIVETRAN_APISECRET.
Option 2: Use Terraform variables in CI/CD
If your CI/CD system injects Terraform variables, declare them as sensitive. Replace the empty provider block from the previous section with the following configuration:
variable "fivetran_api_key" {
type = string
sensitive = true
}
variable "fivetran_api_secret" {
type = string
sensitive = true
}
provider "fivetran" {
api_key = var.fivetran_api_key
api_secret = var.fivetran_api_secret
}
Inject the values through TF_VAR_ environment variables:
export TF_VAR_fivetran_api_key="$FIVETRAN_APIKEY"
export TF_VAR_fivetran_api_secret="$FIVETRAN_APISECRET"
Terraform automatically reads these variables when you run terraform plan or terraform apply, so you don't have to pass credentials as command-line arguments.
Find your group and destination
A group is the top-level container in Fivetran. Every connection belongs to a group with a configured destination.
The example in this guide creates a group and destination. To use an existing group instead, obtain its group_id from the Fivetran REST API or from the Fivetran dashboard URL shown while viewing the destination.
To bring an existing destination under Terraform management, use terraform import.
Create a connection
fivetran_connection_v2 always creates a connection in a paused state. To start syncing, you need to create a linked fivetran_connection_v2_pause_state resource with paused = false.
The following example creates a group, a BigQuery destination, and a PostgreSQL connection:
variable "bq_project_id" {
type = string
}
variable "pg_host" {
type = string
}
variable "pg_user" {
type = string
}
variable "pg_password" {
type = string
sensitive = true
}
variable "pg_database" {
type = string
}
resource "fivetran_group" "my_group" {
name = "production"
}
resource "fivetran_destination" "my_destination" {
group_id = fivetran_group.my_group.id
service = "big_query"
time_zone_offset = "0"
run_setup_tests = true
config {
project_id = var.bq_project_id
data_set_location = "US"
}
}
resource "fivetran_connection_v2" "my_connection" {
group_id = fivetran_group.my_group.id
service = "postgres"
config = {
host = var.pg_host
port = 5432
database = var.pg_database
user = var.pg_user
password = var.pg_password
auth_method = "PASSWORD"
schema_prefix = "postgres"
update_method = "QUERY_BASED"
}
destination_schema_names = "FIVETRAN_NAMING"
sync_frequency = 360
pause_after_trial = true
run_setup_tests = true
depends_on = [fivetran_destination.my_destination]
}
resource "fivetran_connection_v2_pause_state" "my_connection" {
connection_id = fivetran_connection_v2.my_connection.id
paused = false
}
The config and auth attributes are dynamic, service-specific objects. During planning, the provider retrieves connector metadata and validates the supplied field names, types, and applicable rules for the selected service. Place each field in the object defined by the metadata for that service. Sensitive fields are not necessarily part of auth; for PostgreSQL, user and password are config fields.
In this example, schema_prefix controls the naming of replicated PostgreSQL schemas in the destination. It does not select a source schema. QUERY_BASED provides a simpler starting point than WAL_PGOUTPUT, which requires additional logical-replication configuration.
If you are importing an existing connection, import fivetran_connection_v2 first and then import fivetran_connection_v2_pause_state. Importing the pause-state resource before the connection exists in Terraform state produces a replacement plan.
Sensitive input values can be stored in Terraform state. Protect the state backend with encryption and appropriately restricted access.
Apply the configuration:
terraform plan # Preview the changes
terraform apply # Create the resources
How to find your connection service ID
The service attribute uses an internal identifier that may differ from the connection's display name. Use the fivetran_connectors_metadata data source to list the source types available to your account:
data "fivetran_connectors_metadata" "all" {}
output "connection_services" {
value = data.fivetran_connectors_metadata.all.sources[*].id
}
To use this only for service discovery, place it in a separate temporary Terraform configuration, run terraform apply, and inspect the connection_services output. This avoids provisioning your actual infrastructure before you have confirmed the correct service identifier. You can also retrieve service identifiers from the public GET /v1/metadata/connectors REST API endpoint.