
The StackGuardian Terraform Provider allows Terraform to programmatically interact with the StackGuardian API to help you manage resources on the StackGuardian platform, ultimately enabling organizations to manage cloud infrastructure in a cost-efficient, secure, and compliant way.
It covers 15 resources and 17 data sources — workflows, workflow groups, stacks, templates and their revisions, connectors, policies, roles, role assignments and runner groups.
[!TIP]
Looking for ready-to-use examples? All StackGuardian Terraform modules and examples are maintained in the terraform-stackguardian-modules repository.
Quick start
The provider is published on the Terraform Registry:
terraform {
required_providers {
stackguardian = {
source = "StackGuardian/stackguardian"
version = "~> 1.12"
}
}
}
provider "stackguardian" {
api_key = "<YOUR-API-KEY>" # or env var STACKGUARDIAN_API_KEY
org_name = "<YOUR-ORG-NAME>" # or env var STACKGUARDIAN_ORG_NAME
api_uri = "https://api.app.stackguardian.io" # or env var STACKGUARDIAN_API_URI; use "https://api.us.stackguardian.io" for the US region
}
resource "stackguardian_workflow_group" "example" {
resource_name = "Simple-Workflow-Group"
description = "Example of how to create a workflow group using the StackGuardian Terraform Provider"
tags = ["tf-provider-example", "example"]
}
Documentation
Reference for every resource and data source is on the
Terraform Registry,
alongside eleven guides:
Examples
Development
Prerequisites
- Go >= 1.26.7 (see go.mod)
- Terraform — CI tests against 1.14.0; the
acceptance suite skips versions below 1.1.0, and the
import {} block examples need 1.5.0 or newer
tfplugindocs for documentation work, via make tools-install
act to run the GitHub workflows locally (optional)
Common tasks
| Command |
What it does |
make build |
Compile the provider binary |
make install |
Build and install into ~/.terraform.d/plugins for local use |
make test |
Unit tests |
make test-acc |
Acceptance tests against a real organization |
make docs-generate |
Regenerate docs/ from the schemas and templates |
make docs-validate |
Structure and frontmatter checks |
make docs-check |
Fail if docs/ is out of date — the CI gate |
make docs-validate-examples |
Type-check every documentation example |
Documentation workflow
docs/ is generated — never edit it by hand. Content lives in two places:
- Attribute text comes from
MarkdownDescription in each schema.go, mostly via shared
constants in internal/constants/. A data source should reuse the same
constant as its resource twin so the two cannot drift.
- Page prose lives in
docs-templates/, and embedded .tf snippets in
docs-examples/.
Edit those, then:
make docs-generate # rebuild docs/
make docs-validate # structure and frontmatter
make docs-validate-examples # type-check every example
make docs-check # fail if docs/ is stale
docs-validate-examples needs no credentials and makes no API calls. It builds the provider, serves
it from a local filesystem mirror, and runs terraform validate over every example — the standalone
files under docs-examples/ and docs-guides-assets/, plus every ```terraform block embedded
in page and guide prose. Prose blocks are not uniform, so
scripts/extract-doc-blocks.py classifies each one and checks it
the way it can actually be checked: self-contained snippets are validated, import {} blocks have
their target verified against the schema, and bare attribute fragments have their names looked up.
That catches unknown resource types, renamed attributes, bad references and type errors before a
reader copies them.
Testing
Unit tests need nothing:
make test
Acceptance tests create and destroy real resources, so they need an organization:
export TF_ACC=1
export STACKGUARDIAN_API_KEY=<key>
export STACKGUARDIAN_API_URI=<uri>
export STACKGUARDIAN_ORG_NAME=<org>
make test-acc # everything
make test-acc TEST=./internal/resource/workflow_git/ # one package
make test-acc TESTARGS='-run TestAccWorkflowGit_WithVcsConfig' # one test
Every identifier the suite creates is generated per run and prefixed tfacc-, via
acctest.ResourceName. Static names made the suite order-dependent: a run that failed before its
destroy step left the name taken, and every later run failed at create with 409 already exists.
The shared prefix is what makes a leak identifiable afterwards.
When a run is interrupted between create and destroy, its resources survive. Sweep them:
make test-acc-sweep # report what carries the prefix; deletes nothing
make test-acc-sweep-apply # delete it
The sweep only ever touches names carrying the tfacc- prefix, and reports rather than deletes
unless you ask it to.
Running the workflows locally
The GitHub workflows can be run on your machine with act, which
avoids pushing a branch to see a CI result:
make gh-workflow-test-provider # the provider test workflow
make gh-workflow-test-api-stg # API tests against staging
make gh-workflow-test-api-prd # API tests against production
Release notes for each version are in the CHANGELOG and on the
GitHub releases page.
The minimum supported Terraform version is 1.5.7. The supported range is
defined in internal/constants/terraform_version.go:
MinTerraformVersion — the support floor, 1.5.7.
MaxTerraformVersion — the newest release CI exercises. Not a ceiling on
support; the provider imposes none.
SupportedTerraformVersions — the CI matrix: the floor, the newest tested
release, and the latest patch of every minor series in between.
Four layers keep that promise honest:
| Layer |
What it does |
Where |
| Runtime check |
The provider refuses to configure on a CLI below the floor, with a message saying so |
internal/provider/version_check.go |
| Acceptance tests |
Every test case fails — rather than silently skips — below the floor |
acctest.VersionChecks() |
| Compatibility gate |
Every pull request to main makes each Terraform version in the matrix load the provider, decode its full schema, and validate every example under docs-examples/. No credentials required. |
.github/workflows/compat.yaml |
| Acceptance matrix |
Every pull request to main runs the full acceptance suite against that same matrix |
.github/workflows/test.yaml |
Both workflows hardcode the matrix in their YAML.
TestTerraformMatrixMatchesWorkflows fails if either drifts from
SupportedTerraformVersions, so the Go list stays the single place to edit when
the range changes.
Raising the floor is a breaking change for users: bump the provider version
alongside it and note it in the CHANGELOG.
Continuous integration
All workflows gate on main:
feature branch ──PR──▶ main ──tag v*──▶ release
│ │
compatibility gate acceptance matrix
(no credentials) (hits the API)
A pull request to main runs the hermetic compatibility gate first, then the
expensive acceptance suite that creates real resources. Both target main
only — no develop branch is involved.
| Workflow |
Runs on |
Needs secrets |
What it does |
compat.yaml |
PR and push to main; manual |
No |
Build, go vet, unit tests, docs validation, and the Terraform compatibility matrix |
test.yaml |
PR and push to main; manual |
Yes |
Full acceptance suite across the Terraform matrix, plus docs validation |
release.yaml |
Tag v*; manual |
Yes |
Runs both of the above, then builds and signs the release |
test-api-prd.yaml |
Manual only |
Yes |
API high-load test against production, using main |
test-api-stg.yaml |
Manual only |
Yes |
API high-load test against staging, using main |
test-api.yaml |
Called by the two above |
Yes |
Shared implementation; takes gitref and testenv inputs |
community.yml |
Called by release.yaml |
Yes |
GoReleaser build and GPG signing |
No workflow is scheduled. The two API load tests in particular are triggered by
hand from the Actions tab — they used to run on a cron during a fixed window,
and now need someone to start them.
Everything that calls the API shares one StackGuardian organization, and some
tests use fixed resource names, so overlapping runs collide in ways that look
like version incompatibilities rather than the race they are. test.yaml guards
against this twice: max-parallel: 1 keeps its own matrix sequential, and a
concurrency: acceptance-tests group stops two of its runs overlapping. That
group does not cover test-api-prd.yaml or test-api-stg.yaml — check the
Actions tab before triggering a load test by hand.
Contributing
Contributions are welcome — please see CONTRIBUTING.md for guidelines and the Code of Conduct for community standards. Use GitHub issues to report bugs or request features.
License
This project is licensed under the Mozilla Public License 2.0.