# Terraboard: a web dashboard for inspecting and comparing Terraform state versions

> Terraboard is a Go and Vue.js web application that reads Terraform state files from S3, GCS, Terraform Cloud or GitLab and presents them through a searchable, diff-capable dashboard. A PostgreSQL database is always required, and multi-backend configuration demands a YAML file rather than environment variables.

**camptocamp/terraboard** — :earth_africa: :clipboard:  A web dashboard to inspect Terraform States 

- Repository: https://github.com/camptocamp/terraboard
- Website: https://terraboard.io
- Stars: 2,010 · Forks: 169
- Language: Go
- License: Apache-2.0
- Published: 2026-10-11 · Updated: 2026-10-11 · Language: en
- Canonical page: https://hysenlabs.com/projects/camptocamp-terraboard

## Browsing Terraform state files without write access to the backend

Terraboard reads Terraform state files from remote backends and presents them as a browsable, searchable interface. Its purpose is inspection: viewing what a state contains at a specific version, finding resources by type or attribute, and comparing two versions to see what changed. It does not execute Terraform operations, apply changes or modify state files in any way.

Engineers managing infrastructure across many workspaces run into two practical problems: state files are JSON stored in object storage with no built-in web interface, and the Terraform CLI gives no way to browse historical versions visually. Terraboard handles both by pulling state versions from a configured backend, importing them into a local PostgreSQL database, and serving four views through a web UI on port 8080. It has no mechanism for running Terraform or modifying state: the project is a read-only viewer. What you see in the dashboard reflects what is in the state files, and nothing you do in the UI changes the backend.

Camptocamp, a Swiss open source integrator, publishes the project under Apache-2.0. Written in Go for the server process and Vue.js for the front end, the build chain requires both Go 1.21 and Node.js with Yarn, as shown by the Dockerfile's two-stage build using golang:1.21 and node:lts.

## Four views: overview by modification date, resource search, state detail, and diff

Four views are documented. The overview lists all state files ordered by most recent modification date. A state view shows the details of a selected version, including resource types, names and attribute values. A search interface queries resources across all imported states by type, name or attribute. A diff view, reached from the state view, compares the current version against any earlier version that Terraboard has stored.

Diff between state versions is what plain object storage browsing does not offer on its own. Tracking which resources changed between plan runs, or which attributes shifted during a refactor, otherwise requires storing state versions separately or writing custom comparison scripts. Terraboard stores those historical versions in PostgreSQL and makes them available through the compare view, which is accessible from the state view for any imported state file.

Screenshots of all four views are in the screenshots/ directory of the repository. No live demo URL is documented in the README.

## PostgreSQL as the required internal store, built from state files on demand

Every Terraboard deployment needs a PostgreSQL database, regardless of which backend holds the state files. Terraboard imports state data from the remote backend into PostgreSQL and serves all four views from that local copy. Losing the database does not lose the canonical data, because the README states that the dataset can be rebuilt from the state files at any time. What it does lose is the history of queries and the performance benefit of having data local.

In the docker-compose.yml at the repository root, the db service uses the postgres:9.5 image with POSTGRES_USER set to gorm, POSTGRES_PASSWORD to mypassword, and POSTGRES_DB to gorm. A named volume tb-data persists the data between container restarts, and a healthcheck runs pg_isready -U gorm at ten-second intervals with a five-second timeout and five retries before the terraboard service starts. Those database credentials are development defaults and would need to be replaced in any deployment that is not purely local.

## Starting with Docker Compose: two services, credentials via environment variables

The docker-compose.yml at the repository root defines both services and passes S3 credentials through environment variables. Before running it, the shell environment needs AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION, AWS_BUCKET and AWS_DYNAMODB_TABLE set. Terraboard reads those values through the AWS_REGION, AWS_BUCKET and AWS_DYNAMODB_TABLE keys it expects inside the container.

The compose file binds two ports on the terraboard service:

```yaml
ports:
  - "8080:8080"
  - "8081:8081"
```

Port 8080 is where the web UI is served. The README does not explain what 8081 carries, but the compose file maps it. Once both services are running, the UI is reachable at the address of the host machine on port 8080.

For a source build, the Makefile provides a go install target:

```bash
go install .
```

The Dockerfile shows that the production binary is built with CGO_ENABLED=1 and GOOS=linux using a two-stage process: a Go builder stage on golang:1.21 and a node-builder stage on node:lts that runs yarn install and yarn run build for the Vue.js front end. The final image uses FROM scratch.

## Multi-backend configuration requires a YAML file, not environment variables

Terraboard supports three configuration methods: environment variables, CLI parameters, and a YAML configuration file. However, only the YAML method works when configuring more than one backend or bucket. Environment variables and CLI parameters are documented as only usable for single-provider configuration.

An example YAML file is in the root directory (example.yml) and the test/ subdirectory. The YAML configuration is also able to load values from environment variables, which allows secrets to stay in environment variables while the structural configuration stays in the file. The README specifically notes that all flags and environment variables related to provider settings are incompatible with multi-provider configuration, and that the YAML file is required to configure multiple buckets or providers.

That constraint catches engineers off guard when starting with a single AWS S3 bucket: an environment-variable-only setup works fine until a second bucket or provider is needed, at which point a YAML config file becomes mandatory regardless of how the first setup was done.

## AWS S3 requires versioning enabled, .tfstate suffix, and four IAM permissions

When using AWS S3 as the state backend, the requirements are specific. S3 bucket versioning must be enabled, and state files must use the .tfstate suffix. Four IAM permissions are required on the AWS credentials: s3:GetObject, s3:ListBucket, s3:ListBucketVersions, and s3:GetObjectVersion. Terraboard uses all four to list buckets, retrieve state files and read specific historical versions.

Lock state retrieval from DynamoDB is optional. When configured, the credentials additionally need dynamodb:Scan access to the relevant DynamoDB table, which is the backend Terraform uses to prevent concurrent applies. Omitting this permission means Terraboard can still show state versions but cannot display lock state information.

For Terraform Cloud, the requirements differ: an account on app.terraform.io, an existing organization, and a token scoped to that organization. Google Cloud Storage is also supported as a state backend, as is GitLab's managed Terraform state. The S3-compatible backend section in the README covers MinIO as a concrete example of a non-AWS S3-compatible provider, which extends Terraboard's reach to self-hosted object storage setups.

## Docker registry moved to GHCR; last release v2.4.0 published on 2024-07-24

Terraboard's Docker registry was migrated from Dockerhub to the GitHub Container Registry (GHCR). New image tags are published at the GHCR location at github.com/camptocamp/terraboard/pkgs/container/terraboard. Old tags remain on the Dockerhub repository for backward compatibility, but new releases do not go there. Anyone whose deployment pulls by tag rather than by digest will need to update the image reference to the GHCR location to receive future releases.

Release history shows three tagged versions: v2.4.0 on 2024-07-24, v2.3.0 on 2023-10-26, and v2.2.0 on 2022-05-25. That is a span of roughly two years between v2.2.0 and v2.4.0, with no minor patch releases in between. The last push to the repository was on 2026-06-15, and the repository is not archived. CHANGELOG.md at the repository root documents what each release changed.

Apache-2.0 is the declared license. Building from source requires Go 1.21.5, as stated in go.mod, with a toolchain directive pointing at go1.22.5. The project uses goreleaser for release builds, as shown by .goreleaser.yml in the repository root.

## Conclusion

Use Terraboard if you want a read-only web UI to browse, search and diff Terraform state versions across S3, GCS, Terraform Cloud or GitLab without writing custom tooling. Skip it if you have no PostgreSQL instance to run alongside it, or if you need state write operations rather than inspection. Before deploying, confirm that your AWS credentials carry all four listed S3 IAM permissions, that the S3 bucket has versioning enabled, and pull images from the GHCR registry rather than Dockerhub, since that is where new tags are published since the migration.

## FAQ

### What is Terraboard?

Terraboard is a web dashboard that reads Terraform state files from remote backends such as AWS S3, Google Cloud Storage, Terraform Cloud and GitLab, imports them into PostgreSQL, and presents them through a search, diff and version-history interface.

### How do I run Terraboard?

The repository provides a docker-compose.yml that starts both Terraboard and a PostgreSQL 9.5 database. Set your AWS credentials and bucket name as environment variables before running it. Port 8080 serves the web UI.

### Which Terraform state backends does Terraboard support?

Terraboard supports AWS S3 with optional DynamoDB lock tracking, S3-compatible backends such as MinIO, Google Cloud Storage, Terraform Cloud, and GitLab's managed Terraform state.

### Does Terraboard support multiple Terraform state backends at once?

Yes, but multi-backend or multi-bucket configuration requires a YAML configuration file. Environment variables and CLI parameters work only for a single-provider setup.

### Where are new Terraboard Docker images published?

New image tags are published to the GitHub Container Registry (GHCR) at github.com/camptocamp/terraboard/pkgs/container/terraboard. The README notes that the registry was migrated from Dockerhub, where old tags remain but new ones do not appear.

## Sources

- [camptocamp/terraboard on GitHub](https://github.com/camptocamp/terraboard)
- [License: Apache-2.0](https://github.com/camptocamp/terraboard/blob/master/LICENSE)
- [Project website](https://terraboard.io)
- [README](https://github.com/camptocamp/terraboard/blob/master/README.md)
- [Releases](https://github.com/camptocamp/terraboard/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/camptocamp-terraboard
