Skip to main content

Overview

This example shows how to create multiple environments with different configurations using Terraform’s for_each loop.

Configuration

terraform {
  required_providers {
    qovery = {
      source  = "qovery/qovery"
      version = "~> 0.48.2"
    }
  }
}

provider "qovery" {
  token = var.qovery_api_token
}

# Look up existing resources
data "qovery_organization" "my_org" {
  name = "My Organization"
}

data "qovery_project" "my_project" {
  organization_id = data.qovery_organization.my_org.id
  name            = "My Project"
}

data "qovery_cluster" "my_cluster" {
  organization_id = data.qovery_organization.my_org.id
  name            = "production"
}

# Define environment configurations
locals {
  environments = {
    development = {
      mode     = "DEVELOPMENT"
      cpu      = 250
      memory   = 256
      replicas = 1
      branch   = "develop"
    }
    staging = {
      mode     = "STAGING"
      cpu      = 500
      memory   = 512
      replicas = 2
      branch   = "staging"
    }
    production = {
      mode     = "PRODUCTION"
      cpu      = 1000
      memory   = 1024
      replicas = 3
      branch   = "main"
    }
  }
}

# Create multiple environments
resource "qovery_environment" "envs" {
  for_each = local.environments

  project_id = data.qovery_project.my_project.id
  cluster_id = data.qovery_cluster.my_cluster.id
  name       = each.key
  mode       = each.value.mode
}

# Deploy application to each environment
resource "qovery_application" "app" {
  for_each = local.environments

  environment_id = qovery_environment.envs[each.key].id
  name           = "my-app"

  git_repository = {
    url    = "https://github.com/your-org/app"
    branch = each.value.branch
  }

  build_mode      = "DOCKER"
  dockerfile_path = "Dockerfile"

  cpu    = each.value.cpu
  memory = each.value.memory

  min_running_instances = each.value.replicas
  max_running_instances = each.value.replicas

  ports = [{
    internal_port       = 8080
    external_port       = 443
    protocol            = "HTTP"
    publicly_accessible = true
  }]

  # Auto-deploy for non-production environments
  auto_deploy = each.key != "production"
}

# Deploy database for each environment
resource "qovery_database" "db" {
  for_each = local.environments

  environment_id = qovery_environment.envs[each.key].id
  name           = "database"
  type           = "POSTGRESQL"
  version        = "15"
  mode           = "MANAGED"

  # Smaller databases for dev/staging
  storage = each.key == "production" ? 50 : 10

  accessibility = "PRIVATE"
}

Variables

variable "qovery_api_token" {
  description = "Qovery API token"
  type        = string
  sensitive   = true
}

Outputs

output "environment_ids" {
  value = {
    for env_name, env in qovery_environment.envs : env_name => env.id
  }
  description = "Map of environment names to IDs"
}

output "application_urls" {
  value = {
    for env_name, app in qovery_application.app : env_name => app.external_host
  }
  description = "Map of environment names to application URLs"
}

output "database_hosts" {
  value = {
    for env_name, db in qovery_database.db : env_name => db.internal_host
  }
  description = "Map of environment names to database hosts"
  sensitive   = true
}

Deployment

# Initialize
terraform init

# Set API token
export TF_VAR_qovery_api_token="your-api-token"

# Deploy all environments
terraform apply

# View outputs
terraform output

Features

Each environment has tailored resource allocations:
  • Development: Minimal resources (250 CPU, 256 MB RAM, 1 replica)
  • Staging: Medium resources (500 CPU, 512 MB RAM, 2 replicas)
  • Production: Full resources (1000 CPU, 1024 MB RAM, 3 replicas)
Environments deploy from different Git branches:
  • Development → develop branch
  • Staging → staging branch
  • Production → main branch
  • Development and Staging: Auto-deploy enabled
  • Production: Manual deployments only
  • Development & Staging: 10 GB storage
  • Production: 50 GB storage

Selective Deployment

Deploy to specific environments:
# Deploy only to development
terraform apply -target=qovery_environment.envs[\"development\"] -target=qovery_application.app[\"development\"]

# Deploy only to production
terraform apply -target=qovery_environment.envs[\"production\"] -target=qovery_application.app[\"production\"]

Alternative: Using Workspaces

You can also use Terraform workspaces for environment separation:
locals {
  environment = terraform.workspace

  config = {
    dev = {
      mode   = "DEVELOPMENT"
      cpu    = 250
      memory = 256
    }
    staging = {
      mode   = "STAGING"
      cpu    = 500
      memory = 512
    }
    production = {
      mode   = "PRODUCTION"
      cpu    = 1000
      memory = 1024
    }
  }
}

resource "qovery_environment" "env" {
  project_id = data.qovery_project.my_project.id
  cluster_id = data.qovery_cluster.my_cluster.id
  name       = local.environment
  mode       = local.config[local.environment].mode
}
# Create workspaces
terraform workspace new dev
terraform workspace new staging
terraform workspace new production

# Deploy to specific workspace
terraform workspace select dev
terraform apply

terraform workspace select production
terraform apply

Next Steps