> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sevalla.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These are the docs for Sevalla, a platform for deploying applications, databases, static sites, object storage and load balancers. The dashboard is at https://app.sevalla.com.
> Bold text in steps is an exact dashboard label.
> To act on a Sevalla account, prefer the Sevalla MCP server (https://mcp.sevalla.com/mcp, see https://docs.sevalla.com/ai-agents/overview.md), then the Sevalla CLI (https://docs.sevalla.com/developer-tools/cli.md), then the REST API (https://api-docs.sevalla.com, OpenAPI spec at https://api.sevalla.com/v3/openapi.json).
> Every page index is at https://docs.sevalla.com/llms.txt.

# Terraform provider

> Manage Sevalla applications, databases, static sites, load balancers, buckets, pipelines and more as code with the sevalla-hosting/sevalla Terraform provider.

The Sevalla Terraform provider, [`sevalla-hosting/sevalla`](https://registry.terraform.io/providers/sevalla-hosting/sevalla/latest) on the Terraform Registry, manages Sevalla services as code through the [Sevalla API](/developer-tools/api). It has 29 resources and 20 data sources. The current version is 1.1.0, and it works with Terraform 1.0 or later.

## Before you begin

* Terraform 1.0 or later.
* An [API key](/developer-tools/api-keys#create-an-api-key) with the permissions for the resources you manage. A plan that creates applications and databases needs create, read, update and delete on them.

## Configure the provider

Add the provider to your configuration and give it the API key through the `SEVALLA_API_KEY` environment variable:

```hcl main.tf theme={null}
terraform {
  required_providers {
    sevalla = {
      source  = "sevalla-hosting/sevalla"
      version = "~> 1.1"
    }
  }
}

provider "sevalla" {}
```

```bash theme={null}
export SEVALLA_API_KEY="svl_..."
terraform init
```

| Setting | What it does |
| - | - |
| `api_key` (provider argument, sensitive) | The API key. Overrides `SEVALLA_API_KEY`. Pass it from a variable, never as a literal. |
| `SEVALLA_API_KEY` (environment variable) | The API key, when `api_key` isn't set |
| `SEVALLA_API_URL` (environment variable) | Another API base URL. Must start with `https://` (`SEVALLA_API_URL must use the https:// scheme.`). |

Without a key, `terraform plan` stops with `The Sevalla API key must be set in the provider configuration or via the SEVALLA_API_KEY environment variable.`

## Deploy an application with a database

This configuration creates the `storefront` application from a public repository in Frankfurt, a PostgreSQL database `orders-db` in the same location, an internal connection between them, a `DATABASE_URL` environment variable, and the application's first deployment.

```hcl main.tf theme={null}
variable "db_password" {
  type      = string
  sensitive = true
}

data "sevalla_clusters" "all" {}
data "sevalla_database_resource_types" "all" {}

locals {
  # eu-frankfurt-1 is Frankfurt, Germany, on OCI. Companies still on Google Cloud use europe-west3.
  frankfurt = one([for c in data.sevalla_clusters.all.clusters : c.id if c.location == "eu-frankfurt-1"])
  db1       = one([for t in data.sevalla_database_resource_types.all.database_resource_types : t.id if t.name == "db1"])
}

resource "sevalla_application" "storefront" {
  display_name   = "storefront"
  cluster_id     = local.frankfurt
  source         = "publicGit"
  repo_url       = "https://github.com/acme/storefront"
  default_branch = "main"
}

resource "sevalla_database" "orders" {
  display_name     = "orders-db"
  type             = "postgresql"
  version          = "17"
  cluster_id       = local.frankfurt
  resource_type_id = local.db1
  db_name          = "orders"
  db_user          = "storefront"
  db_password      = var.db_password
}

resource "sevalla_database_internal_connection" "orders" {
  database_id    = sevalla_database.orders.id
  application_id = sevalla_application.storefront.id
  target_type    = "app"
}

resource "sevalla_application_environment_variable" "database_url" {
  application_id = sevalla_application.storefront.id
  key            = "DATABASE_URL"
  value          = "postgres://storefront:${var.db_password}@${sevalla_database.orders.internal_hostname}:${sevalla_database.orders.internal_port}/orders"
}

resource "sevalla_application_deployment" "storefront" {
  application_id = sevalla_application.storefront.id
  is_restart     = false

  depends_on = [
    sevalla_database_internal_connection.orders,
    sevalla_application_environment_variable.database_url,
  ]
}
```

```bash theme={null}
export TF_VAR_db_password="a-long-random-password"
terraform plan
terraform apply
```

After `terraform apply`, the application appears under **Applications** with its first deployment running, and `orders-db` under **Databases**. Things to know about this configuration:

* Creating an application doesn't deploy it. `sevalla_application_deployment` triggers a deployment when it's created. Its `is_restart` defaults to `true`, which redeploys the existing build, so set it to `false` for an application that has never been built. To deploy again when something changes, put the changing values in its `triggers` map: a change there replaces the resource and starts a new deployment. Destroying it doesn't cancel or undo anything.
* `cluster_id` can't change after creation, on both the application and the database. Neither can the database's `type`, `version`, `db_name`, `db_user` or `db_password`; `resource_type_id` can, to resize the database.
* Database versions depend on the engine and the location. The [Create a database](/databases/create) form shows the versions you can use.
* The Terraform state holds the database password and environment variable values in plain text. Keep the state in an encrypted backend with restricted access.

## Resources

| Resource | Manages | Import ID |
| - | - | - |
| `sevalla_application` | An application from a Git repository or Docker image, with its build settings | `<application_id>` |
| `sevalla_application_deployment` | A deployment, triggered when the resource is created or replaced | Not importable |
| `sevalla_application_deployment_hook` | An application's deploy hook | `<application_id>` |
| `sevalla_application_domain` | A custom domain of an application | `<application_id>/<domain_id>` |
| `sevalla_application_environment_variable` | An environment variable of an application | `<application_id>/<env_var_id>` |
| `sevalla_application_ip_restriction` | An application's IP restriction rules | `<application_id>` |
| `sevalla_application_private_port` | A private port of an application | `<application_id>/<private_port_id>` |
| `sevalla_application_process` | A process (web, worker, cron or job) | `<application_id>/<process_id>` |
| `sevalla_application_tcp_proxy` | A TCP proxy of an application | `<application_id>/<tcp_proxy_id>` |
| `sevalla_database` | A PostgreSQL, MySQL, MariaDB, Redis or Valkey database | `<database_id>` |
| `sevalla_database_internal_connection` | An internal connection between a database and an application or another database | `<database_id>/<connection_id>` |
| `sevalla_database_ip_restriction` | A database's IP restriction rules | `<database_id>` |
| `sevalla_static_site` | A static site | `<static_site_id>` |
| `sevalla_static_site_domain` | A custom domain of a static site | `<static_site_id>/<domain_id>` |
| `sevalla_static_site_environment_variable` | An environment variable of a static site | `<static_site_id>/<env_var_id>` |
| `sevalla_load_balancer` | A load balancer | `<load_balancer_id>` |
| `sevalla_load_balancer_destination` | A destination of a load balancer | `<load_balancer_id>/<destination_id>` |
| `sevalla_load_balancer_domain` | A custom domain of a load balancer | `<load_balancer_id>/<domain_id>` |
| `sevalla_object_storage` | A bucket | `<object_storage_id>` |
| `sevalla_object_storage_cors_policy` | A CORS policy of a bucket | `<object_storage_id>/<cors_policy_id>` |
| `sevalla_pipeline` | A pipeline | `<pipeline_id>` |
| `sevalla_pipeline_stage` | A stage of a pipeline | `<pipeline_id>/<stage_id>` |
| `sevalla_pipeline_stage_application` | An application in a pipeline stage | `<pipeline_id>/<stage_id>/<application_id>` |
| `sevalla_project` | A project | `<project_id>` |
| `sevalla_project_service` | A service in a project | `<project_id>/<service_id>` |
| `sevalla_docker_registry` | A registry credential for private Docker images | `<docker_registry_id>` |
| `sevalla_webhook` | A [webhook](/developer-tools/webhooks) | `<webhook_id>` |
| `sevalla_api_key` | An [API key](/developer-tools/api-keys) | `<api_key_id>` |
| `sevalla_global_environment_variable` | A global environment variable for every application | `<global_env_var_id>` |

Import an existing service so Terraform manages it, for example:

```bash theme={null}
terraform import sevalla_application.storefront 7f3c2b1a-9e8d-4c7b-a6f5-4e3d2c1b0a9f
```

## Data sources

| Data source | Returns |
| - | - |
| `sevalla_application`, `sevalla_applications` | One application, or every application |
| `sevalla_database`, `sevalla_databases` | One database, or every database |
| `sevalla_static_site`, `sevalla_static_sites` | One static site, or every static site |
| `sevalla_load_balancer`, `sevalla_load_balancers` | One load balancer, or every load balancer |
| `sevalla_object_storage` | One bucket |
| `sevalla_pipeline` | One pipeline |
| `sevalla_project` | One project |
| `sevalla_docker_registry` | One registry credential |
| `sevalla_webhook` | One webhook |
| `sevalla_api_key` | One API key |
| `sevalla_clusters` | The locations (`id`, `name`, `display_name`, `location`) |
| `sevalla_process_resource_types` | The process sizes, with CPU in millicores and memory in bytes |
| `sevalla_database_resource_types` | The database sizes, with CPU, memory and storage |
| `sevalla_users` | The company's users |
| `sevalla_api_key_permissions` | The permissions an API key can have |
| `sevalla_api_key_roles` | The predefined API key roles |

Every resource's arguments and attributes are on the [Terraform Registry](https://registry.terraform.io/providers/sevalla-hosting/sevalla/latest/docs). The source and issues are on [GitHub](https://github.com/sevalla-hosting/terraform-provider-sevalla).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.