- Why not a personal access token
- What a GitHub App changes
- Why a pull request and not a push
- What to look at in the pull request
- Who can connect it
- Turning it off
- Frequently asked questions
Generating Terraform from a live AWS account is the easy half. The awkward half is getting it into the repository your team actually reviews, without handing a tool a personal access token that can reach every repository you can.
The answer is a GitHub App opening a pull request. This page explains why that is the right shape, and what it means for who can see what.
Why not a personal access token
A personal access token is the obvious thing to reach for and the wrong thing to use, for three reasons that all bite later rather than immediately.
It carries your whole account. A classic token scoped to repo can read and write every repository you have access to, including ones the tool has no business touching and ones belonging to other organisations. Fine-grained tokens narrow this, but the ceiling is still a person's access rather than a job's.
It is a person, not a service. Commits arrive attributed to whoever generated the token. When that person leaves and the token is revoked, the integration breaks with no obvious cause, and the audit trail says a human pushed something they have never heard of.
It does not expire usefully. A long-lived token in a database is a credential you have to rotate, store encrypted, and worry about. A GitHub App exchanges a signed assertion for an installation token that expires in an hour.
The practical test: if the integration's credential can reach a repository the integration should never touch, the credential is wrong regardless of how carefully it is stored.
What a GitHub App changes
A GitHub App is installed onto specific repositories by someone with permission to do that, and it authenticates as itself. Three consequences follow.
Access is granted per repository, by an admin, visibly. The installation screen lists exactly which repositories the App can reach, and an organisation owner can see and revoke it. Nobody has to trust that a tool will restrict itself.
Credentials are short-lived. The App holds a private key and mints installation tokens that expire in about an hour. There is no long-lived secret sitting in a database waiting to leak.
Actions are attributed to the App. A pull request opened by InfraSync says so. That matters when someone six months later asks where a branch came from.
InfraSync records an installation per organisation, so connecting is a one-time admin action rather than something every engineer repeats. The connection state, and which repositories are reachable, is visible in the workspace rather than implied.
Why a pull request and not a push
Generated Terraform is a draft. It reflects what is in the account right now, including the things that are there by accident, and it uses whatever module boundaries the generator chose rather than the ones your team would choose. Pushing that directly to a default branch would be wrong even if the code were perfect, because it skips the step where a human decides whether this is the shape they want.
So the output lands on a branch and opens a pull request. That gives you the review surface you already have: diffs, comments, required checks, CODEOWNERS, and whatever CI you run on Terraform. If your pipeline runs terraform plan on pull requests, the generated code gets planned before anyone merges it, which is the single most useful check available.
Each push is tracked as a job with its branch, its pull request number and URL, and a status of pending, success or failed. A failure is visible as a failure rather than as silence, which matters because the most common failure is a permission problem on the repository rather than anything wrong with the code.
What to look at in the pull request
Generated Terraform is worth reviewing differently from hand-written Terraform, because its characteristic problems are different.
- Hardcoded physical IDs. A generator writes what it found: subnet IDs, security group IDs, AMI IDs, all as literals. That is an accurate snapshot and it is not portable. Anything you intend to apply in a second environment needs those lifted into variables or data sources. This is the single biggest gap between generated code and code you would have written.
- Resources you did not know existed. The scan finds everything, including the test bucket from 2023. Those showing up in the diff is the point, not a defect.
- Module boundaries. The generator groups by service. Your team may group by application or environment. Reshaping is a normal part of the first review.
- The plan. A clean
terraform planagainst the existing account is the goal. A plan proposing to destroy and recreate something is telling you the generated configuration does not match reality closely enough yet.
More on the reshaping step in building Terraform modules from existing infrastructure, and on reaching a clean plan in the AWS to Terraform guide.
Who can connect it
Connecting a GitHub organisation is an administrative action with lasting effect, so it is gated on the maintainer role or above rather than available to every member. Installing the App on GitHub's side additionally requires whatever permission GitHub itself demands, which for an organisation means an owner or someone with App management delegated to them.
That is two independent approvals, on both sides, and it is deliberate. An integration that can open pull requests against your infrastructure repository should not be one person's unilateral decision.
Turning it off
Revocation belongs on GitHub's side, not ours, and that is the correct design. Removing the App's installation from your organisation immediately ends its access regardless of what any other system believes. You do not have to trust a vendor to honour a disconnect request.
Nothing already merged is affected. The generated Terraform is yours; it is ordinary code in your repository with no runtime dependency on us.
Frequently asked questions
Why use a GitHub App instead of a personal access token?
Because a token carries a person's whole access, is attributed to that person, and is long-lived. A GitHub App is installed onto specific repositories by an admin, authenticates as itself so its actions are attributed to the App, and mints installation tokens that expire in about an hour rather than sitting in a database indefinitely.
Does InfraSync push generated Terraform directly to my main branch?
No. Output lands on a branch and opens a pull request, so the generated code passes through the review surface you already have: diffs, comments, required checks, CODEOWNERS and any Terraform plan you run on pull requests. Generated code is a draft by nature and should not bypass review.
What permissions does the GitHub App need?
Access is granted per repository at installation time by someone with permission to install Apps on the organisation, and the installation screen lists exactly which repositories are included. An organisation owner can see and revoke the installation at any time from GitHub.
Who in my team can connect a GitHub organisation?
Connecting is gated on the maintainer role or above inside InfraSync, and installing the App on GitHub's side requires whatever permission GitHub demands, which for an organisation means an owner or someone with App management delegated. That is two independent approvals by design.
What should I look for when reviewing generated Terraform?
Hardcoded physical IDs are the main one. A generator writes the subnet, security group and AMI IDs it actually found, which is an accurate snapshot but not portable, so anything destined for a second environment needs them lifted into variables or data sources. Also check module boundaries against how your team groups things, and confirm terraform plan comes back clean rather than proposing to destroy and recreate.
How do I disconnect the GitHub integration?
Remove the App's installation from your GitHub organisation. That ends access immediately regardless of what any other system believes, so you are not relying on a vendor to honour a disconnect. Anything already merged is unaffected, since the generated Terraform is ordinary code in your repository.