Skip to main content
RapidDev - Software Development Agency
flutterflow-integrationsFlutterFlow API Call

Terraform

FlutterFlow cannot run Terraform, hold .tfstate, or execute terraform apply. The only real integration is with HCP Terraform (formerly Terraform Cloud) via its REST API at https://app.terraform.io/api/v2/. Your FlutterFlow app can read workspace status and latest run results as a mobile infra dashboard, and trigger plan/apply runs — but only through a backend proxy, since the org token can destroy real infrastructure.

What you'll learn

  • Why FlutterFlow cannot run Terraform and what it can do with HCP Terraform instead
  • How to create a FlutterFlow API Group with the correct JSON:API headers for HCP Terraform
  • How to navigate JSON:API response nesting using JSON Paths (data[].attributes, not top-level fields)
  • How to display workspace run status in a FlutterFlow ListView
  • Why triggering plan/apply runs requires a backend proxy and how to set one up with Firebase Cloud Functions
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate17 min read25 minutesDevOps & ToolsLast updated July 2026RapidDev Engineering Team
TL;DR

FlutterFlow cannot run Terraform, hold .tfstate, or execute terraform apply. The only real integration is with HCP Terraform (formerly Terraform Cloud) via its REST API at https://app.terraform.io/api/v2/. Your FlutterFlow app can read workspace status and latest run results as a mobile infra dashboard, and trigger plan/apply runs — but only through a backend proxy, since the org token can destroy real infrastructure.

Quick facts about this guide
FactValue
ToolTerraform
CategoryDevOps & Tools
MethodFlutterFlow API Call
DifficultyIntermediate
Time required25 minutes
Last updatedJuly 2026

What 'Connecting FlutterFlow to Terraform' Actually Means

Terraform is a command-line infrastructure-as-code tool — you write .tf files, run terraform plan and terraform apply on a machine that has provider credentials, and Terraform provisions cloud infrastructure. FlutterFlow is a browser-based visual app builder that compiles to a Flutter client running on a phone or browser. There is no path for FlutterFlow to run the Terraform binary, access local state files, or do anything that normally happens in a terminal.

What IS possible: FlutterFlow can talk to HCP Terraform (HashiCorp Cloud Platform Terraform, the hosted cloud service formerly known as Terraform Cloud) via its REST API. HCP Terraform runs your Terraform code on its own managed runners, stores state remotely, and exposes a JSON:API at https://app.terraform.io/api/v2/ for reading workspace details, run history, and run status. This makes it possible to build a mobile infra-runs dashboard: an engineering team can check whether their latest Terraform apply succeeded or failed, see which workspace last changed, and even trigger a new plan run — all from a phone.

HCP Terraform's free tier covers up to approximately 500 managed resources (verify current limits at developer.hashicorp.com/terraform/cloud-docs). The Standard tier is usage-based, and Plus/Enterprise plans add additional governance features. The Terraform CLI itself is free and open-source. For the API integration covered here, all you need is an HCP Terraform account with at least one workspace.

The most important technical fact about the HCP Terraform API: it follows the JSON:API specification, meaning response data lives under data.attributes (not at the top level), relationships are under data.relationships, and list results come back as a data[] array. FlutterFlow's JSON Path generator handles this correctly, but when writing paths manually you need data[0].attributes.status — not a top-level status field.

Integration method

FlutterFlow API Call

FlutterFlow integrates exclusively with HCP Terraform (the hosted cloud service, formerly Terraform Cloud) via its REST API — not with the Terraform CLI or local state files. A FlutterFlow API Group targets https://app.terraform.io/api/v2/ with a Bearer token and the JSON:API content type header, then reads workspace and run data whose fields live under JSON:API's data[].attributes nesting. Triggering a plan or apply run must go through a Firebase Cloud Function to keep the organization token off the client, since it can apply or destroy live infrastructure.

Prerequisites

  • A FlutterFlow project (any plan)
  • An HCP Terraform account with at least one organization and one workspace (app.terraform.io)
  • An HCP Terraform API token — User, Team, or Organization token (generated in HCP Terraform → User Settings → Tokens)
  • For triggering runs: a Firebase project with Cloud Functions enabled (Blaze plan required for outbound HTTP calls)
  • Your HCP Terraform organization name (visible in the HCP Terraform URL: app.terraform.io/app/{org-name}/)

Step-by-step guide

1

Set expectations — FlutterFlow reads HCP Terraform, it does not run Terraform

Before building anything, it is essential to establish what this integration can and cannot do, because the mismatch between expectation and reality is significant for a tool like Terraform. FlutterFlow is a client-side app builder. When someone searches 'FlutterFlow Terraform integration,' they might imagine FlutterFlow running terraform apply in the cloud. That is not what happens. FlutterFlow compiles to a Flutter app that runs on the user's phone — it has no ability to execute CLI commands, hold .tfstate files, or interact with Terraform providers. HCP Terraform (HashiCorp Cloud Platform Terraform), at https://app.terraform.io/, is the part of the Terraform ecosystem that HAS a REST API your FlutterFlow app can call. HCP Terraform stores your Terraform code in workspaces, runs plans and applies on managed cloud runners, stores state remotely, and exposes a well-documented API for reading and triggering those operations. The Terraform CLI binary itself has no API — it is a local command-line tool. So the integration you are building is: FlutterFlow → HCP Terraform REST API → reads workspace/run data. The app becomes a mobile status reader and optional remote trigger. Actual execution of Terraform runs happens entirely on HCP Terraform's infrastructure — your FlutterFlow app only requests and displays the results. There is an important security consideration as well. HCP Terraform's Organization-level API tokens can apply and destroy live infrastructure. These tokens must NEVER ship inside your FlutterFlow app's compiled code. Read-only User or Team tokens are safer for the dashboard path. For triggering runs, you must route the request through a Firebase Cloud Function that holds the token server-side — covered in Step 4. Decide upfront: read-only dashboard only, or read + trigger runs?

Pro tip: Use a scoped HCP Terraform Team token with read-only permissions for the dashboard steps. Generate it at HCP Terraform → Settings → Teams → select your team → Team API Token. This limits exposure: a read-only token cannot trigger destructive actions even if extracted from the app.

Expected result: You understand the boundary: FlutterFlow reads and displays HCP Terraform workspace and run data. It does not execute Terraform code. You have your HCP Terraform API token and your organization name ready.

2

Create the TerraformCloud API Group with correct JSON:API headers

In your FlutterFlow project, click API Calls in the left navigation panel. Click + Add, then select Create API Group. Name the group TerraformCloud and set the Base URL to https://app.terraform.io/api/v2 (no trailing slash). Now add two headers to the group — these will apply to every API Call inside it: 1. Authorization: Bearer {{terraformToken}} — your HCP Terraform API token. You will store the token as an App Constant in Settings & Integrations → App Settings → App Constants; name the constant TERRAFORM_TOKEN and bind the header value to it. 2. Content-Type: application/vnd.api+json — this is the JSON:API content type that HCP Terraform expects. On write operations (POST, PATCH), the HCP Terraform API requires this exact content type header rather than application/json. On GET requests it is also expected. Setting it at the group level covers all calls. Save the group. The two headers are the foundation of every HCP Terraform API call you will make. Getting the Content-Type wrong is one of the most common errors on write calls — it causes 415 Unsupported Media Type responses. Note about the token: an Organization API token gives read and write access to all resources under the organization, including the ability to trigger applies and potentially destroy infrastructure. For a read-only dashboard, use a Team token scoped to specific workspaces with read permissions, or a User token with appropriate access. Store whichever token you choose in the App Constant and never paste it directly into a header value as a hardcoded string.

terraform_api_group_config.json
1// TerraformCloud API Group configuration for FlutterFlow:
2// Base URL: https://app.terraform.io/api/v2
3// Shared headers (set at API Group level):
4
5{
6 "Authorization": "Bearer {{terraformToken}}",
7 "Content-Type": "application/vnd.api+json"
8}
9
10// App Constant setup:
11// Settings & Integrations → App Settings → App Constants
12// Name: TERRAFORM_TOKEN
13// Value: your HCP Terraform API token (team/user token, read scope)
14// Bind the header value to this constant.

Pro tip: HCP Terraform API rate limit is approximately 30 requests per second per token (verify current limits at developer.hashicorp.com/terraform/cloud-docs/api-docs). For a status dashboard with manual refresh, you are well within limits. If you add automatic polling, set a minimum 10-second interval.

Expected result: The TerraformCloud API Group is saved at https://app.terraform.io/api/v2 with both the Authorization and Content-Type headers configured. The group appears in your API Calls panel.

3

Add workspace and run API Calls with JSON:API path extraction

Inside the TerraformCloud API Group, click + Add → Create API Call. Name the first call GetWorkspaces and set the method to GET with endpoint /organizations/{{orgName}}/workspaces — replace {{orgName}} with a variable (add it in the Variables tab of the API Call, type: String). This endpoint returns a JSON:API list of all workspaces for your organization. In the Response & Test tab, enter your actual organization name in the orgName variable field and click Test API Call. You should receive a 200 response with a JSON body. Here is where JSON:API nesting matters: the workspace data is NOT at the top level. It lives under data[], and each workspace's fields are under data[].attributes. Click Generate JSON Paths — FlutterFlow will extract paths like: - $.data[0].attributes.name — workspace name - $.data[0].attributes.description — workspace description - $.data[0].attributes.terraform-version — Terraform version in use - $.data[0].id — workspace ID (needed for subsequent calls) Add a second API Call named GetWorkspaceRuns with GET /workspaces/{{workspaceId}}/runs. Add a workspaceId variable (String). Test it with one of the workspace IDs you retrieved from the first call. The runs response also follows JSON:API; JSON Path $.data[0].attributes.status gives you the latest run status (possible values: pending, plan_queued, planning, planned, applying, applied, errored, canceled, force_canceled, policy_checked, policy_override). Add a third API Call named GetRunDetails with GET /runs/{{runId}} for a single run's full details, including $.data.attributes.status, $.data.attributes.status-timestamps.applied-at, and $.data.attributes.message. Now bind the workspace list to a screen. Create a Page with a Backend Query using GetWorkspaces (bind orgName to your App Constant or a hardcoded Page Parameter). Add a ListView component and set its data source to the query result — each list item shows the workspace name and a status badge derived from the current run status.

terraform_json_paths.json
1// JSON Path reference for HCP Terraform JSON:API responses
2// API Group: TerraformCloud
3
4// GET /organizations/{{orgName}}/workspaces
5// Workspace list paths:
6// $.data[0].id — workspace ID
7// $.data[0].attributes.name — workspace name
8// $.data[0].attributes.description — description
9// $.data[0].attributes.terraform-version — TF version
10// $.data[0].attributes['resource-count'] — managed resource count
11// $.data[0].attributes['updated-at'] — last updated timestamp
12
13// GET /workspaces/{{workspaceId}}/runs
14// Run list paths:
15// $.data[0].id — run ID
16// $.data[0].attributes.status — run status string
17// $.data[0].attributes.message — commit message / trigger
18// $.data[0].attributes['created-at'] — run created timestamp
19// $.data[0].attributes['status-timestamps']['applied-at'] — apply time
20
21// GET /runs/{{runId}}
22// Single run paths:
23// $.data.id
24// $.data.attributes.status
25// $.data.attributes.message
26// $.data.attributes['has-changes'] — boolean: plan found changes

Pro tip: HCP Terraform attribute names use kebab-case with hyphens (resource-count, updated-at, status-timestamps). When FlutterFlow generates JSON Paths, it handles these correctly. If you write paths manually, wrap hyphenated keys in single quotes in the path string: $.data[0].attributes['resource-count'].

Expected result: GetWorkspaces and GetWorkspaceRuns API Calls test successfully with 200 responses. JSON Paths are generated and include the workspace names, IDs, and run status fields. A ListView on a test screen populates with your HCP Terraform workspaces.

4

(Advanced) Trigger a Terraform run via a Firebase Cloud Function proxy

If you want a 'Trigger Plan' button in your FlutterFlow app that creates a new HCP Terraform run for a workspace, you must route that request through a backend proxy. Creating a run requires a POST to /runs with an Organization or Team token that has write permissions — and that token can trigger apply operations that create, modify, or destroy real cloud infrastructure. Shipping it in client Dart would be a critical security risk. The pattern: deploy a Firebase Cloud Function that receives the workspace ID and run type from FlutterFlow, holds the HCP Terraform write token as an environment variable, and POSTs to the HCP Terraform /runs endpoint using the JSON:API format. FlutterFlow calls your Cloud Function URL instead of the Terraform API directly. In Firebase Console → Functions → create a new Node.js function. Store the HCP Terraform org token in Firebase environment config or Secret Manager (never in function source code). The function constructs a JSON:API run-creation body and POSTs it to https://app.terraform.io/api/v2/runs with the correct Content-Type: application/vnd.api+json header. Once deployed, note your Cloud Function URL. Back in FlutterFlow, create a new API Group called TerraformProxy pointing at your Cloud Function base URL, or add a single API Call to an existing group for the trigger action. Wire it to a Button widget using the Action Flow Editor: button → Actions → + Add Action → Backend Call → select the trigger API Call → pass the workspaceId as a variable → on success, show a SnackBar confirming the run was queued. Add a confirmation AlertDialog before the action fires — triggering a plan/apply on a production workspace is not reversible. Gate the button with a confirmation step: 'Are you sure you want to trigger a Terraform plan on production?' If you would rather skip building the proxy yourself, RapidDev's team handles FlutterFlow integrations like this every week — free scoping call at rapidevelopers.com/contact.

index.js
1// Firebase Cloud Function — HCP Terraform run trigger proxy (Node.js)
2const functions = require('firebase-functions');
3const fetch = require('node-fetch');
4
5exports.triggerTerraformRun = functions.https.onRequest(async (req, res) => {
6 res.set('Access-Control-Allow-Origin', '*');
7 if (req.method === 'OPTIONS') { res.status(204).send(''); return; }
8
9 const terraformToken = process.env.TERRAFORM_ORG_TOKEN;
10 const { workspaceId, message } = req.body;
11
12 if (!workspaceId) {
13 return res.status(400).json({ error: 'workspaceId is required' });
14 }
15
16 const runPayload = {
17 data: {
18 type: 'runs',
19 attributes: {
20 message: message || 'Triggered from FlutterFlow app',
21 'plan-only': true // set to false to allow apply after plan
22 },
23 relationships: {
24 workspace: {
25 data: { type: 'workspaces', id: workspaceId }
26 }
27 }
28 }
29 };
30
31 const response = await fetch('https://app.terraform.io/api/v2/runs', {
32 method: 'POST',
33 headers: {
34 'Authorization': `Bearer ${terraformToken}`,
35 'Content-Type': 'application/vnd.api+json'
36 },
37 body: JSON.stringify(runPayload)
38 });
39
40 const data = await response.json();
41 res.status(response.status).json(data);
42});

Pro tip: Set plan-only: true in the run payload to create a speculative plan that shows what would change without actually applying it. This is much safer for a mobile trigger — the on-call engineer can review the plan in the HCP Terraform dashboard before approving the apply. Only set it to false if your workflow explicitly supports auto-apply.

Expected result: The Cloud Function is deployed and returns a 201 response with the new run's ID and status when called. In FlutterFlow, the Trigger Plan button fires the action, shows the confirmation dialog, calls the function, and displays a success SnackBar. The new run appears in the HCP Terraform dashboard.

Common use cases

Mobile infra-runs dashboard for an on-call engineering team

An ops team wants to monitor their HCP Terraform workspace run history from a phone during on-call rotations. A FlutterFlow screen lists all workspaces for the organization, showing the latest run status (planned, applied, errored) and when it was last updated. Tapping a workspace navigates to a run detail screen with logs URL and a link to open HCP Terraform in the browser.

FlutterFlow Prompt

Build an 'Infra Status' screen that lists all HCP Terraform workspaces for my organization, showing workspace name, latest run status (color-coded: green for applied, red for errored, yellow for planning), and the last-updated timestamp. Tapping a workspace shows the run details.

Copy this prompt to try it in FlutterFlow

Remote plan-trigger button for deployment workflows

A release manager app includes a 'Trigger Terraform Plan' button for a specific workspace. When tapped, the app sends a request to a Firebase Cloud Function that signs and posts a run creation request to HCP Terraform's /runs endpoint. The FlutterFlow screen then polls the run status every 30 seconds and shows a progress indicator until the plan completes or fails.

FlutterFlow Prompt

Add a 'Trigger Plan' button to the workspace detail screen. When tapped, call a backend function that creates a new Terraform run for this workspace. Show the run status updating in real time with a status badge and a link to view the full plan output in the HCP Terraform dashboard.

Copy this prompt to try it in FlutterFlow

Multi-workspace environment health overview

A startup managing separate staging and production Terraform workspaces wants a quick visual health check from a mobile app. The FlutterFlow app shows three cards — dev, staging, prod — each displaying the workspace's current resource count, last apply status, and whether a drift check is pending. All data is read from the HCP Terraform API with a scoped read-only token.

FlutterFlow Prompt

Create a dashboard with three cards for my dev, staging, and production Terraform workspaces. Each card shows the workspace name, current run status, resource count, and last-applied timestamp. Use color coding to highlight any workspaces in an errored or needs-attention state.

Copy this prompt to try it in FlutterFlow

Troubleshooting

JSON Path returns null or empty for all workspace fields

Cause: HCP Terraform uses JSON:API format — workspace attributes are nested under data[].attributes, not at the top level. Paths like $.name or $.status will always return null because the fields do not exist at the root.

Solution: Use JSON Path expressions that navigate the JSON:API envelope: $.data[0].attributes.name for a single item, or $.data[*].attributes.name for a list. When FlutterFlow's Generate JSON Paths tool runs on the actual API response, it produces the correct paths automatically. If you wrote paths manually, prefix them with $.data[0].attributes.

415 Unsupported Media Type on POST requests to HCP Terraform

Cause: The Content-Type header is missing or set to application/json instead of the required application/vnd.api+json. HCP Terraform's JSON:API specification requires the vnd.api+json content type on all write operations.

Solution: In your TerraformCloud API Group headers, verify that Content-Type is exactly application/vnd.api+json. If the POST is in a Cloud Function, confirm the header is included in the fetch call's headers object. Standard application/json is rejected by the HCP Terraform write endpoints.

401 Unauthorized on all HCP Terraform API calls

Cause: The API token is missing, expired, or the Authorization header value is malformed. HCP Terraform tokens do not expire by default (unless set to expire during creation), but can be revoked manually.

Solution: Verify your token is active at HCP Terraform → User Settings → Tokens (or the relevant Team/Org token page). Confirm the Authorization header value is Bearer followed by a space and the exact token string — no quotes around the token, no extra whitespace. Update the App Constant in FlutterFlow if the token was regenerated.

XMLHttpRequest error when testing HCP Terraform API calls in FlutterFlow's web builder (browser preview)

Cause: The HCP Terraform API sets CORS headers allowing only specific origins. FlutterFlow's browser preview origin may not be in the allowlist, causing browser-enforced CORS blocks. Native iOS and Android builds are not affected.

Solution: Test HCP Terraform API Calls using the Response & Test tab in the FlutterFlow API Calls panel (which makes the request server-side, bypassing browser CORS) rather than by clicking buttons in the visual Run mode preview. On a published native mobile build, the CORS restriction does not apply.

Best practices

  • Never embed an HCP Terraform Organization or Team write token in client Dart or FlutterFlow App Constants — use a read-only Team token for the dashboard and route run triggers through a Firebase Cloud Function.
  • Always verify JSON Path expressions against the actual JSON:API response structure — HCP Terraform fields live under data.attributes, not at the root level.
  • Use plan-only: true when triggering runs from a mobile app — this creates a speculative plan the team can review before applying, preventing accidental infrastructure changes.
  • Add a confirmation dialog before any run-trigger action in your FlutterFlow app — applying Terraform changes to production infrastructure is not easily reversible.
  • Set a sensible polling interval if you show live run status updates — 10 to 30 seconds is appropriate to stay well within HCP Terraform's rate limits.
  • Store your HCP Terraform organization name in a FlutterFlow App Constant alongside the token, so it is easy to update if you rename the organization or switch accounts.
  • Scope the HCP Terraform token to specific workspaces using Team tokens rather than using a full Organization token — this limits the blast radius if the token is ever extracted from the app binary.
  • Always read JSON:API hyphenated attribute names (resource-count, updated-at) with single-quote bracket notation in manually written JSON Paths to avoid parsing errors.

Alternatives

Frequently asked questions

Can FlutterFlow run terraform apply?

No. Terraform is a CLI tool that runs on a machine with provider credentials and a local or remote state backend. FlutterFlow compiles to a Flutter client app running on the user's phone — it cannot execute CLI commands. The only integration available is with HCP Terraform's REST API to read workspace status and trigger runs on HCP's own managed runners.

What is the difference between Terraform CLI and HCP Terraform, and which one does FlutterFlow talk to?

The Terraform CLI (terraform plan, terraform apply) is a local executable that runs on a developer's machine or CI server — it has no REST API. HCP Terraform (app.terraform.io) is HashiCorp's hosted service that stores workspaces, runs Terraform on managed cloud runners, and provides a REST API. FlutterFlow can only talk to HCP Terraform, not to the CLI.

Why do my JSON Paths return null even though I can see the data in the API response?

HCP Terraform uses JSON:API format, where response data lives under a data key and actual field values live under data.attributes (not at the top level). A path like $.name or $.status will always return null. The correct paths are $.data[0].attributes.name and $.data[0].attributes.status. Using FlutterFlow's Generate JSON Paths button on the actual response body will produce the correct paths automatically.

Is it safe to store the HCP Terraform token in a FlutterFlow App Constant?

For a read-only Team token used in an internal engineering tool on controlled devices, it is an acceptable risk. For any public-facing app or a token with write permissions (the kind that can trigger applies or destroy infrastructure), you must route the API calls through a Firebase Cloud Function that holds the token as a server-side environment variable. A compiled Flutter APK can be decompiled and constants extracted.

Can I use this to monitor self-hosted Terraform Enterprise instead of HCP Terraform?

Yes, with a URL change. Terraform Enterprise exposes the same REST API as HCP Terraform, but hosted on your own servers. Replace the base URL in your API Group from https://app.terraform.io/api/v2 to https://your-terraform-enterprise-host/api/v2. The authentication headers, JSON:API format, and endpoint paths are the same. Note that self-hosted Terraform Enterprise may be behind a VPN, so your FlutterFlow web build may not reach it — mobile builds on the corporate network will.

What HCP Terraform plan do I need to use the API?

The HCP Terraform Free tier includes REST API access and covers up to approximately 500 managed resources (verify current limits at developer.hashicorp.com/terraform/cloud-docs). The Standard and Plus tiers add team management, audit logging, and policy controls. For the dashboard and run-trigger integration described in this guide, the Free tier is sufficient to get started.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire FlutterFlow integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.