> For the complete documentation index, see [llms.txt](https://docs.espresso.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.espresso.ai/snowflake-optimizer/terraform-provider.md).

# Terraform provider

## Authentication

In the Espresso dashboard, select an existing account, open **Tools → API Keys**, choose **Generate API key → Organization key**, and copy the complete `ok_` secret. It cannot be displayed again. Set it as `ESPRESSO_API_KEY`.

## Snowflake credentials

```hcl
resource "espresso_account" "production" {
  slug         = "acme_snowflake_production"
  display_name = "Acme Snowflake Production"
  product      = "snowflake"
}

data "espresso_snowflake_public_key" "production" {
  account = espresso_account.production.slug
}

resource "snowflake_service_user" "espresso" {
  name              = "ESPRESSO_AI_USER"
  default_role      = "ESPRESSO_AI_ROLE"
  default_warehouse = "ESPRESSO_AI_WH"
  rsa_public_key    = data.espresso_snowflake_public_key.production.public_key
}

resource "espresso_snowflake_credentials" "production" {
  account           = espresso_account.production.slug
  snowflake_account = "acme-org-acme-production"
  host              = "acme-org-acme-production.snowflakecomputing.com"
  username           = snowflake_service_user.espresso.name
  role               = "ESPRESSO_AI_ROLE"
  warehouse          = "ESPRESSO_AI_WH"
}
```

`espresso_snowflake_public_key` only reads the public half of an existing Espresso keypair. Configure the keypair through Espresso onboarding before reading it, then assign the value to the Snowflake service user before creating `espresso_snowflake_credentials`. The credentials resource always uses the stored keypair and tests the Snowflake connection before saving the remaining connection settings. Omit `host` to derive it from `snowflake_account`.

An account's `display_name` can be updated in place. Its `slug` and `product` are immutable. Removing an account or credentials resource from Terraform stops managing it but does not delete the account or stored credentials from Espresso.

## Warehouse Agent settings

```hcl
resource "espresso_snowflake_warehouse_agent" "production" {
  account     = espresso_account.production.slug
  enabled     = true
  auto_opt_in = true
  notes       = "Managed by Terraform"
}

locals {
  transforming = {
    min_clusters   = 1
    max_clusters   = 4
    scaling_policy = "STANDARD"
  }
}

resource "snowflake_warehouse" "transforming" {
  name              = "TRANSFORMING"
  min_cluster_count = local.transforming.min_clusters
  max_cluster_count = local.transforming.max_clusters
  scaling_policy    = local.transforming.scaling_policy

  lifecycle {
    ignore_changes = [min_cluster_count, max_cluster_count, scaling_policy]
  }
}

resource "espresso_snowflake_warehouse_agent_warehouse" "transforming" {
  account        = espresso_account.production.slug
  name           = snowflake_warehouse.transforming.name
  enabled        = true
  min_clusters   = local.transforming.min_clusters
  max_clusters   = local.transforming.max_clusters
  scaling_policy = local.transforming.scaling_policy
}
```

The lifecycle list prevents the Snowflake and Espresso providers from fighting over Warehouse Agent settings. Terraform lifecycle values cannot be conditional. To return control safely, first set the Espresso warehouse's `enabled` to `false` and apply, then remove its `ignore_changes` entries and apply again. The Snowflake provider then reconciles the warehouse to the configured values.

Each Warehouse Agent warehouse configuration is managed as a discrete resource. Its settings fields are optional, so an `account` and `name` can adopt the current values without changing them. Removing a Warehouse Agent resource stops Terraform management without changing the current Espresso settings or the underlying warehouse.
