Terraform Cloud Backend Plugin
The Terraform Cloud Backend provides an API proxy to Terraform Cloud with automatic token resolution from Vault.
Overview
| Property | Value |
|---|---|
| Package | @internal/plugin-terraform-cloud-backend |
| Type | Backend |
| Plugin ID | terraform-cloud |
| Integration | Terraform Cloud, Vault |
Architecture
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /tokens | Get TFC token for org |
| GET | /available-tokens | List available tokens |
| GET | /health | Health check |
| ALL | /proxy/* | Proxy to Terraform Cloud |
Token Resolution
Resolution Strategy
Token Lookup Paths
The backend searches for tokens in these Vault paths:
- User-specific org token:
users/{username}/tfc-{org-name} - User generic token:
users/{username}/tfc-token - Group-specific org token:
groups/{group}/tfc-{org-name} - Group generic token:
groups/{group}/tfc-token
Token Format
{
"token": "xxx.atlasv1.yyy",
"organization": "acme-corp",
"created": "2024-01-15T10:30:00Z"
}
Or multi-organization format:
{
"acme-corp": "xxx.atlasv1.yyy",
"other-org": "xxx.atlasv1.zzz"
}
API Proxy
All requests to /proxy/* are forwarded to Terraform Cloud:
Rate Limit Headers
The proxy forwards TFC rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Request limit per period |
X-RateLimit-Remaining | Remaining requests |
X-RateLimit-Reset | Reset timestamp |
User Info Extraction
User information is extracted from JWT claims:
interface UserInfo {
userId: string; // From sub claim
username: string; // Extracted from userId
groups: string[]; // From ent claims
}
JWT Claims Processing
// Extract from sub: "user:default/john.doe"
const userId = claims.sub;
const username = userId.split("/").pop(); // "john.doe"
// Extract from ent: ["group:default/platform-team"]
const groups = claims.ent
.filter((e) => e.startsWith("group:"))
.map((e) => e.split("/").pop()); // ["platform-team"]
Configuration
# app-config.yaml
terraformCloud:
apiUrl: https://app.terraform.io/api/v2
TypeScript Config Schema
// config.d.ts
export interface Config {
terraformCloud?: {
/**
* Terraform Cloud API base URL
* @default https://app.terraform.io/api/v2
*/
apiUrl?: string;
};
}
Example: Token Setup
Organization-Specific Token
Store in Vault at groups/platform-team/tfc-acme-corp:
{
"token": "xxx.atlasv1.yyy"
}
Multi-Organization Token
Store in Vault at groups/platform-team/tfc-token:
{
"acme-corp": "xxx.atlasv1.yyy",
"staging-org": "xxx.atlasv1.zzz",
"default": "xxx.atlasv1.www"
}
Error Handling
Token Not Found
{
"error": "Token not found",
"message": "No TFC token found for organization 'acme-corp'",
"checkedPaths": [
"users/john.doe/tfc-acme-corp",
"users/john.doe/tfc-token",
"groups/platform-team/tfc-acme-corp",
"groups/platform-team/tfc-token"
]
}
TFC API Error
{
"error": "TFC API Error",
"status": 403,
"message": "Forbidden - token may be expired or revoked"
}
Related Documentation
- Terraform Cloud Frontend - Frontend plugin
- Vault Secrets Backend - Token storage
- Plugins Overview