cd /news/developer-tools/terrateam-plan-from-drift-issues · home topics developer-tools article
[ARTICLE · art-108992] src=perrotta.dev ↗ pub= topic=developer-tools verified=true sentiment=· neutral

terrateam: plan from drift issues

Terrateam, a GitHub-native infrastructure-as-code platform, now supports running `terrateam plan` from drift issues via a GitHub Actions relay that creates a temporary draft PR, enabling plan execution without pull request approval. The relay, developed by Perrotta, preserves Terrateam's locks, hooks, and credentials, and a live test returned 'Plan: 0 to add, 8 to change, 0 to destroy'. Apply remains unsupported because issues lack PR approval intent.

read2 min views3 publishedAug 24, 2026

Problem statement: Terrateam opens drift reports as GitHub issues, but terrateam plan

only works on pull requests.

The distinction is explicit in Terrateam’s issue comment handler:

{ primary = Primary.{ number = pull_request_id; pull_request = Some _; _ }; _ };

| Gw.Issue_comment_event.Issue_comment_created _ ->
    Logs.debug (fun m -> m "%s : NOOP : ISSUE_COMMENT_CREATED" request_id);
    Prmths.Counter.inc_one (Metrics.comment_events_total "noop");
    Abbs_future_combinators.return_ok ()

Calling the repository workflow directly was not an option either. Its work token comes from the Terrateam backend.

So I kept Terrateam in charge and gave it the pull request it expects. A GitHub Actions relay checks that the source is an open Terrateam drift issue and that the commenter has repository write access. It then puts a comment-only Terraform file in each selected drift directory:

markers = [
    InputGitTreeElement(
        path=f"{directory}/terrateam_issue_relay.tf",
        mode="100644",
        type="blob",
        content=f"# Terrateam plan relay for drift issue #{issue_number}, comment {comment_id}.\n",
    )
    for directory in directories
]

That path change gives Terrateam a real dirspace without changing infrastructure. The relay opens a temporary draft PR and posts the original command on it:

pull = repo.create_pull(
    base=repo.default_branch,
    head=branch,
    title=f"Terrateam plan relay for drift issue #{issue_number}",
    body=relay_body(issue_number, comment_id, event["comment"]["html_url"]),
    draft=True,
)
pull.as_issue().create_comment(command)

Terrateam uses its normal locks, hooks, credentials, and batching. Another workflow copies its comments back to the drift issue. apply

remains unsupported: an issue has no PR approval or review intent.

The live test planned the requested directory and returned the result:

## Plans :thumbsup:

## Terrateam Plan Output :thumbsup:

**Plan: 0 to add, 8 to change, 0 to destroy**

The temporary PR ended where it should:

% gh pr view 6687 --json number,state,headRefName,title
{"headRefName":"bot/terrateam-issue-relay/6663-5398113346","number":6687,"state":"CLOSED","title":"Terrateam plan relay for drift issue #6663"}
% ./ci/run_python_tests.sh ci/terrateam_issue_relay
collected 19 items
tests/test_relay.py ...................                                  [100%]
============================== 19 passed in 1.45s ==============================

A scheduled job deletes inactive relay branches after 30 hours. Terrateam still owns plan execution; the relay only translates the issue command into its existing PR protocol.

🤖 *Drafted with * ∎

/bloggify

.— § —

Reply via [email](mailto:serendipity@perrotta.dev?subject=Reply to: terrateam: plan from drift issues)

── more in #developer-tools 4 stories · sorted by recency
── more on @terrateam 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/terrateam-plan-from-…] indexed:0 read:2min 2026-08-24 ·