Skip to content

portainer/terraform-provider-portainer

Repository files navigation

Terraform Logo Β Β Β  portainer-provider-terraform Β Β Β  portainer-provider-opentofu

Terraform Provider for Portainer

Contributors GitHub go.mod Go version GitHub Workflow Status GitHub release (latest by date including pre-releases)

Explore the docs Β»

Portainer Terraform Provider

A Terraform provider to manage Portainer resources via its REST API using Terraform.

It supports provisioning and configuration of Portainer users and will be extended to support other objects such as teams, stacks, endpoints, and access control.

Requirements

  • Terraform v0.13+
  • Portainer 2.x with admin API key support enabled
  • Go 1.21+ (if building from source)

Building and Installing

make build

Provider Support

Provider Provider Support Status
Terraform Done
OpenTofu Done

Example Provider Configuration

provider "portainer" {
  endpoint = "https://portainer.example.com"
  api_key  = "your-api-key"
  skip_ssl_verify  = true # optional (default value is `false`)
}

Authentication

  • Static API key

Static credentials can be provided by adding the api_key variables in-line in the Portainer provider block:

πŸ” Authentication: This provider supports only API keys via the X-API-Key header. JWT tokens curentlly are not supported in this provider.

Usage:

provider "portainer" {
  api_key  = "your-api-key"
}

Environment variables

You can provide your configuration via the environment variables representing your minio credentials:

$ export PORTAINER_ENDPOINT="https://portainer.example.com"
$ export PORTAINER_API_KEY="your-api-key"
$ export PORTAINER_SKIP_SSL_VERIFY=true

Arguments Reference

Name Type Required Description
endpoint string βœ… yes The URL of the Portainer instance. /api will be appended automatically if missing.
api_key string βœ… yes API key used to authenticate requests.
skip_ssl_verify boolean ❌ no Set to true to skip TLS certificate verification (useful for self-signed certs). Default: false

Usage

See our examples per resources in docs.

🧩 Supported Resources

Resource Documentation Example Status Terraform Import E2E Tests
portainer_user user.md example Done Yes Daily
portainer_team team.md example Done Yes Daily
portainer_team_membership team_membership.md example Done Yes Daily
portainer_environment environment.md example Done Not yet None
portainer_tag tag.md example Done Yes Daily
portainer_endpoint_group endpoint_group.md example Done Yes Daily
portainer_registry registry.md example Done Not yet Daily
portainer_backup backup.md example Done Not yet Daily
portainer_backup_s3 backup_s3.md example Done Not yet None
portainer_auth auth.md example Done Not yet Daily
portainer_edge_group edge_group.md example Done Yes None
portainer_edge_stack edge_stack.md example Done Not yet None
portainer_edge_job edge_job.md example Done Not yet None
portainer_stack stack.md example Done Not yet Daily
portainer_custom_template custom_template.md example Done Yes Daily
portainer_container_exec container_exec.md example Done Not yet Daily
portainer_docker_network docker_network.md example Done Not yet Daily
portainer_docker_image docker_image.md example Done Not yet Daily
portainer_docker_volume docker_volume.md example Done Not yet Daily
portainer_docker_secret docker_secret.md example Done Not yet Daily
portainer_docker_config docker_config.md example Done Not yet Daily
portainer_open_amt open_amt.md example Done Not yet None
portainer_settings settings.md example Done Not yet Daily
portainer_endpoint_settings endpoint_settings.md example Done Not yet Daily
portainer_portainer_endpoint_service_update endpoint_service_update.md example Done Not yet None
portainer_endpoint_snapshot endpoint_snapshot.md example Done Not yet Daily
portainer_endpoint_association endpoint_association.md example Done Not yet None
portainer_ssl ssl.md example Done Not yet Daily
portainer_webhook webhook.md example Done Not yet Daily
portainer_webhook_execute webhook_execute.md example Done Not yet None
portainer_resource_control resource_control.md example Done Not yet None
portainer_licenses licenses.md example Done Not yet None
portainer_cloud_credentials cloud_credentials.md example Done Not yet None
portainer_kubernetes_delete_object kubernetes_delete_object.md example Done Not yet None
portainer_kubernetes_helm kubernetes_helm.md example Done Not yet Daily
portainer_kubernetes_ingresscontrollers kubernetes_ingresscontrollers.md example Done Not yet Daily
portainer_kubernetes_namespace_ingresscontrollers kubernetes_namespace_ingresscontrollers.md example Done Not yet Daily
portainer_kubernetes_namespace_system kubernetes_namespace_system.md example Done Not yet Daily
portainer_kubernetes_namespace kubernetes_namespace.md example Done Not yet Daily
portainer_kubernetes_cronjob kubernetes_cronjob.md example Done Not yet Daily
portainer_kubernetes_job kubernetes_job.md example Done Not yet Daily
portainer_kubernetes_service_accounts kubernetes_service_account.md example Done Not yet Daily
portainer_kubernetes_configmaps kubernetes_configmaps.md example Done Not yet Daily
portainer_kubernetes_secret kubernetes_secret.md example Done Not yet Daily
portainer_kubernetes_service kubernetes_service.md example Done Not yet Daily
portainer_kubernetes_role kubernetes_role.md example Done Not yet Daily
portainer_kubernetes_rolebinding kubernetes_rolebinding.md example Done Not yet Daily
portainer_kubernetes_clusterrole kubernetes_clusterrole.md example Done Not yet Daily
portainer_kubernetes_clusterrolebinding kubernetes_clusterrolebinding.md example Done Not yet Daily
portainer_kubernetes_application kubernetes_application.md example Done Not yet Daily
portainer_kubernetes_ingress kubernetes_ingress.md example Done Not yet Daily
portainer_kubernetes_volume kubernetes_volume.md example Done Not yet Daily
portainer_kubernetes_storage kubernetes_storage.md example Done Not yet Daily

πŸ’‘ Missing a resource?

Is there a Portainer resource you'd like to see supported?

πŸ‘‰ Open an issue and we’ll consider it for implementation β€” or even better, submit a Pull Request to contribute directly!

πŸ“˜ See CONTRIBUTING.md for guidelines.

πŸ’¬ Community & Feedback

Have questions, suggestions or want to contribute ideas?
Join the Portainer Community Slack and hop into the #portainer-terraform channel!

Want to report issues, submit pull requests or browse the source code?
Check out the GitHub Repository for this provider.

♻️ Terraform Import Guide

You can import existing Portainer-managed resources into Terraform using the terraform import command. This is useful for adopting GitOps practices or migrating manually created resources into code.

βœ… General Syntax

terraform import <RESOURCE_TYPE>.<NAME> <ID>
  • <RESOURCE_TYPE> – the Terraform resource type, e.g., portainer_tag
  • <NAME> – the local name you've chosen in your .tf file
  • <ID> – the Portainer object ID (usually numeric)

πŸ›  Example: Import an existing tag

Let's say you already have a tag with ID 3 in Portainer. First, define it in your configuration:

resource "portainer_tag" "existing_tag" {
  name = "production"
}

Then run the import:

terraform import portainer_tag.existing_tag 3

Terraform will fetch the current state of the resource and start managing it. You can now safely plan and apply updates from Terraform.

πŸ“¦ Auto-generate Terraform configuration

After a successful import, you can automatically generate the resource definition from the Terraform state:

./generate-tf.sh

This script reads the current Terraform state and generates a file named generated.tf with the proper configuration of the imported resources. You can copy or refactor the output into your main Terraform files.

ℹ️ Note: Only resources with import support listed as βœ… in the table above can be imported.

βœ… Daily End-to-End Testing

To ensure maximum reliability and functionality of this provider, automated end-to-end tests are executed every day via GitHub Actions.

These tests run against a real Portainer instance (started using docker compose) and validate the majority of supported resources using real Terraform plans and applies.

πŸ’‘ This helps catch regressions early and ensures the provider remains fully operational and compatible with the Portainer API.

πŸ”„ Workflows

The project uses GitHub Actions to automate validation and testing of the provider.

  • Validate and lint documentation files (README.md and docs/)
  • Initialize, test and check the Portainer provider with Terraform and OpenTofu
  • Publish the new version of the Portainer Terraform provider to Terraform Registry
  • Run daily E2E Terraform tests against a live Portainer instance spun up via Docker Compose (make up) at 07:00 UTC

πŸ§ͺ Localy Testing

To test the provider locally, start the Portainer Web UI using Docker Compose:

make up

Then open http://localhost:9000 in your browser.

πŸ” Predefined Test Credentials for Login (use also E2E tests)

Thanks to the portainer_data directory included in this repository, a test user and token are preloaded when you launch the local Portainer instance:

Field Value
Username admin
Password password123456789
API Token ptr_xrP7XWqfZEOoaCJRu5c8qKaWuDtVc2Zb07Q5g22YpS8=

You can now apply your Terraform templates and observe changes live in the UI.

☸️ Testing Kubernetes Resources Locally

If you want to test Kubernetes-related resources, you can spin up a local Kubernetes cluster with k3d, deploy the Portainer Agent into it, and connect Portainer to that environment:

make install-k3d             # Install k3d CLI
make k3d-up                  # Create a local k3d cluster
make k8s-deploy-agent        # Deploy Portainer Agent into Kubernetes
make k3d-connect-portainer   # Connect Portainer container to the k3d network
make k3d-export-ip           # Export Kubernetes IP into terraform.tfvars

Then you can apply your Kubernetes environemnt from directory e2e-tests/environment run by:

cd e2e-tests/environment
terraform init
terraform apply

and than Kubernetes-related Terraform templates under e2e-tests/kubernetes* (or a similar directory):

cd e2e-tests/kubernetes*
terraform init
terraform apply

Testing a new version of the Portainer provider

After making changes to the provider source code, follow these steps: Build the provider binary:

make build

Install the binary into the local Terraform plugin directory:

make install-plugin

Update your main.tf to use the local provider source Add the following to your Terraform configuration:

terraform {
  required_providers {
    portainer = {
      source  = "localdomain/local/portainer"
    }
  }
}

Now you're ready to test your provider against the local Portainer instance.

Roadmap

See the open issues for a list of proposed features (and known issues). See CONTRIBUTING for more information.

License

This module is 100% Open Source and is distributed under the MIT License.
See the LICENSE file for more information.

Acknowledgements