{"id":44704442,"url":"https://github.com/zfael/github-infra","last_synced_at":"2026-02-15T10:40:18.412Z","repository":{"id":327267532,"uuid":"1108589660","full_name":"zfael/github-infra","owner":"zfael","description":null,"archived":false,"fork":false,"pushed_at":"2025-12-30T12:14:52.000Z","size":22,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-03T03:29:30.717Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zfael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-02T16:44:50.000Z","updated_at":"2025-12-30T12:14:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zfael/github-infra","commit_stats":null,"previous_names":["zfael/github-infra"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zfael/github-infra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zfael%2Fgithub-infra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zfael%2Fgithub-infra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zfael%2Fgithub-infra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zfael%2Fgithub-infra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zfael","download_url":"https://codeload.github.com/zfael/github-infra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zfael%2Fgithub-infra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29475882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T10:25:47.032Z","status":"ssl_error","status_checked_at":"2026-02-15T10:25:01.815Z","response_time":118,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-15T10:40:17.622Z","updated_at":"2026-02-15T10:40:18.403Z","avatar_url":"https://github.com/zfael.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitHub Infrastructure as Code\n\nTerraform project to provision and manage GitHub repositories for personal accounts with declarative configuration and modular design.\n\n## Features\n\n- 🏗️ **Declarative Repository Management**: Define all repository settings in a single configuration file\n- 🔒 **Branch Protection Rules**: Comprehensive branch protection with customizable security settings\n- 🧩 **Modular Design**: Reusable modules for repositories and branch protection\n- ☁️ **Terraform Cloud Integration**: Remote state management with Terraform Cloud free tier\n- 🔐 **Security First**: Built-in defaults for security best practices\n- 📝 **Fully Composable**: Each repository is independently configured\n\n## Prerequisites\n\n1. **GitHub Personal Access Token (PAT)**\n   - Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)\n   - Generate new token with the following scopes:\n     - `repo` (Full control of private repositories)\n     - `admin:repo_hook` (Full control of repository hooks)\n     - `delete_repo` (Delete repositories)\n   - Save the token securely - you'll need it for authentication\n\n2. **Terraform Cloud Account** (Free)\n   - Sign up at [app.terraform.io](https://app.terraform.io)\n   - Create an organization\n   - Update `versions.tf` with your organization name\n\n3. **Terraform CLI**\n   - Install Terraform \u003e= 1.6.0\n   - Download from [terraform.io](https://www.terraform.io/downloads)\n\n## Project Structure\n\n```\ngithub-infra/\n├── modules/\n│   ├── repository/           # Repository creation module\n│   │   ├── main.tf\n│   │   ├── variables.tf\n│   │   └── outputs.tf\n│   └── branch-protection/    # Branch protection module\n│       ├── main.tf\n│       ├── variables.tf\n│       └── outputs.tf\n├── main.tf                   # Root module orchestration\n├── variables.tf              # Root variables\n├── outputs.tf                # Root outputs\n├── providers.tf              # Provider configuration\n├── versions.tf               # Terraform and provider versions\n├── terraform.tfvars.example  # Example configuration\n├── .gitignore               # Git ignore rules\n└── README.md                # This file\n```\n\n## Setup\n\n### 1. Clone and Configure\n\n```bash\n# Clone or navigate to this repository\ncd github-infra\n\n# Copy the example configuration\ncp terraform.tfvars.example terraform.tfvars\n\n# Edit terraform.tfvars with your settings\nvim terraform.tfvars\n```\n\n### 2. Configure Terraform Cloud\n\nEdit `versions.tf` and replace `REPLACE_WITH_YOUR_ORG` with your Terraform Cloud organization name:\n\n```hcl\ncloud {\n  organization = \"your-terraform-cloud-org\"\n  \n  workspaces {\n    name = \"github-infra\"\n  }\n}\n```\n\n### 3. Set Environment Variables\n\n```bash\n# GitHub Personal Access Token\nexport GITHUB_TOKEN=\"your_github_personal_access_token\"\n\n# GitHub owner (your username) - alternative to setting in tfvars\nexport TF_VAR_github_owner=\"your-github-username\"\n```\n\n### 4. Initialize Terraform\n\n```bash\n# Initialize Terraform (will prompt for Terraform Cloud login)\nterraform init\n\n# Validate configuration\nterraform validate\n\n# Format code\nterraform fmt -recursive\n```\n\n## Usage\n\n### Define Repositories\n\nEdit `terraform.tfvars` to define your repositories:\n\n```hcl\ngithub_owner = \"your-github-username\"\n\nrepositories = {\n  \"my-project\" = {\n    description = \"My awesome project\"\n    visibility  = \"public\"\n    \n    has_issues = true\n    auto_init  = true\n    \n    gitignore_template = \"Node\"\n    license_template   = \"mit\"\n    topics             = [\"nodejs\", \"api\"]\n    \n    branch_protection = {\n      pattern                         = \"main\"\n      require_signed_commits          = true\n      require_conversation_resolution = true\n      \n      required_pull_request_reviews = {\n        required_approving_review_count = 1\n        dismiss_stale_reviews           = true\n      }\n    }\n  }\n}\n```\n\n### Apply Configuration\n\n```bash\n# Preview changes\nterraform plan\n\n# Apply changes\nterraform apply\n\n# View outputs\nterraform output\n```\n\n### Add a New Repository\n\n1. Add a new entry to the `repositories` map in `terraform.tfvars`\n2. Run `terraform plan` to preview\n3. Run `terraform apply` to create the repository\n\n### Remove a Repository\n\n1. Remove the repository entry from `terraform.tfvars`\n2. Run `terraform plan` to preview (repository will be archived by default)\n3. Run `terraform apply` to archive the repository\n\n## Configuration Reference\n\n### Repository Settings\n\n| Field | Type | Default | Description |\n|-------|------|---------|-------------|\n| `description` | string | `\"\"` | Repository description |\n| `visibility` | string | `\"private\"` | Repository visibility: `public`, `private`, or `internal` |\n| `has_issues` | bool | `true` | Enable GitHub Issues |\n| `has_discussions` | bool | `false` | Enable GitHub Discussions |\n| `has_projects` | bool | `false` | Enable GitHub Projects |\n| `has_wiki` | bool | `false` | Enable GitHub Wiki |\n| `has_downloads` | bool | `false` | Enable downloads |\n| `auto_init` | bool | `false` | Initialize with README |\n| `gitignore_template` | string | `null` | Gitignore template (e.g., `\"Node\"`, `\"Python\"`, `\"Go\"`) |\n| `license_template` | string | `null` | License template (e.g., `\"mit\"`, `\"apache-2.0\"`, `\"gpl-3.0\"`) |\n| `topics` | list(string) | `[]` | Repository topics/tags |\n| `allow_merge_commit` | bool | `true` | Allow merge commits |\n| `allow_squash_merge` | bool | `true` | Allow squash merging |\n| `allow_rebase_merge` | bool | `true` | Allow rebase merging |\n| `allow_auto_merge` | bool | `false` | Allow auto-merge on pull requests |\n| `delete_branch_on_merge` | bool | `true` | Automatically delete head branches after merge |\n| `vulnerability_alerts` | bool | `true` | Enable security alerts |\n| `archive_on_destroy` | bool | `true` | Archive instead of delete on destroy |\n| `is_template` | bool | `false` | Make this a template repository |\n| `homepage_url` | string | `null` | Repository homepage URL |\n\n### Branch Protection Settings\n\nBranch protection is optional. Omit the `branch_protection` block to create a repository without protection.\n\n| Field | Type | Default | Description |\n|-------|------|---------|-------------|\n| `pattern` | string | **required** | Branch pattern (e.g., `\"main\"`, `\"develop\"`) |\n| `enforce_admins` | bool | `false` | Enforce rules for administrators |\n| `require_signed_commits` | bool | `false` | Require signed commits |\n| `require_conversation_resolution` | bool | `false` | Require conversation resolution before merge |\n| `allows_force_pushes` | bool | `false` | Allow force pushes |\n| `allows_deletions` | bool | `false` | Allow branch deletion |\n| `lock_branch` | bool | `false` | Lock branch (read-only) |\n| `required_status_checks` | object | `null` | Required status checks configuration |\n| `required_pull_request_reviews` | object | `null` | Required PR reviews configuration |\n| `restrict_pushes` | object | `null` | Push restrictions configuration |\n\n#### Required Status Checks\n\n```hcl\nrequired_status_checks = {\n  strict   = true                    # Require branches to be up to date\n  contexts = [\"ci/tests\", \"ci/lint\"] # Status checks that must pass\n}\n```\n\n#### Required Pull Request Reviews\n\n```hcl\nrequired_pull_request_reviews = {\n  required_approving_review_count = 2    # Number of required approvals (1-6)\n  dismiss_stale_reviews           = true # Dismiss approvals on new commits\n  require_code_owner_reviews      = true # Require review from code owners\n  require_last_push_approval      = true # Require approval of latest push\n}\n```\n\n## Common Workflows\n\n### Strict Security Repository\n\n```hcl\n\"secure-app\" = {\n  description = \"High-security application\"\n  visibility  = \"private\"\n  \n  vulnerability_alerts = true\n  \n  branch_protection = {\n    pattern                         = \"main\"\n    enforce_admins                  = true\n    require_signed_commits          = true\n    require_conversation_resolution = true\n    \n    required_pull_request_reviews = {\n      required_approving_review_count = 2\n      dismiss_stale_reviews           = true\n      require_code_owner_reviews      = true\n      require_last_push_approval      = true\n    }\n    \n    required_status_checks = {\n      strict   = true\n      contexts = [\"security-scan\", \"tests\", \"lint\"]\n    }\n  }\n}\n```\n\n### Simple Personal Project\n\n```hcl\n\"my-notes\" = {\n  description = \"Personal notes\"\n  visibility  = \"private\"\n  \n  has_issues = true\n  auto_init  = true\n  \n  topics = [\"personal\", \"notes\"]\n  \n  # No branch protection - simple repo\n}\n```\n\n### Open Source Project\n\n```hcl\n\"awesome-lib\" = {\n  description = \"An awesome open source library\"\n  visibility  = \"public\"\n  \n  has_issues      = true\n  has_discussions = true\n  homepage_url    = \"https://awesome-lib.dev\"\n  \n  license_template   = \"mit\"\n  gitignore_template = \"Node\"\n  \n  topics = [\"javascript\", \"library\", \"open-source\"]\n  \n  branch_protection = {\n    pattern = \"main\"\n    \n    required_pull_request_reviews = {\n      required_approving_review_count = 1\n      dismiss_stale_reviews           = true\n    }\n    \n    required_status_checks = {\n      strict   = true\n      contexts = [\"tests\", \"lint\"]\n    }\n  }\n}\n```\n\n## Outputs\n\nAfter applying, Terraform outputs the following information:\n\n- `repositories`: Complete details of all created repositories\n- `repository_urls`: Quick map of repository names to URLs\n- `protected_branches`: List of repositories with branch protection\n\nView outputs:\n\n```bash\nterraform output\nterraform output repositories\nterraform output repository_urls\n```\n\n## Security Best Practices\n\n1. **Never commit sensitive data**\n   - Keep `terraform.tfvars` out of version control (already in `.gitignore`)\n   - Use environment variables for tokens\n   - Rotate tokens regularly\n\n2. **Use branch protection**\n   - Always protect `main` and production branches\n   - Require pull request reviews\n   - Enable signed commits for sensitive repositories\n\n3. **Enable security features**\n   - Enable `vulnerability_alerts`\n   - Use `private` visibility by default\n   - Set `archive_on_destroy = true` to prevent accidental deletion\n\n4. **Terraform Cloud security**\n   - Enable 2FA on Terraform Cloud account\n   - Use workspace permissions appropriately\n   - Review state file access\n\n## Troubleshooting\n\n### Authentication Issues\n\n```bash\n# Verify token is set\necho $GITHUB_TOKEN\n\n# Test GitHub API access\ncurl -H \"Authorization: token $GITHUB_TOKEN\" https://api.github.com/user\n```\n\n### Terraform Cloud Login\n\n```bash\n# Login to Terraform Cloud\nterraform login\n\n# Or manually create ~/.terraform.d/credentials.tfrc.json\n```\n\n### State Issues\n\n```bash\n# Refresh state\nterraform refresh\n\n# View current state\nterraform show\n\n# Import existing repository (if needed)\nterraform import 'module.repositories[\"repo-name\"].github_repository.this' owner/repo-name\n```\n\n### Validation Errors\n\n```bash\n# Check configuration\nterraform validate\n\n# Format code\nterraform fmt -recursive\n\n# Show plan with detailed logs\nTF_LOG=DEBUG terraform plan\n```\n\n## Maintenance\n\n### Update Dependencies\n\n```bash\n# Update providers\nterraform init -upgrade\n\n# Check for updates\nterraform version\n```\n\n### Backup State\n\nTerraform Cloud automatically versions state. To download:\n\n```bash\n# Download state\nterraform state pull \u003e terraform.tfstate.backup\n```\n\n## Contributing\n\nThis is a personal infrastructure project. Feel free to fork and adapt for your own use.\n\n## License\n\nMIT License - Feel free to use this as a template for your own infrastructure.\n\n## Resources\n\n- [Terraform GitHub Provider Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs)\n- [Terraform Cloud Documentation](https://developer.hashicorp.com/terraform/cloud-docs)\n- [GitHub API Documentation](https://docs.github.com/en/rest)\n\n---\n\n**Happy Infrastructure Coding!** 🚀\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzfael%2Fgithub-infra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzfael%2Fgithub-infra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzfael%2Fgithub-infra/lists"}