TrademarkTrademark
Features
Documentation

Integrating Terraform with Backstage

Learn how to connect Terraform workflows to Backstage so teams can provision infrastructure self-service with approved modules and policy guardrails.
Sebastian StadilMarch 6, 2026Updated March 31, 2026
Integrating Terraform with Backstage
Key takeaways
  • Integrating Terraform with Backstage lets developers provision infrastructure self-service from a familiar portal while enforcing standardized, validated templates.
  • Three integration paths exist: open-source Backstage Scaffolder with custom CI/CD, Terraform Cloud, or Terraform Cloud alternatives like Scalr.
  • The open-source route offers maximum control but high engineering effort, while Terraform Cloud simplifies operations at the cost of being Terraform-centric.
  • Scalr supports multiple IaC tools (Terraform, OpenTofu, Terragrunt), flexible state storage, and a hierarchical account/environment/workspace model, with an officially supported Backstage plugin.
  • The right choice depends on an organization's requirements, existing infrastructure, technical expertise, and budget.

This Guide is just as valid for OpenTofu as it is for Terraform! Backstage is an open-source framework for building internal developer portals. When you wire Terraform into it, developers can provision their own infrastructure from a portal they already use, and the platform team gets to standardize how that infrastructure gets built. This guide walks through the ways to connect the two and what each approach costs you in effort and flexibility.

Why Bridge Backstage and Terraform?

The point is developer self-service. With Terraform behind Backstage, a developer who needs a database or a cloud storage bucket can request it from the portal instead of filing a ticket and waiting. They don't have to know HCL or the cloud provider's API. And because every request runs through templates the platform team has already vetted, the infrastructure that comes out the other end follows the same security and governance rules every time. That combination addresses the usual complaints: provisioning is slow, tooling drifts from team to team, and nobody can find what already exists.

Integration Options

Several paths exist for this integration:

The Open-Source Route: Using Backstage's Scaffolder with custom CI/CD pipelines to run Terraform CLI commands offers maximum flexibility. This approach provides complete control but demands significant engineering effort for setup, maintenance, and security.

Terraform Cloud: HashiCorp's managed service can offload Terraform execution and state management. Backstage plugins can provide visibility and sometimes control over Terraform Cloud workspaces. This simplifies operations but introduces costs and reliance on the HashiCorp ecosystem, which is exclusively Terraform-centric.

Terraform Cloud Alternatives like Scalr: Platforms such as Scalr offer a compelling alternative for managing Terraform (and other tools like OpenTofu and Terragrunt) at scale, presenting distinct advantages in a Backstage integration.

Conceptual Code Sample (Backstage Plugin interacting with Scalr API):

See the officially supported Scalr plugin with Backstage here:

// packages/app/src/components/catalog/EntityPage.ts
 
+ import { EntityScalrEnvironmentContent } from '@scalr-io/backstage-plugin-scalr';
 
const domainPage = (
  <EntityLayout>
    <EntityLayout.Route path="/" title="Overview">
      <Grid container spacing={3} alignItems="stretch">
        {entityWarningContent}
        <Grid item md={6}>
          <EntityAboutCard variant="gridItem" />
        </Grid>
        <Grid item md={6} xs={12}>
          <EntityCatalogGraphCard variant="gridItem" height={400} />
        </Grid>
        <Grid item md={6}>
          <EntityHasSystemsCard variant="gridItem" />
        </Grid>
      </Grid>
    </EntityLayout.Route>
 
+   <EntityLayout.Route path="/scalr" title="Scalr">
+     <EntityScalrEnvironmentContent />
+   </EntityLayout.Route>
  </EntityLayout>
);

Conceptual Code Sample (Backstage Plugin interacting with TFC API):

// backstage-tfc-plugin-component.ts (Simplified)
import { tfeApiRef } from '@backstage/plugin-terraform-common';
// ...
async function provisionWithTFC(workspaceId: string, variables: Record<string, any>) {
  const tfeApi = useApi(tfeApiRef);
  try {
    // 1. Create a new run
    const run = await tfeApi.createRun({
      workspaceId,
      message: 'Run triggered from Backstage',
      // Potentially set autoApply: true if desired
    });
 
    // 2. (Optional) Upload configuration versions if not VCS-driven
    // 3. (Optional) Set variables for the run
    await tfeApi.setVariables({
        workspaceId,
        runId: run.id, // Or apply to workspace directly
        variables: Object.entries(variables).map(([key, value]) => ({
            key,
            value: String(value),
            category: 'terraform',
            sensitive: false,
        })),
    });
 
    // 4. (If not auto-apply) Apply the run after plan review
    // This might involve manual steps in TFC UI or further API calls
    console.log(`Terraform Cloud run ${run.id} created. Review and apply in TFC.`);
 
  } catch (error) {
    console.error('Error provisioning with Terraform Cloud:', error);
  }
}

Conceptual Code Sample (Backstage Scaffolder Template Action):

# scaffolder-template.yaml
# ...
steps:
  - id: trigger-terraform-pipeline
    name: Trigger Terraform CI/CD Pipeline
    action: 'http:request' # Or a custom action for your CI/CD system
    input:
      url: 'https://my-ci-cd.example.com/api/v1/trigger'
      method: 'POST'
      headers:
        Content-Type: 'application/json'
        Authorization: 'Bearer ${{ parameters.ciCdToken }}'
      body:
        repository: '${{ parameters.gitRepoUrl }}'
        branch: 'main'
        terraformAction: 'apply'
        variables:
          instance_type: '${{ parameters.instanceType }}'
          region: '${{ parameters.region }}'
# ...

In the CI/CD pipeline (e.g., Jenkins, GitLab CI, GitHub Actions):

# ci-cd-pipeline-script.sh
terraform init
terraform validate
terraform plan -out=tfplan -var="instance_type=$INSTANCE_TYPE" -var="region=$REGION"
# Potentially add an approval gate here
terraform apply -auto-approve tfplan

Considering Your Options: The Scalr Perspective

Each approach works, but the more complex your environment, the more the third option tends to pay off. Scalr lets teams keep their existing state storage instead of moving everything to a proprietary backend, which matters if you already have established practices you don't want to unwind.

Scalr also organizes accounts, environments, and workspaces in a hierarchy, with credentials and policies shared down that tree. For a large organization, that structure usually maps onto how teams are actually arranged, so governance can be set once and inherited rather than configured workspace by workspace. The more Backstage becomes the single front door to your infrastructure, the more the platform behind it has to handle that breadth without getting in the way.

Scalr also has an officially supported plugin for Backstage.

Self-service through Backstage multiplies the number of workspaces a platform team has to oversee, so that team needs a way to watch the whole fleet. Scalr gives account-wide reports across every workspace: resources, modules, providers, versions, drift, and stale workspaces. It also adds queued-run and pending-approval metrics and event streaming to Datadog, so a platform engineer can spot a stuck team and step in to raise a quota, fix a policy, or unblock a run.

Summary Comparison

Feature Open-Source (Custom CI/CD) Terraform Cloud Scalr (and similar alternatives)
Control & Flexibility Very High Medium High
Engineering Effort High Low Medium
Cost Potentially Low (infra) Per-resource (RUM) Usage-based (per run)
State Management Self-managed Managed by TFC Flexible (self or managed by Scalr)
Governance Custom implementation TFC Policies (OPA) Scalr Policies (OPA), RBAC, Hierarchy
Multi-IaC Tooling Yes (with custom work) Terraform only Yes (Terraform, OpenTofu, etc.)
Vendor Lock-in Low Medium (HashiCorp ecosystem) Low
Setup Complexity High Medium Medium
Scalability Depends on CI/CD setup High High
Community Support Large (Backstage, TF) Large (Terraform) Growing

Making the Right Choice

Which path you pick comes down to your requirements, what you already run, how much engineering time you can spend, and your budget. The open-source route gives you the most customization but asks the most of your team. Terraform Cloud is managed and easy to start with, though it stays Terraform-specific. If you care most about flexible governance in a complicated environment and want support for more than just Terraform, Scalr is worth a look. Whatever you choose, the aim is the same: developers get infrastructure quickly, and the platform team keeps it governed.

About the author
Sebastian StadilCEO at Scalr
Sebastian Stadil is the CEO of Scalr with 15+ years of DevOps experience. He started with AWS in 2004 and advised early Microsoft Azure and Google Cloud.