A hardened GitHub repository whose settings live in code: merge policy, security features, Actions restrictions,
rulesets, and deployment environments
(ADR-0132).
- Merging: squash only (pull request title and body become the commit), head branches deleted after merge.
- Security: secret scanning with push protection, Dependabot alerts and security updates.
- Actions: only GitHub-owned, verified-creator, and explicitly allowed actions, each pinned to a full commit SHA;
workflows get a read-only
GITHUB_TOKEN and can't approve pull requests.
- Default branch ruleset: no deletion or force push, linear history, pull requests required (with
required_approvals, stale reviews dismissed, conversations resolved), and required_status_checks passing.
- Release tags ruleset: tags matching
release_tag_pattern can't be deleted, moved, or force-pushed.
- Environments: deploy only from
main; admins can't bypass protection; reviewers must approve each deployment.
Non-secret values (role ARNs, regions) go in environment or repository variables — there are no stored secrets.
- With
deletion_protection = true the repository is archived rather than deleted on destroy, and a guard resource
makes tofu destroy fail.
Settings with no provider support — private vulnerability reporting and immutable releases — are set by hand
(see the bootstrap runbook).
module "repository" {
source = "git::https://github.com/NCodeGroup/identity-platform.git//modules/github-repository?ref=<version>"
name = "example-infra"
description = "Example infrastructure"
allowed_actions_patterns = ["opentofu/setup-opentofu@*"]
required_status_checks = ["validate"]
environments = {
lab = {
variables = { AWS_ROLE_ARN = "arn:aws:iam::123456789012:role/example-apply-lab" }
}
production = {
reviewers = ["example-owner"]
variables = { AWS_ROLE_ARN = "arn:aws:iam::123456789012:role/example-apply-production" }
}
}
}
To manage a repository that already exists, import it in the calling root:
import {
to = module.repository.github_repository.this
id = "example-infra"
}
| Name |
Version |
| terraform |
>= 1.13.0 |
| github |
>= 6.13, < 7.0 |
| Name |
Version |
| github |
>= 6.13, < 7.0 |
| terraform |
n/a |
| Name |
Description |
Type |
Default |
Required |
| description |
Repository description. |
string |
n/a |
yes |
| name |
Repository name (without the owner). |
string |
n/a |
yes |
| allowed_actions_patterns |
Third-party actions allowed in addition to GitHub-owned and verified-creator actions, for example opentofu/setup-opentofu@*. Every action must still be pinned to a full commit SHA. |
list(string) |
[] |
no |
| deletion_protection |
Archive instead of delete on destroy, and block tofu destroy of this component. |
bool |
true |
no |
| environments |
Deployment environments keyed by name. Only the default branch can deploy to them. reviewers are GitHub logins who must approve each deployment; variables are non-secret environment variables (role ARNs, regions, bucket names). |
map(object({ reviewers = optional(list(string), []) prevent_self_review = optional(bool, false) wait_timer = optional(number, 0) variables = optional(map(string), {}) })) |
{} |
no |
| homepage_url |
Website shown in the repository's About panel. |
string |
null |
no |
| release_tag_pattern |
Tags protected from deletion and from being moved. |
string |
"refs/tags/v*" |
no |
| required_approvals |
Approving reviews required before a pull request can merge into the default branch. |
number |
0 |
no |
| required_status_checks |
Status check contexts that must pass before a pull request can merge into the default branch. |
list(string) |
[] |
no |
| topics |
Repository topics. |
list(string) |
[] |
no |
| variables |
Non-secret repository-level Actions variables (for example the read-only plan role ARN). |
map(string) |
{} |
no |
| visibility |
Repository visibility. |
string |
"public" |
no |
| Name |
Description |
| environments |
Names of the deployment environments. |
| full_name |
Repository as owner/name. |
| repository_id |
GitHub's numeric repository ID; unlike the name, it never changes or gets reused. |