{"id":28487822,"url":"https://github.com/rios0rios0/terra","last_synced_at":"2026-05-23T02:04:31.013Z","repository":{"id":206594069,"uuid":"717116679","full_name":"rios0rios0/terra","owner":"rios0rios0","description":"A powerful wrapper for Terragrunt and Terraform that revolutionizes infrastructure as code management. Inspired by the simplicity and efficiency of Kubernetes, terra allows you to apply Terraform code with the ease of specifying paths directly in your commands.","archived":false,"fork":false,"pushed_at":"2026-05-19T18:39:03.000Z","size":871,"stargazers_count":12,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-19T19:10:32.507Z","etag":null,"topics":["automation","golang","infrastructure-as-code","terraform","terragrunt"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rios0rios0.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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},"funding":{"github":"rios0rios0"}},"created_at":"2023-11-10T15:40:30.000Z","updated_at":"2026-05-19T15:56:48.000Z","dependencies_parsed_at":"2026-05-08T21:00:53.063Z","dependency_job_id":null,"html_url":"https://github.com/rios0rios0/terra","commit_stats":null,"previous_names":["rios0rios0/terra"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/rios0rios0/terra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rios0rios0%2Fterra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rios0rios0%2Fterra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rios0rios0%2Fterra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rios0rios0%2Fterra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rios0rios0","download_url":"https://codeload.github.com/rios0rios0/terra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rios0rios0%2Fterra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33379721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T01:21:08.577Z","status":"online","status_checked_at":"2026-05-23T02:00:05.530Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["automation","golang","infrastructure-as-code","terraform","terragrunt"],"created_at":"2025-06-08T05:08:00.867Z","updated_at":"2026-05-23T02:04:26.003Z","avatar_url":"https://github.com/rios0rios0.png","language":"Go","funding_links":["https://github.com/sponsors/rios0rios0"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eTerra\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/rios0rios0/terra/releases/latest\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/release/rios0rios0/terra.svg?style=for-the-badge\u0026logo=github\" alt=\"Latest Release\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/rios0rios0/terra/blob/main/LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/license/rios0rios0/terra.svg?style=for-the-badge\u0026logo=github\" alt=\"License\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/rios0rios0/terra/actions/workflows/default.yaml\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/rios0rios0/terra/default.yaml?branch=main\u0026style=for-the-badge\u0026logo=github\" alt=\"Build Status\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://sonarcloud.io/summary/overall?id=rios0rios0_terra\"\u003e\n        \u003cimg src=\"https://img.shields.io/sonar/coverage/rios0rios0_terra?server=https%3A%2F%2Fsonarcloud.io\u0026style=for-the-badge\u0026logo=sonarqubecloud\" alt=\"Coverage\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://sonarcloud.io/summary/overall?id=rios0rios0_terra\"\u003e\n        \u003cimg src=\"https://img.shields.io/sonar/quality_gate/rios0rios0_terra?server=https%3A%2F%2Fsonarcloud.io\u0026style=for-the-badge\u0026logo=sonarqubecloud\" alt=\"Quality Gate\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.bestpractices.dev/projects/12031\"\u003e\n        \u003cimg src=\"https://img.shields.io/cii/level/12031?style=for-the-badge\u0026logo=opensourceinitiative\" alt=\"OpenSSF Best Practices\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nA powerful wrapper for Terragrunt and Terraform that revolutionizes infrastructure as code management. Inspired by the simplicity and efficiency of Kubernetes, `terra` allows you to apply Terraform code with the ease of specifying paths directly in your commands.\n\n## Features\n\n- Seamless integration with Terraform and Terragrunt\n- Intuitive command-line interface with path-based syntax\n- Enhanced state management\n- Simplified module path specification\n- Cross-platform compatibility\n- Non-interactive execution via `--yes` / `-y` (or `--no` / `-n`) that maps to Terraform's `-auto-approve` and Terragrunt's `--non-interactive` -- no PTY pattern matching, works reliably with `terraform apply`\n- Self-update capability to automatically update terra to the latest version\n- Version checking for Terra, Terraform, and Terragrunt dependencies\n- Automatic dependency installation and management\n- Support for AWS and Azure cloud provider switching\n- **Parallel execution for any command** - Run any Terragrunt command across multiple modules simultaneously using the `--parallel=N` flag, where N is the number of concurrent threads. Use `--only=mod1,mod2` to select specific modules or `--skip=mod3` to exclude modules.\n- **Centralized module and provider caching** - Automatically configures `TG_DOWNLOAD_DIR` and `TG_PROVIDER_CACHE_DIR` so Terragrunt modules and providers are downloaded once and reused across all stacks, repos, and terminals. Enables the Terragrunt Provider Cache Server (`TG_PROVIDER_CACHE=1`) for concurrent-safe provider deduplication with file locking, and pins `TG_NO_AUTO_PROVIDER_CACHE_DIR=true` so the CAS experiment's `auto-provider-cache-dir` feature does not silently override the shared cache path. Override defaults with `TERRA_MODULE_CACHE_DIR` and `TERRA_PROVIDER_CACHE_DIR` environment variables. Disable the Provider Cache Server with `TERRA_NO_PROVIDER_CACHE=true`.\n- **CAS (Content Addressable Store)** - Enables Terragrunt's experimental CAS by default (`TG_EXPERIMENT=cas`), which deduplicates Git clones via hard links for faster subsequent clones and reduced disk usage. Disable with `TERRA_NO_CAS=true`.\n- **Partial Parse Config Cache** - Enables Terragrunt's Partial Parse Config Cache by default (`TG_USE_PARTIAL_PARSE_CONFIG_CACHE=true`), which caches parsed HCL configs across modules sharing the same root include for faster config parsing. Disable with `TERRA_NO_PARTIAL_PARSE_CACHE=true`.\n- **Auto-initialization with upgrade detection** - Automatically detects when terraform/terragrunt needs `init --upgrade` (backend changes, provider conflicts, uninitialized modules) and runs it transparently before retrying the original command.\n\n## Installation\n\n### Quick Install (Recommended)\n\nInstall `terra` with a single command:\n```bash\ncurl -fsSL https://raw.githubusercontent.com/rios0rios0/terra/main/install.sh | sh\n```\n\nOr using wget:\n```bash\nwget -qO- https://raw.githubusercontent.com/rios0rios0/terra/main/install.sh | sh\n```\n\n### Installation Options\n\nThe installer supports several options:\n```bash\n# Install specific version\ncurl -fsSL https://raw.githubusercontent.com/rios0rios0/terra/main/install.sh | sh -s -- --version v1.0.0\n\n# Install to custom directory\ncurl -fsSL https://raw.githubusercontent.com/rios0rios0/terra/main/install.sh | sh -s -- --install-dir /usr/local/bin\n\n# Show what would be installed without doing it\ncurl -fsSL https://raw.githubusercontent.com/rios0rios0/terra/main/install.sh | sh -s -- --dry-run\n\n# Force reinstallation\ncurl -fsSL https://raw.githubusercontent.com/rios0rios0/terra/main/install.sh | sh -s -- --force\n```\n\n### Alternative Installation Methods\n\n#### Build from Source\n```bash\ngit clone https://github.com/rios0rios0/terra.git\ncd terra\nmake install\n```\n\n#### Download Pre-built Binaries\nDownload pre-built binaries from the [releases page](https://github.com/rios0rios0/terra/releases).\n\nAfter installation, you can install Terraform and Terragrunt dependencies automatically:\n```bash\nterra install\n```\n\nTo update terra itself to the latest version:\n```bash\nterra self-update\n```\n\n## Usage\n\nHere's how to use `terra` with Terraform/Terragrunt:\n```bash\n# it's going to apply all subdirectories inside \"path\"\nterra apply --all /path\n\n# it's going to plan all subdirectories inside \"to\"\nterra plan --all /path/to\n\n# it's going to plan just the \"module\" subdirectory inside \"to\"\nterra plan --all /path/to/module\n\n# or using Terraform approach, plan just the \"module\" subdirectory inside \"to\"\nterra plan /path/to/module\n\n# skip all confirmation prompts (apply/destroy use Terraform's -auto-approve)\nterra apply --yes --all /path\nterra -y plan --all /path/to\n\n# run non-interactively and abort on any confirmation prompt (no auto-approve)\nterra apply --no --all /path\nterra -n plan --all /path/to\n```\n\n### Command Reference\n\n```bash\nclear       Clear all cache and modules directories\nformat      Format all files in the current directory\ninstall     Install or update Terraform and Terragrunt to the latest versions\nupdate      Install or update Terraform and Terragrunt to the latest versions (alias for install)\nself-update Update terra to the latest version\nversion     Show Terra, Terraform, and Terragrunt versions\n```\n\n### Confirmation Flags: `--yes` and `--no`\n\nTerra translates two terra-level confirmation flags into native Terraform and Terragrunt flags so CI/CD pipelines and parallel workers never get stuck on prompts:\n\n| Flag | Short | Injected into the forwarded command |\n|------|-------|-------------------------------------|\n| `--yes` | `-y` | Terragrunt's `--non-interactive` + Terraform's `-auto-approve` (for `apply` / `destroy`) |\n| `--no` | `-n` | Terragrunt's `--non-interactive` only (Terraform's apply prompt aborts instead of proceeding, matching a \"no\" answer) |\n\nNo PTY, no regex-based prompt detection. The translation happens before the command is forwarded to Terragrunt, so the behavior is reliable across Terraform and Terragrunt versions.\n\n```bash\n# Non-interactive apply across a stack (Terraform's -auto-approve is injected automatically)\nterra apply --yes /path\nterra -y apply --all /path\nterra apply --parallel=4 --yes /path\n\n# Non-interactive execution that aborts on any confirmation prompt\nterra plan --no --all /path\nterra apply --parallel=4 --no /path\n```\n\n**When using `--parallel` with `apply` / `destroy`**, a confirmation flag is required because parallel workers cannot share stdin:\n\n```bash\n# ERROR: parallel workers cannot prompt\nterra apply --parallel=4 /path\n\n# CORRECT: inject native non-interactive flags\nterra apply --parallel=4 --yes /path\n```\n\n#### Deprecated: `--reply` / `-r`\n\nThe legacy `--reply` and `-r` flags still work but emit a deprecation warning. They are translated to the same native flags as their `--yes` / `--no` equivalents:\n\n| Legacy form | Mapped to |\n|-------------|-----------|\n| `--reply=y`, `-r=y`, bare `--reply`, bare `-r` | `--yes` |\n| `--reply=n`, `-r=n` | `--no` |\n\nMigrate scripts at your earliest convenience; `--reply` will be removed in a future release.\n\n### Parallel Execution\n\nTerra provides two independent parallel execution strategies. **They are not interchangeable** -- each one owns its own set of filter flags, and mixing them produces a validation error.\n\n**Choosing a strategy:**\n\n- State operation across multiple modules from a root directory? → must use `--parallel=N`. Terragrunt's `--all` does not support state commands. Single-module state commands (e.g., `terra state rm \u003caddr\u003e /path/to/one/module`) still work without `--parallel`.\n- Need terragrunt DAG ordering / `dependencies` block awareness? → must use `--all`.\n- Flat stack, want basename filtering? → either works; `--parallel=N` is simpler.\n- Need glob, graph, or git-diff filtering? → must use `--all` with terragrunt's `--filter`.\n\n**Terra-managed parallel** (`--parallel=N`) -- terra discovers modules and runs N goroutine workers. Filter modules with terra's `--only`/`--skip`:\n```bash\n# Run init across all modules with 4 parallel threads\nterra init --parallel=4 /path/to/infrastructure\n\n# Select specific directories with --only\nterra plan --parallel=4 --only=dev,staging,prod /path/to/infrastructure\n\n# Skip specific directories with --skip\nterra apply --parallel=4 --skip=test,backup /path/to/infrastructure\n\n# State commands across a root with multiple modules use --parallel\n# (single-module state commands can still be forwarded without --parallel)\nterra import --parallel=4 null_resource.example resource-id /path/to/infrastructure\nterra state rm --parallel=2 null_resource.example /path/to/infrastructure\n```\n\n**Terragrunt-managed parallel** (`--all`) -- forwarded directly to terragrunt. Filter modules with terragrunt's `--filter` (preferred) or `--queue-exclude-dir`:\n```bash\n# Terragrunt's native run-all\nterra apply --all /path/to/infrastructure\n\n# Terragrunt's run-all with concurrency control\nterra plan --all --parallelism=4 /path/to/infrastructure\n\n# Terragrunt's run-all skipping a module with --filter (preferred)\nterra apply --all --filter='!excluded-mod' /path/to/infrastructure\n\n# Terragrunt's run-all skipping a module with the legacy flag\nterra apply --all --queue-exclude-dir=excluded-mod /path/to/infrastructure\n```\n\n**Filter equivalence table** -- use the column that matches your chosen strategy:\n\n| Intent                  | With `--parallel=N`  | With `--all`                          |\n|-------------------------|----------------------|---------------------------------------|\n| Skip one module         | `--skip=mod1`        | `--filter='!mod1'`                    |\n| Skip multiple           | `--skip=mod1,mod2`   | `--filter='!mod1' --filter='!mod2'`   |\n| Only specific modules   | `--only=mod1,mod2`   | `--filter='mod1' --filter='mod2'`     |\n| Path glob               | *(not supported)*    | `--filter='./prod/**'`                |\n| Graph expression        | *(not supported)*    | `--filter='service...'`               |\n| Git-diff expression     | *(not supported)*    | `--filter='[main...HEAD]'`            |\n\n\u003e **Note:** `--parallel` and `--all` cannot be used together -- they represent competing execution strategies. Similarly, terra's `--only`/`--skip` only work with `--parallel`; passing them alongside `--all` produces an educational validation error that shows the `--filter` equivalent for your command. In the reverse direction, terragrunt-owned flags (`--filter`, `--queue-exclude-dir`, `--queue-include-dir`) trigger a warning when combined with `--parallel=N` because terra's worker pool silently ignores them.\n\nFor comprehensive documentation, see [docs/parallel-execution.md](docs/parallel-execution.md). If you encounter Git clone errors (`BUG: refs/files-backend.c`) during parallel execution, see [docs/parallel-git-clone-race.md](docs/parallel-git-clone-race.md).\n\n### Version Management\n\n#### Checking Versions\n```bash\nterra version\n```\nThis displays Terra, Terraform, and Terragrunt versions.\n\n#### Self-Update\n```bash\n# Interactive update (prompts for confirmation)\nterra self-update\n\n# Force update without prompts\nterra self-update --force\n\n# Dry run to see what would be updated\nterra self-update --dry-run\n```\n\n#### Dependency Management\n```bash\n# Install dependencies (prompts for updates if newer versions available)\nterra install\n\n# Alternative command (alias for install)\nterra update\n```\n\n## Environment Configuration\n\nTerra can be configured with environment variables for cloud provider integration. Create a `.env` file in your project root:\n\n```bash\n# Optional: Cloud provider (if specified, must be \"aws\" or \"azure\")\nTERRA_CLOUD=aws\n\n# AWS specific (required for role switching when using AWS)\nTERRA_AWS_ROLE_ARN=arn:aws:iam::123456789012:role/terraform-role\n\n# Azure specific (required for subscription switching when using Azure)\nTERRA_AZURE_SUBSCRIPTION_ID=12345678-1234-1234-1234-123456789012\n\n# Optional: Terraform workspace\nTERRA_WORKSPACE=dev\n\n# Optional: Terraform variables (any TF_VAR_* variables)\nTF_VAR_environment=development\nTF_VAR_region=us-west-2\n\n# Optional: Centralized cache directories (defaults shown below)\n# TERRA_MODULE_CACHE_DIR=~/.cache/terra/modules\n# TERRA_PROVIDER_CACHE_DIR=~/.cache/terra/providers\n\n# Optional: Disable Terragrunt CAS (Content Addressable Store) experiment\n# TERRA_NO_CAS=true\n\n# Optional: Disable Terragrunt Partial Parse Config Cache\n# TERRA_NO_PARTIAL_PARSE_CACHE=true\n\n# Optional: Disable automatic workspace selection from TERRA_WORKSPACE\n# TERRA_NO_WORKSPACE=true\n\n# Optional: Override the per-download deadline that `terra install`\n# applies to the Terraform / Terragrunt fetch (default 10 minutes).\n# Useful when slower transports (corporate proxies, low-bandwidth\n# links, QEMU-emulated multi-arch container builds) push the\n# Terragrunt download past the default. Accepts any value parseable\n# by `time.ParseDuration` -- e.g. `30m`, `1h`, `20m30s`. Malformed\n# or non-positive values fall back to the default and log a warning.\n# TERRA_DOWNLOAD_TIMEOUT=30m\n```\n\n**Note**: If `TERRA_CLOUD` is specified, it must be set to either \"aws\" or \"azure\". This enables cloud-specific features like role switching for AWS or subscription switching for Azure.\n\nIf you have some input variables, you can use environment variables (`.env`) with the prefix `TF_VAR_`:\n```bash\n# .env example for Terraform variables\nTF_VAR_foo=bar\n# command (that depends on the environment variable called \"foo\")\nterra apply --all /path/to/module\n```\nMore about it in:\n- [Terraform documentation](https://www.terraform.io/docs/language/values/variables.html#environment-variables)\n- [Terragrunt documentation](https://terragrunt.gruntwork.io/docs/features/inputs/)\n\n## Known Issues\n\n1. Notice that Windows has `path` size limitations (256 characters).\n   If you are using WSL interoperability (calling `.exe` files inside WSL), you could have errors like this:\n   ```bash\n   /mnt/c/WINDOWS/system32/notepad.exe: Invalid argument\n   ```\n   That means you exceeded the `path` size limitation on the current `path` you are running the command.\n   To avoid this issue, move your infrastructure project to a shorter `path`, closer to your \"/home\" directory, for example.\n\n## Benchmarks\n\nProvider caching strategy comparison using `terragrunt init` with `azurerm` provider `v4.42.0` on a single module:\n\n### Speed\n\n| Strategy                   | Cold cache | Warm cache (median) |\n|----------------------------|------------|---------------------|\n| No cache                   | 12.4s      | 12.4s               |\n| `TF_PLUGIN_CACHE_DIR` only | 11.9s      | **8.9s**            |\n| `TG_PROVIDER_CACHE` only   | 11.8s      | 10.6s               |\n| Both combined              | 11.4s      | 9.5s                |\n\n### Disk usage\n\n| Strategy                   | Shared cache | Per module         | Total (N modules)  |\n|----------------------------|--------------|--------------------|--------------------|\n| No cache                   | 0            | 238 MB (full copy) | 238 MB x N         |\n| `TF_PLUGIN_CACHE_DIR` only | 219 MB       | 19 MB (symlink)    | 219 MB + 19 MB x N |\n| `TG_PROVIDER_CACHE` only   | 219 MB       | 19 MB (symlink)    | 219 MB + 19 MB x N |\n| Both combined              | 219 MB       | 19 MB (symlink)    | 219 MB + 19 MB x N |\n\nWhile `TF_PLUGIN_CACHE_DIR` provides slightly better single-module warm-cache performance (8.9s vs 10.6s), it causes \"text file busy\" (`ETXTBSY`) errors during parallel execution (`--parallel=N`) because Terraform creates symlinks without file locking. Terra uses `TG_PROVIDER_CACHE` (Provider Cache Server) by default because it serializes provider downloads with file locking, making it safe for concurrent access from parallel goroutines. Disable with `TERRA_NO_PROVIDER_CACHE=true`.\n\n## Contributing\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\n`terra` is released under the [MIT License](LICENSE.md). See the LICENSE file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frios0rios0%2Fterra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frios0rios0%2Fterra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frios0rios0%2Fterra/lists"}