Skip to main content
Version: 0.6.0

Getting Started


Project Overview

The TFGQL project provides a flexible GraphQL API for interacting with Terraform Cloud and Terraform Enterprise resources, including organizations, teams, workspaces, runs, and more. It wraps the underlying REST API, exposing a strongly typed schema with advanced filtering, rate-limit handling, and streaming pagination under the hood.

tip

Curious how this compares to a shell script that calls the REST API? Check out the comparison page


No Frills Starter

brew tap jeremymefford/tfgql
brew install tfgql
export TFGQL_JWT_ENCRYPTION_KEY=$(openssl rand -base64 32)
tfgql
tip

The TFGQL_JWT_ENCRYPTION_KEY variable is not strictly required, but highly recommended otherwise you'll need to mint a new JWT every time you restart tfgql

The service listens on http://127.0.0.1:4000 by default. Set the environment variables in the previous section before launching (TFGQL_JWT_ENCRYPTION_KEY, TFE_BASE_URL, etc.).

For Linux hosts download the matching binary from the GitHub release page, unpack it and run it directly. Windows users should deploy via the Docker container (no native Windows binary is currently published).


Exploring the API

Open GraphiQL at:

http://127.0.0.1:4000/

Check out the use cases

info

Read this to learn how to set up authentication for requests in GraphiQL.

Exchange a TFC Token for a JWT

Every GraphQL request must include a JWT issued by the server. Exchange your Terraform API token by calling the auth endpoint:

curl -X POST http://<endpoint>/auth/token \
-H 'content-type: application/json' \
-d '{"tfcToken":"<your terraform api token>"}'

The response contains an encrypted token and expiration timestamp:

{ "token": "<jwe>", "expiresAt": "2025-02-07T18:21:34.000Z" }

Include the token in the Authorization header for all GraphQL calls:

curl http://<endpoint>/ \
-H 'content-type: application/json' \
-H 'authorization: Bearer <jwe>' \
--data '{"query":"{ __typename }"}'

GraphiQL authentication setup

Step 1

Open http://127.0.0.1:4000/ in your browser. The GraphiQL auth prompt appears automatically.

Step 2

Paste your Terraform Cloud / Terraform Enterprise token and click Authenticate.

Step 3

GraphiQL exchanges that token at POST /auth/token, then stores the encrypted JWT and expiry in browser session storage for subsequent requests.

tip

Something not working with your auth? Click Logout in the GraphiQL token bar, then authenticate again.

Step 4

Run queries directly. GraphiQL automatically attaches Authorization: Bearer <encrypted-jwt> to GraphQL requests while you are authenticated.


Basic Queries

See use cases for more real-world queries

  query {
organizations {
id
name
}
}

Filtering Data

Use the filter argument to narrow results. For example, fetch teams named like "ci_%":

query {
teams(filter: { name: { _ilike: "ci_%" } }) {
id
name
organization { id }
}
}

See the Concepts page for filter operators.


Nested Queries

GraphQL supports nested relationships in a single request:

query {
organizations {
name
teams(filter: { name: { _ilike: "%dev%" } }) {
name
users(filter: { username: { _eq: "alice" } }) {
id
username
}
}
}
}
info

Each nested resolution is only aware of the parent context. Therefore it is not possible to do where style filters like "fetch all the teams that have a user named like X".

If you filter on a nested relationship, it will filter only at the nested level. Extending the previous example, if you fetched all teams with a user filter on the users, the result will be ALL teams and only filtering the users. It will not be only teams that meet the user criteria.

There are a couple custom queries that allow passing filters for different levels of resolution, but those are bespoke and cannot be broadly applied. See this ADR if you want more info.

Resources