Terraform can manage Vercel resources, but its provider is surprisingly limited, focusing primarily on project and domain management, not deployment orchestration.
Let’s see it in action. Imagine you want to provision a new Vercel project and associate a custom domain with it. Here’s a main.tf snippet:
terraform {
required_providers {
vercel = {
source = "vercel/vercel"
version = "~> 0.6.0"
}
}
}
provider "vercel" {
# VERCEL_ORG_ID and VERCEL_TOKEN are typically set as environment variables
# or can be explicitly passed here.
# org_id = "your-vercel-org-id"
# token = "your-vercel-api-token"
}
resource "vercel_project" "my_app" {
name = "my-awesome-app"
framework = "nextjs"
repository_url = "https://github.com/your-username/my-awesome-app"
repository_provider = "github"
}
resource "vercel_domain" "my_app_domain" {
name = "my-awesome-app.example.com"
project_id = vercel_project.my_app.id
}
output "project_id" {
value = vercel_project.my_app.id
}
output "domain_status" {
value = vercel_domain.my_app_domain.status
}
When you run terraform apply, Terraform communicates with the Vercel API to create these resources. It will:
- Create the
vercel_project: This involves sending a request to Vercel to set up a new project, linking it to your GitHub repository, and specifying the framework. Vercel then provisions the necessary infrastructure for this project. - Create the
vercel_domain: After the project is created, Terraform requests Vercel to add your custom domain and associate it with the newly created project. Vercel will then provide DNS records that you need to configure with your domain registrar.
The core problem this solves is declarative infrastructure management for Vercel. Instead of manually clicking through the Vercel dashboard or writing custom scripts for repetitive setup tasks, you define your Vercel project and its associated domains in a version-controlled Terraform configuration. This makes it repeatable, auditable, and easier to manage across different environments.
Internally, the vercel Terraform provider acts as a client to the Vercel API. It translates your HCL (HashiCorp Configuration Language) into API calls. For vercel_project, it’s primarily creating a project resource. For vercel_domain, it’s linking a DNS name to an existing project ID. The provider abstracts away the details of authentication (using VERCEL_ORG_ID and VERCEL_TOKEN) and the specific API endpoints.
The most surprising thing is how limited the official Terraform provider is regarding actual deployments. While you can define a project and its repository, the provider does not directly trigger or manage Vercel deployments. Terraform’s role ends at provisioning the project and its domain. When you push code to your linked repository, Vercel’s CI/CD handles the build and deployment process automatically. Terraform doesn’t orchestrate these builds; it just sets up the environment for them.
This means that while Terraform is excellent for managing the infrastructure of your Vercel projects (project creation, domain mapping, environment variables), you’ll still rely on Vercel’s built-in CI/CD for the actual deployment lifecycle.
The next logical step is to manage Vercel environment variables using Terraform, which is crucial for configuring your applications across different stages.