This guide walks you through deploying a Docker Compose stack to multiple Edge environments using Terraform and the Portainer Terraform provider.
If you are new to Terraform, the core idea is straightforward: you describe what you want in configuration files, and Terraform figures out how to make it happen. You declare the end state, and Terraform does the work.
Prerequisites
To get started, you'll need:
- A running Portainer instance with admin access and Edge Compute enabled
- At least one Edge Group configured in Portainer, containing your target Edge environments
- Terraform v1.0 or later installed on your local machine
- A Portainer API key
1. Set up your project
Note: The Portainer Terraform provider supports authentication using either an API key or username and password. This example uses API key authentication, which is recommended for automation.
Create a new directory for your Terraform configuration and navigate into it.
mkdir portainer-edge-stack
cd portainer-edge-stack
Create a main.tf file and add the provider configuration below. This tells Terraform where your Portainer instance is and how to authenticate with it.
# main.tf
terraform {
required_providers {
portainer = {
source = "portainer/portainer"
}
}
}
provider "portainer" {
endpoint = var.portainer_url
api_key = var.portainer_api_key
}
Create a variables.tf file to declare the variables used in your configuration:
# variables.tf
variable "portainer_url" {
description = "The URL of your Portainer instance"
type = string
}
variable "portainer_api_key" {
description = "Portainer API key for authentication"
type = string
sensitive = true
}
variable "edge_group_ids" {
description = "List of Edge Group IDs to deploy the stack to"
type = list(number)
}
Create a terraform.tfvars file to supply your Terraform configuration variables.
This file will contain a list of your Edge Group IDs. To find your Edge Group IDs, open the Portainer UI and navigate to your Edge Groups. Click on a group and note the numeric ID in the URL - it will look like /edge/groups/1.
You can target multiple Edge Groups in a single stack deployment by passing a list of IDs:
edge_group_ids = [1, 2, 3]
When Terraform runs, it will deploy the stack to all environments that belong to those groups.
# terraform.tfvars
portainer_url = "https://portainer.example.com"
portainer_api_key = "your-api-key-here"
edge_group_ids = [1] # replace with your actual Edge Group ID(s)
Now initialise Terraform. This downloads the Portainer provider plugin and prepares your working directory:
terraform init
You should see output confirming the provider has been installed successfully.
2. Define your Edge Stack
Create a file called edge_stack.tf. This is where you define the Edge Stack you want Portainer to deploy across your Edge environments.
In this example we are deploying a simple nginx web server, which is a good starting point for getting familiar with the workflow.
The deployment_type can be 0 for Compose, or 1 for Kubernetes.
The edge_groups references the edge_group_ ids set in the terraform.tfvars file.
stack_file_content uses Terraform’s heredoc syntax (<<-EOT … EOT) to write a multiline string inline. The content is a standard Docker Compose file.
# edge_stack.tf
resource "portainer_edge_stack" "first_edge_stack" {
name = "my-first-edge-stack"
deployment_type = 0
edge_groups = var.edge_group_ids
stack_file_content = <<-EOT
version: "3.8"
services:
web:
image: nginx:latest
ports:
- "8080:80"
restart: unless-stopped
EOT
}
3. Preview the changes with terraform plan
Before making any changes to Portainer, Terraform lets you preview exactly what it intends to do. Run:
terraform plan -out edge_stack.tfplan
Terraform will connect to your Portainer instance, compare the current state to what your configuration describes, and print a summary of what it plans to do.
Each line prefixed with + means that resource will be created.
Lines with ~ indicate updates.
Lines with - indicate deletions.
The -out flag saves the plan to a file. This guarantees that when you run apply, Terraform executes exactly what you reviewed and nothing more.
4. Deploy the Edge Stack with terraform apply
Once you are happy with the plan, apply it:
terraform apply edge_stack.tfplan
Terraform will carry out the actions shown in the plan and report back as each one completes.
Once finished, you will see a summary confirming how many resources were added, changed, or destroyed.
Terraform also writes a state file terraform.tfstate to your project directory. This records what has been created and is how Terraform knows what already exists the next time you run plan or apply. To update your Edge Stack later, edit edge_stack.tf and run plan and apply again. Terraform will update the Edge Stack in place rather than recreating it from scratch.
Important: The state file can contain sensitive values - do not commit it to source control.
5. Verify the Edge Stack is running and optionally remove it
Navigate to your Edge Stacks in the Portainer UI. You should see your stack listed with a per-device deployment status showing how many environments have acknowledged, pre-pulled images, or successfully deployed the stack.
If you want to remove the stack from Portainer, run:
terraform destroy
Important: Terraform destroy removes everything Terraform manages in your current configuration. Only run this when you intend to fully remove the resources.
Further examples
An extensive list of additional examples - including edge stacks, registries, S3 backups, and more - can be found in the Portainer Terraform provider GitHub repository.
Full provider documentation is available within the Terraform docs.
Try Portainer with 3 Nodes Free
If you're ready to get started with Portainer Business, 3 nodes free is a great place to begin. If you'd prefer to get in touch with us, we'd love to hear from you!

