Showing preview only (8,488K chars total). Download the full file or copy to clipboard to get everything.
Repository: gruntwork-io/terragrunt
Branch: main
Commit: bd643cd47632
Files: 4072
Total size: 7.3 MB
Directory structure:
gitextract_0weulqda/
├── .coderabbit.yaml
├── .codespellrc
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── 01-bug_report.md
│ │ ├── 02-bad_error_message.md
│ │ ├── 03-rfc.yml
│ │ └── 04-feature-request.md
│ ├── assets/
│ │ └── release-assets-config.json
│ ├── cloud-nuke/
│ │ └── config.yml
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ ├── scripts/
│ │ ├── announce-release.sh
│ │ ├── gopls/
│ │ │ ├── check-for-changes.sh
│ │ │ ├── create-issue.js
│ │ │ ├── create-pr.js
│ │ │ └── run.sh
│ │ ├── release/
│ │ │ ├── README.md
│ │ │ ├── check-release-exists.sh
│ │ │ ├── create-archives.sh
│ │ │ ├── generate-checksums.sh
│ │ │ ├── generate-upload-summary.sh
│ │ │ ├── get-version.sh
│ │ │ ├── install-go-winres.ps1
│ │ │ ├── install-gon.sh
│ │ │ ├── lib-release-config.sh
│ │ │ ├── prepare-macos-artifacts.sh
│ │ │ ├── prepare-windows-artifacts.ps1
│ │ │ ├── restore-p12-certificate.ps1
│ │ │ ├── set-permissions.sh
│ │ │ ├── sign-checksums.sh
│ │ │ ├── sign-macos-binaries.sh
│ │ │ ├── sign-windows.ps1
│ │ │ ├── upload-assets.sh
│ │ │ ├── verify-assets-uploaded.sh
│ │ │ ├── verify-binaries-downloaded.sh
│ │ │ ├── verify-files.sh
│ │ │ ├── verify-smctl.ps1
│ │ │ └── verify-static-binary.sh
│ │ └── setup/
│ │ ├── cas.sh
│ │ ├── engine.sh
│ │ ├── experiment-mode.sh
│ │ ├── gcp.sh
│ │ ├── generate-mocks.sh
│ │ ├── generate-secrets.sh
│ │ ├── mac-sign.sh
│ │ ├── provider-cache-server.sh
│ │ ├── run-setup-scripts.sh
│ │ ├── sops.sh
│ │ ├── ssh.sh
│ │ ├── terraform-switch-latest.sh
│ │ ├── terraform-switch.sh
│ │ ├── tofu-switch.sh
│ │ └── windows-setup.ps1
│ └── workflows/
│ ├── announce-release.yml
│ ├── base-test.yml
│ ├── build-no-proxy.yml
│ ├── build.yml
│ ├── ci.yml
│ ├── cloud-nuke.yml
│ ├── codespell.yml
│ ├── flake.yml
│ ├── fuzz.yml
│ ├── go-mod-tidy-check.yml
│ ├── gopls.yml
│ ├── install-script-test.yml
│ ├── integration-test.yml
│ ├── license-check.yml
│ ├── lint.yml
│ ├── markdownlint.yml
│ ├── oidc-integration-test.yml
│ ├── precommit.yml
│ ├── release.yml
│ ├── sign-macos.yml
│ ├── sign-windows.yml
│ ├── stale.yml
│ └── update-codified-remote-deps.yml
├── .gitignore
├── .golangci.yml
├── .gon_amd64.hcl
├── .gon_arm64.hcl
├── .licensei.toml
├── .markdownlint-cli2.yaml
├── .pre-commit-config.yaml
├── .sonarcloud.properties
├── CODEOWNERS
├── KEYS
├── LICENSE.txt
├── Makefile
├── README.md
├── SECURITY.md
├── docs/
│ ├── .gitignore
│ ├── .vercelignore
│ ├── README.md
│ ├── astro.config.mjs
│ ├── components.json
│ ├── mise.toml
│ ├── package.json
│ ├── public/
│ │ ├── install
│ │ ├── robots.txt
│ │ └── schemas/
│ │ ├── auth-provider-cmd/
│ │ │ ├── v1/
│ │ │ │ └── schema.json
│ │ │ └── v2/
│ │ │ └── schema.json
│ │ └── run/
│ │ └── report/
│ │ ├── v1/
│ │ │ └── schema.json
│ │ ├── v2/
│ │ │ └── schema.json
│ │ ├── v3/
│ │ │ └── schema.json
│ │ └── v4/
│ │ └── schema.json
│ ├── src/
│ │ ├── assets/
│ │ │ └── icons/
│ │ │ └── terragrunt-icon-accent.astro
│ │ ├── components/
│ │ │ ├── Command.astro
│ │ │ ├── CompactFooter.astro
│ │ │ ├── CompatibilityTable.astro
│ │ │ ├── Flag.astro
│ │ │ ├── Header.astro
│ │ │ ├── InstallTab.astro
│ │ │ ├── InstallTabs.astro
│ │ │ ├── PageSidebar.astro
│ │ │ ├── SectionSpacer.astro
│ │ │ ├── SiteTitle.astro
│ │ │ ├── SkipLink.astro
│ │ │ ├── ThemeToggle.astro
│ │ │ ├── dv-IconButton.astro
│ │ │ ├── ui/
│ │ │ │ ├── Button.tsx
│ │ │ │ └── ButtonLink.tsx
│ │ │ └── vendored/
│ │ │ └── starlight/
│ │ │ ├── Card.astro
│ │ │ ├── FileTree.astro
│ │ │ ├── Icon.astro
│ │ │ ├── Icons.ts
│ │ │ ├── README.md
│ │ │ ├── file-tree-icons.ts
│ │ │ └── rehype-file-tree.ts
│ │ ├── content/
│ │ │ └── docs/
│ │ │ ├── 01-getting-started/
│ │ │ │ ├── 01-quick-start.mdx
│ │ │ │ ├── 02-overview.mdx
│ │ │ │ ├── 03-install.mdx
│ │ │ │ └── 04-terminology.md
│ │ │ ├── 02-guides/
│ │ │ │ └── 01-terralith-to-terragrunt/
│ │ │ │ ├── 01-introduction.md
│ │ │ │ ├── 02-overview.md
│ │ │ │ ├── 03-setup.mdx
│ │ │ │ ├── 04-step-1-starting-the-terralith.mdx
│ │ │ │ ├── 05-step-2-refactoring.mdx
│ │ │ │ ├── 06-step-3-adding-dev.mdx
│ │ │ │ ├── 07-step-4-breaking-the-terralith.mdx
│ │ │ │ ├── 08-step-5-adding-terragrunt.mdx
│ │ │ │ ├── 09-step-6-breaking-the-terralith-further.mdx
│ │ │ │ ├── 10-step-7-taking-advantage-of-terragrunt-stacks.mdx
│ │ │ │ ├── 11-step-8-refactoring-state-with-terragrunt-stacks.mdx
│ │ │ │ └── 12-wrap-up.mdx
│ │ │ ├── 03-features/
│ │ │ │ ├── 01-units/
│ │ │ │ │ ├── 02-includes.mdx
│ │ │ │ │ ├── 03-state-backend.mdx
│ │ │ │ │ ├── 04-extra-arguments.mdx
│ │ │ │ │ ├── 05-authentication.mdx
│ │ │ │ │ ├── 06-hooks.mdx
│ │ │ │ │ ├── 07-auto-init.mdx
│ │ │ │ │ ├── 08-runtime-control.mdx
│ │ │ │ │ ├── 09-engine.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ ├── 02-stacks/
│ │ │ │ │ ├── 02-implicit.mdx
│ │ │ │ │ ├── 03-explicit.mdx
│ │ │ │ │ ├── 04-stack-operations.mdx
│ │ │ │ │ ├── 06-run-queue.mdx
│ │ │ │ │ ├── 07-run-report.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ ├── 06-catalog/
│ │ │ │ │ ├── 02-tui.mdx
│ │ │ │ │ ├── 03-scaffold.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ ├── 07-caching/
│ │ │ │ │ ├── 02-provider-cache-server.mdx
│ │ │ │ │ ├── 03-auto-provider-cache-dir.mdx
│ │ │ │ │ ├── 04-cas.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ └── 08-filter/
│ │ │ │ ├── 02-name.mdx
│ │ │ │ ├── 03-path.mdx
│ │ │ │ ├── 04-attributes.mdx
│ │ │ │ ├── 05-graph.mdx
│ │ │ │ ├── 06-git.mdx
│ │ │ │ ├── 07-combining.mdx
│ │ │ │ ├── 08-filters-file.mdx
│ │ │ │ └── index.mdx
│ │ │ ├── 04-reference/
│ │ │ │ ├── 01-hcl/
│ │ │ │ │ ├── 01-overview.mdx
│ │ │ │ │ ├── 02-blocks.mdx
│ │ │ │ │ ├── 03-attributes.mdx
│ │ │ │ │ └── 04-functions.mdx
│ │ │ │ ├── 02-cli/
│ │ │ │ │ ├── 01-overview.mdx
│ │ │ │ │ ├── 02-commands/
│ │ │ │ │ │ ├── 0-opentofu-shortcuts.md
│ │ │ │ │ │ ├── 0100-run.md
│ │ │ │ │ │ ├── 0200-exec.md
│ │ │ │ │ │ ├── 0500-catalog.md
│ │ │ │ │ │ ├── 0600-scaffold.md
│ │ │ │ │ │ ├── 0700-find.md
│ │ │ │ │ │ ├── 0800-list.md
│ │ │ │ │ │ ├── 1100-render.md
│ │ │ │ │ │ ├── backend/
│ │ │ │ │ │ │ ├── 0300-bootstrap.md
│ │ │ │ │ │ │ ├── 0301-migrate.md
│ │ │ │ │ │ │ └── 0302-delete.md
│ │ │ │ │ │ ├── dag/
│ │ │ │ │ │ │ └── 1000-graph.md
│ │ │ │ │ │ ├── hcl/
│ │ │ │ │ │ │ ├── 0900-fmt.md
│ │ │ │ │ │ │ └── 0901-validate.md
│ │ │ │ │ │ ├── info/
│ │ │ │ │ │ │ └── 1200-print.md
│ │ │ │ │ │ └── stack/
│ │ │ │ │ │ ├── 0400-generate.md
│ │ │ │ │ │ ├── 0401-run.md
│ │ │ │ │ │ ├── 0402-output.md
│ │ │ │ │ │ └── 0403-clean.md
│ │ │ │ │ └── 98-global-flags.mdx
│ │ │ │ ├── 03-strict-controls.mdx
│ │ │ │ ├── 04-experiments.md
│ │ │ │ ├── 05-supported-versions.mdx
│ │ │ │ ├── 06-lock-files.mdx
│ │ │ │ ├── 07-logging/
│ │ │ │ │ ├── 01-overview.md
│ │ │ │ │ └── 02-formatting.md
│ │ │ │ └── 08-terragrunt-cache.md
│ │ │ ├── 05-community/
│ │ │ │ ├── 01-contributing.mdx
│ │ │ │ ├── 02-support.md
│ │ │ │ └── 03-license.md
│ │ │ ├── 06-troubleshooting/
│ │ │ │ ├── 01-debugging.mdx
│ │ │ │ ├── 02-open-telemetry.md
│ │ │ │ └── 03-performance.mdx
│ │ │ ├── 07-process/
│ │ │ │ ├── 01-1-0-guarantees.mdx
│ │ │ │ ├── 02-cli-rules.mdx
│ │ │ │ └── 03-releases.mdx
│ │ │ └── 08-migrate/
│ │ │ ├── 01-migrating-from-root-terragrunt-hcl.md
│ │ │ ├── 02-upgrading-to-terragrunt-0-19-x.md
│ │ │ ├── 03-cli-redesign.md
│ │ │ ├── 04-terragrunt-stacks.mdx
│ │ │ ├── 05-bare-include.md
│ │ │ └── 06-deprecated-attributes.mdx
│ │ ├── content.config.ts
│ │ ├── data/
│ │ │ ├── commands/
│ │ │ │ ├── backend/
│ │ │ │ │ ├── bootstrap.mdx
│ │ │ │ │ ├── delete.mdx
│ │ │ │ │ └── migrate.mdx
│ │ │ │ ├── catalog.mdx
│ │ │ │ ├── dag/
│ │ │ │ │ └── graph.mdx
│ │ │ │ ├── exec.mdx
│ │ │ │ ├── find.mdx
│ │ │ │ ├── hcl/
│ │ │ │ │ ├── fmt.mdx
│ │ │ │ │ └── validate.mdx
│ │ │ │ ├── info/
│ │ │ │ │ └── print.mdx
│ │ │ │ ├── list.mdx
│ │ │ │ ├── opentofu-shortcuts.mdx
│ │ │ │ ├── render.mdx
│ │ │ │ ├── run.mdx
│ │ │ │ ├── scaffold.mdx
│ │ │ │ └── stack/
│ │ │ │ ├── clean.mdx
│ │ │ │ ├── generate.mdx
│ │ │ │ ├── output.mdx
│ │ │ │ └── run.mdx
│ │ │ ├── compatibility/
│ │ │ │ └── compatibility.json
│ │ │ └── flags/
│ │ │ ├── all.mdx
│ │ │ ├── auth-provider-cmd.mdx
│ │ │ ├── backend-bootstrap-all.mdx
│ │ │ ├── backend-bootstrap-config.mdx
│ │ │ ├── backend-bootstrap-download-dir.mdx
│ │ │ ├── backend-delete-all.mdx
│ │ │ ├── backend-delete-config.mdx
│ │ │ ├── backend-delete-download-dir.mdx
│ │ │ ├── backend-delete-force.mdx
│ │ │ ├── backend-migrate-config.mdx
│ │ │ ├── backend-migrate-download-dir.mdx
│ │ │ ├── backend-migrate-force.mdx
│ │ │ ├── catalog-no-hooks.mdx
│ │ │ ├── catalog-no-include-root.mdx
│ │ │ ├── catalog-no-shell.mdx
│ │ │ ├── catalog-root-file-name.mdx
│ │ │ ├── config.mdx
│ │ │ ├── dependency-fetch-output-from-state.mdx
│ │ │ ├── destroy-dependencies-check.mdx
│ │ │ ├── disable-bucket-update.mdx
│ │ │ ├── disable-command-validation.mdx
│ │ │ ├── download-dir.mdx
│ │ │ ├── engine-cache-path.mdx
│ │ │ ├── engine-log-level.mdx
│ │ │ ├── engine-skip-check.mdx
│ │ │ ├── experiment-mode.mdx
│ │ │ ├── experiment.mdx
│ │ │ ├── experimental-engine.mdx
│ │ │ ├── fail-fast.mdx
│ │ │ ├── feature.mdx
│ │ │ ├── filter-affected.mdx
│ │ │ ├── filter.mdx
│ │ │ ├── filters-file.mdx
│ │ │ ├── find-dag.mdx
│ │ │ ├── find-dependencies.mdx
│ │ │ ├── find-exclude.mdx
│ │ │ ├── find-external.mdx
│ │ │ ├── find-format.mdx
│ │ │ ├── find-hidden.mdx
│ │ │ ├── find-include.mdx
│ │ │ ├── find-json.mdx
│ │ │ ├── find-no-hidden.mdx
│ │ │ ├── find-reading.mdx
│ │ │ ├── graph.mdx
│ │ │ ├── hcl-fmt-check.mdx
│ │ │ ├── hcl-fmt-diff.mdx
│ │ │ ├── hcl-fmt-exclude-dir.mdx
│ │ │ ├── hcl-fmt-file.mdx
│ │ │ ├── hcl-fmt-filter.mdx
│ │ │ ├── hcl-fmt-stdin.mdx
│ │ │ ├── hcl-validate-inputs.mdx
│ │ │ ├── hcl-validate-json.mdx
│ │ │ ├── hcl-validate-show-config-path.mdx
│ │ │ ├── hcl-validate-strict.mdx
│ │ │ ├── help.mdx
│ │ │ ├── iam-assume-role-duration.mdx
│ │ │ ├── iam-assume-role-session-name.mdx
│ │ │ ├── iam-assume-role-web-identity-token.mdx
│ │ │ ├── iam-assume-role.mdx
│ │ │ ├── in-download-dir.mdx
│ │ │ ├── inputs-debug.mdx
│ │ │ ├── json-out-dir.mdx
│ │ │ ├── list-dag.mdx
│ │ │ ├── list-dependencies.mdx
│ │ │ ├── list-external.mdx
│ │ │ ├── list-format.mdx
│ │ │ ├── list-hidden.mdx
│ │ │ ├── list-long.mdx
│ │ │ ├── list-no-hidden.mdx
│ │ │ ├── list-tree.mdx
│ │ │ ├── log-custom-format.mdx
│ │ │ ├── log-disable.mdx
│ │ │ ├── log-format.mdx
│ │ │ ├── log-level.mdx
│ │ │ ├── log-show-abs-paths.mdx
│ │ │ ├── no-auto-approve.mdx
│ │ │ ├── no-auto-init.mdx
│ │ │ ├── no-auto-provider-cache-dir.mdx
│ │ │ ├── no-auto-retry.mdx
│ │ │ ├── no-color.mdx
│ │ │ ├── no-dependency-fetch-output-from-state.mdx
│ │ │ ├── no-destroy-dependencies-check.mdx
│ │ │ ├── no-engine.mdx
│ │ │ ├── no-filters-file.mdx
│ │ │ ├── no-stack-generate.mdx
│ │ │ ├── no-tip.mdx
│ │ │ ├── no-tips.mdx
│ │ │ ├── non-interactive.mdx
│ │ │ ├── out-dir.mdx
│ │ │ ├── parallelism.mdx
│ │ │ ├── provider-cache-dir.mdx
│ │ │ ├── provider-cache-hostname.mdx
│ │ │ ├── provider-cache-port.mdx
│ │ │ ├── provider-cache-registry-names.mdx
│ │ │ ├── provider-cache-token.mdx
│ │ │ ├── provider-cache.mdx
│ │ │ ├── queue-construct-as.mdx
│ │ │ ├── queue-exclude-dir.mdx
│ │ │ ├── queue-exclude-external.mdx
│ │ │ ├── queue-excludes-file.mdx
│ │ │ ├── queue-ignore-dag-order.mdx
│ │ │ ├── queue-ignore-errors.mdx
│ │ │ ├── queue-include-dir.mdx
│ │ │ ├── queue-include-external.mdx
│ │ │ ├── queue-include-units-reading.mdx
│ │ │ ├── queue-strict-include.mdx
│ │ │ ├── render-all.mdx
│ │ │ ├── render-format.mdx
│ │ │ ├── render-write.mdx
│ │ │ ├── report-file.mdx
│ │ │ ├── report-format.mdx
│ │ │ ├── report-schema-file.mdx
│ │ │ ├── scaffold-no-hooks.mdx
│ │ │ ├── scaffold-no-include-root.mdx
│ │ │ ├── scaffold-no-shell.mdx
│ │ │ ├── scaffold-root-file-name.mdx
│ │ │ ├── scaffold-var-file.mdx
│ │ │ ├── scaffold-var.mdx
│ │ │ ├── source-map.mdx
│ │ │ ├── source-update.mdx
│ │ │ ├── source.mdx
│ │ │ ├── stack-generate-filter.mdx
│ │ │ ├── stack-output-format.mdx
│ │ │ ├── stack-output-json.mdx
│ │ │ ├── stack-output-raw.mdx
│ │ │ ├── strict-control.mdx
│ │ │ ├── strict-mode.mdx
│ │ │ ├── summary-disable.mdx
│ │ │ ├── summary-per-unit.mdx
│ │ │ ├── tf-forward-stdout.mdx
│ │ │ ├── tf-path.mdx
│ │ │ ├── units-that-include.mdx
│ │ │ ├── use-partial-parse-config-cache.mdx
│ │ │ ├── version-manager-file-name.mdx
│ │ │ ├── version.mdx
│ │ │ └── working-dir.mdx
│ │ ├── fixtures/
│ │ │ └── terralith-to-terragrunt/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ └── best-cat/
│ │ │ │ ├── index.js
│ │ │ │ ├── package.json
│ │ │ │ ├── script.js
│ │ │ │ ├── styles.css
│ │ │ │ └── template.html
│ │ │ ├── mise.toml
│ │ │ └── walkthrough/
│ │ │ ├── step-1-starting-the-terralith/
│ │ │ │ └── live/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── data.tf
│ │ │ │ ├── ddb.tf
│ │ │ │ ├── iam.tf
│ │ │ │ ├── lambda.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── s3.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-2-refactoring/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── main.tf
│ │ │ │ ├── moved.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-3-adding-dev/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── main.tf
│ │ │ │ ├── moved.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-4-breaking-the-terralith/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── .auto.tfvars.example
│ │ │ │ │ ├── backend.tf
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── providers.tf
│ │ │ │ │ ├── removed.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── prod/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── main.tf
│ │ │ │ ├── moved.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── removed.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-5-adding-terragrunt/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── prod/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ ├── step-6-breaking-the-terralith-further/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ ├── removed.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── prod/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ ├── removed.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ ├── step-7-taking-advantage-of-terragrunt-stacks/
│ │ │ │ ├── catalog/
│ │ │ │ │ ├── modules/
│ │ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ │ ├── ddb/
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ │ └── versions.tf
│ │ │ │ │ │ ├── iam/
│ │ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ │ └── versions.tf
│ │ │ │ │ │ ├── lambda/
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ │ └── versions.tf
│ │ │ │ │ │ └── s3/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── units/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── s3/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── prod/
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── root.hcl
│ │ │ └── step-8-refactoring-state-with-terragrunt-stacks/
│ │ │ ├── catalog/
│ │ │ │ ├── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── units/
│ │ │ │ ├── ddb/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── iam/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── lambda/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── s3/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── live/
│ │ │ ├── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── root.hcl
│ │ ├── layouts/
│ │ │ └── BaseLayout.astro
│ │ ├── lib/
│ │ │ ├── commands/
│ │ │ │ ├── headings/
│ │ │ │ │ └── index.ts
│ │ │ │ └── sidebar/
│ │ │ │ └── index.ts
│ │ │ ├── github.ts
│ │ │ └── utils.ts
│ │ ├── pages/
│ │ │ ├── api/
│ │ │ │ └── v1/
│ │ │ │ └── compatibility/
│ │ │ │ └── [tool].ts
│ │ │ ├── index.astro
│ │ │ └── reference/
│ │ │ └── cli/
│ │ │ └── commands/
│ │ │ └── [...slug].astro
│ │ └── styles/
│ │ ├── global.css
│ │ ├── lists.css
│ │ ├── starlight-right-sidebar.css
│ │ └── starlight-search.css
│ ├── tailwind.config.mjs
│ ├── tests/
│ │ └── install_test.sh
│ ├── tsconfig.json
│ └── vercel.json
├── go.mod
├── go.sum
├── internal/
│ ├── awshelper/
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── policy.go
│ │ └── policy_test.go
│ ├── cache/
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ └── context.go
│ ├── cas/
│ │ ├── .gitignore
│ │ ├── benchmark_test.go
│ │ ├── cas.go
│ │ ├── cas_test.go
│ │ ├── content.go
│ │ ├── content_test.go
│ │ ├── errors.go
│ │ ├── errors_test.go
│ │ ├── getter.go
│ │ ├── getter_ssh_test.go
│ │ ├── getter_test.go
│ │ ├── integration_test.go
│ │ ├── local.go
│ │ ├── race_test.go
│ │ ├── store.go
│ │ ├── store_test.go
│ │ ├── tree.go
│ │ └── tree_test.go
│ ├── cli/
│ │ ├── app.go
│ │ ├── app_test.go
│ │ ├── commands/
│ │ │ ├── aws-provider-patch/
│ │ │ │ ├── aws-provider-patch.go
│ │ │ │ ├── aws-provider-patch_test.go
│ │ │ │ ├── cli.go
│ │ │ │ ├── errors.go
│ │ │ │ └── tofu_extensions_test.go
│ │ │ ├── backend/
│ │ │ │ ├── bootstrap/
│ │ │ │ │ ├── bootstrap.go
│ │ │ │ │ └── cli.go
│ │ │ │ ├── cli.go
│ │ │ │ ├── delete/
│ │ │ │ │ ├── cli.go
│ │ │ │ │ └── delete.go
│ │ │ │ └── migrate/
│ │ │ │ ├── cli.go
│ │ │ │ └── migrate.go
│ │ │ ├── catalog/
│ │ │ │ ├── TESTING.md
│ │ │ │ ├── catalog.go
│ │ │ │ ├── catalog_test.go
│ │ │ │ ├── cli.go
│ │ │ │ └── tui/
│ │ │ │ ├── command/
│ │ │ │ │ └── scaffold.go
│ │ │ │ ├── components/
│ │ │ │ │ └── buttonbar/
│ │ │ │ │ └── buttonbar.go
│ │ │ │ ├── delegate.go
│ │ │ │ ├── keys.go
│ │ │ │ ├── model.go
│ │ │ │ ├── model_test.go
│ │ │ │ ├── testdata/
│ │ │ │ │ └── TestTUIInitialOutput.golden
│ │ │ │ ├── tui.go
│ │ │ │ ├── update.go
│ │ │ │ └── view.go
│ │ │ ├── commands.go
│ │ │ ├── dag/
│ │ │ │ ├── cli.go
│ │ │ │ └── graph/
│ │ │ │ ├── cli.go
│ │ │ │ └── cli_test.go
│ │ │ ├── exec/
│ │ │ │ ├── cli.go
│ │ │ │ ├── exec.go
│ │ │ │ └── options.go
│ │ │ ├── find/
│ │ │ │ ├── cli.go
│ │ │ │ ├── find.go
│ │ │ │ ├── find_test.go
│ │ │ │ └── options.go
│ │ │ ├── hcl/
│ │ │ │ ├── cli.go
│ │ │ │ ├── format/
│ │ │ │ │ ├── cli.go
│ │ │ │ │ ├── errors.go
│ │ │ │ │ ├── format.go
│ │ │ │ │ ├── format_bench_test.go
│ │ │ │ │ ├── format_test.go
│ │ │ │ │ └── testdata/
│ │ │ │ │ └── fixtures/
│ │ │ │ │ ├── a/
│ │ │ │ │ │ ├── b/
│ │ │ │ │ │ │ └── c/
│ │ │ │ │ │ │ ├── d/
│ │ │ │ │ │ │ │ ├── e/
│ │ │ │ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ │ │ │ └── services.hcl
│ │ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── expected.hcl
│ │ │ │ │ ├── ignored/
│ │ │ │ │ │ ├── .gitignore
│ │ │ │ │ │ ├── .history/
│ │ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ │ └── .terragrunt-cache/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── validate/
│ │ │ │ ├── cli.go
│ │ │ │ ├── validate.go
│ │ │ │ └── validate_test.go
│ │ │ ├── help/
│ │ │ │ └── cli.go
│ │ │ ├── info/
│ │ │ │ ├── cli.go
│ │ │ │ ├── print/
│ │ │ │ │ ├── cli.go
│ │ │ │ │ └── print.go
│ │ │ │ └── strict/
│ │ │ │ └── command.go
│ │ │ ├── list/
│ │ │ │ ├── cli.go
│ │ │ │ ├── list.go
│ │ │ │ ├── list_test.go
│ │ │ │ └── options.go
│ │ │ ├── render/
│ │ │ │ ├── cli.go
│ │ │ │ ├── options.go
│ │ │ │ ├── render.go
│ │ │ │ └── render_test.go
│ │ │ ├── run/
│ │ │ │ ├── cli.go
│ │ │ │ ├── flags.go
│ │ │ │ ├── help.go
│ │ │ │ └── run.go
│ │ │ ├── scaffold/
│ │ │ │ ├── cli.go
│ │ │ │ ├── scaffold.go
│ │ │ │ └── scaffold_test.go
│ │ │ ├── shortcuts.go
│ │ │ ├── stack/
│ │ │ │ ├── cli.go
│ │ │ │ ├── output.go
│ │ │ │ ├── output_test.go
│ │ │ │ └── stack.go
│ │ │ └── version/
│ │ │ └── cli.go
│ │ ├── flags/
│ │ │ ├── deprecated_flag.go
│ │ │ ├── error_handler.go
│ │ │ ├── error_handler_test.go
│ │ │ ├── errors.go
│ │ │ ├── flag.go
│ │ │ ├── flag_opts.go
│ │ │ ├── flag_test.go
│ │ │ ├── global/
│ │ │ │ └── flags.go
│ │ │ ├── prefix.go
│ │ │ └── shared/
│ │ │ ├── all.go
│ │ │ ├── auth.go
│ │ │ ├── backend.go
│ │ │ ├── config.go
│ │ │ ├── doc.go
│ │ │ ├── download.go
│ │ │ ├── errors.go
│ │ │ ├── failfast.go
│ │ │ ├── feature.go
│ │ │ ├── filter.go
│ │ │ ├── graph.go
│ │ │ ├── iamassumerole.go
│ │ │ ├── inputsdebug.go
│ │ │ ├── parallelism.go
│ │ │ ├── queue.go
│ │ │ ├── scaffold.go
│ │ │ └── tfpath.go
│ │ ├── help.go
│ │ └── help_test.go
│ ├── clihelper/
│ │ ├── app.go
│ │ ├── args.go
│ │ ├── args_test.go
│ │ ├── autocomplete.go
│ │ ├── bool_flag.go
│ │ ├── bool_flag_test.go
│ │ ├── category.go
│ │ ├── command.go
│ │ ├── command_test.go
│ │ ├── commands.go
│ │ ├── context.go
│ │ ├── errors.go
│ │ ├── exit_code.go
│ │ ├── flag.go
│ │ ├── flag_test.go
│ │ ├── flags.go
│ │ ├── flags_test.go
│ │ ├── funcs.go
│ │ ├── generic_flag.go
│ │ ├── generic_flag_test.go
│ │ ├── help.go
│ │ ├── map_flag.go
│ │ ├── map_flag_test.go
│ │ ├── slice_flag.go
│ │ ├── slice_flag_test.go
│ │ ├── sort.go
│ │ └── sort_test.go
│ ├── cloner/
│ │ ├── clone.go
│ │ └── cloner.go
│ ├── codegen/
│ │ ├── codegen.go
│ │ ├── errors.go
│ │ ├── generate.go
│ │ └── generate_test.go
│ ├── component/
│ │ ├── component.go
│ │ ├── component_test.go
│ │ ├── stack.go
│ │ ├── unit.go
│ │ └── unit_output.go
│ ├── configbridge/
│ │ └── bridge.go
│ ├── ctyhelper/
│ │ ├── helper.go
│ │ └── helper_test.go
│ ├── discovery/
│ │ ├── benchmark_test.go
│ │ ├── constructor.go
│ │ ├── discovery.go
│ │ ├── discovery_integration_test.go
│ │ ├── discovery_test.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── filter_test.go
│ │ ├── graph_option.go
│ │ ├── graph_target_test.go
│ │ ├── helpers.go
│ │ ├── options.go
│ │ ├── phase_filesystem.go
│ │ ├── phase_graph.go
│ │ ├── phase_parse.go
│ │ ├── phase_relationship.go
│ │ ├── phase_test.go
│ │ ├── phase_worktree.go
│ │ ├── phase_worktree_integration_test.go
│ │ ├── phase_worktree_test.go
│ │ └── types.go
│ ├── engine/
│ │ ├── engine.go
│ │ ├── engine_test.go
│ │ ├── public_keys.go
│ │ ├── types.go
│ │ └── verification.go
│ ├── errorconfig/
│ │ ├── types.go
│ │ └── types_test.go
│ ├── errors/
│ │ ├── errors.go
│ │ ├── export.go
│ │ ├── multierror.go
│ │ └── util.go
│ ├── experiment/
│ │ ├── errors.go
│ │ ├── experiment.go
│ │ ├── experiment_test.go
│ │ └── warnings.go
│ ├── filter/
│ │ ├── ast.go
│ │ ├── ast_test.go
│ │ ├── candidacy.go
│ │ ├── candidacy_test.go
│ │ ├── classifier.go
│ │ ├── classifier_test.go
│ │ ├── complex_test.go
│ │ ├── diagnostic.go
│ │ ├── diagnostic_test.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── evaluator.go
│ │ ├── evaluator_test.go
│ │ ├── examples_test.go
│ │ ├── filter.go
│ │ ├── filter_test.go
│ │ ├── filters.go
│ │ ├── filters_test.go
│ │ ├── fuzz_test.go
│ │ ├── hints.go
│ │ ├── hints_test.go
│ │ ├── lexer.go
│ │ ├── lexer_test.go
│ │ ├── matcher.go
│ │ ├── parser.go
│ │ ├── parser_test.go
│ │ ├── telemetry.go
│ │ ├── telemetry_test.go
│ │ ├── token.go
│ │ └── walk.go
│ ├── gcphelper/
│ │ ├── config.go
│ │ └── config_test.go
│ ├── git/
│ │ ├── benchmark_test.go
│ │ ├── diff.go
│ │ ├── errors.go
│ │ ├── git.go
│ │ ├── git_test.go
│ │ ├── gogit.go
│ │ ├── gogit_test.go
│ │ └── tree.go
│ ├── github/
│ │ ├── client.go
│ │ └── client_test.go
│ ├── hclhelper/
│ │ ├── wrap.go
│ │ └── wrap_test.go
│ ├── iacargs/
│ │ ├── boolean_args_test.go
│ │ ├── iacargs.go
│ │ └── iacargs_test.go
│ ├── iam/
│ │ └── iam.go
│ ├── locks/
│ │ └── lock.go
│ ├── os/
│ │ ├── exec/
│ │ │ ├── cmd.go
│ │ │ ├── cmd_unix_test.go
│ │ │ ├── cmd_windows_test.go
│ │ │ ├── console_windows_test.go
│ │ │ ├── opts.go
│ │ │ ├── ptty_unix.go
│ │ │ ├── ptty_windows.go
│ │ │ └── testdata/
│ │ │ ├── infinite_loop.bat
│ │ │ ├── test_exit_code.bat
│ │ │ ├── test_exit_code.sh
│ │ │ ├── test_graceful_shutdown.sh
│ │ │ ├── test_sigint_multiple.sh
│ │ │ └── test_sigint_wait.sh
│ │ ├── signal/
│ │ │ ├── context_canceled.go
│ │ │ ├── signal.go
│ │ │ ├── signal_unix.go
│ │ │ └── signal_windows.go
│ │ └── stdout/
│ │ └── stdout.go
│ ├── prepare/
│ │ └── prepare.go
│ ├── providercache/
│ │ ├── options/
│ │ │ └── options.go
│ │ ├── providercache.go
│ │ ├── providercache_test.go
│ │ └── resolve_modules_url_test.go
│ ├── queue/
│ │ ├── queue.go
│ │ └── queue_test.go
│ ├── remotestate/
│ │ ├── backend/
│ │ │ ├── backend.go
│ │ │ ├── common.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── errors.go
│ │ │ ├── gcs/
│ │ │ │ ├── backend.go
│ │ │ │ ├── backend_test.go
│ │ │ │ ├── client.go
│ │ │ │ ├── config.go
│ │ │ │ ├── config_test.go
│ │ │ │ ├── errors.go
│ │ │ │ └── remote_state_config.go
│ │ │ ├── normalize.go
│ │ │ ├── normalize_test.go
│ │ │ └── s3/
│ │ │ ├── backend.go
│ │ │ ├── backend_test.go
│ │ │ ├── client.go
│ │ │ ├── client_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── counting_semaphore.go
│ │ │ ├── counting_semaphore_test.go
│ │ │ ├── errors.go
│ │ │ ├── remote_state_config.go
│ │ │ ├── remote_state_config_test.go
│ │ │ └── retryer.go
│ │ ├── config.go
│ │ ├── remote_state.go
│ │ ├── remote_state_test.go
│ │ ├── terraform_state_file.go
│ │ └── terraform_state_file_test.go
│ ├── report/
│ │ ├── colors.go
│ │ ├── report.go
│ │ ├── report_test.go
│ │ ├── summary.go
│ │ └── writer.go
│ ├── retry/
│ │ └── defaults.go
│ ├── runner/
│ │ ├── common/
│ │ │ ├── options.go
│ │ │ ├── runner.go
│ │ │ └── unit_runner.go
│ │ ├── graph/
│ │ │ └── graph.go
│ │ ├── run/
│ │ │ ├── context.go
│ │ │ ├── creds/
│ │ │ │ ├── getter.go
│ │ │ │ └── providers/
│ │ │ │ ├── amazonsts/
│ │ │ │ │ └── provider.go
│ │ │ │ ├── externalcmd/
│ │ │ │ │ ├── provider.go
│ │ │ │ │ ├── schema.go
│ │ │ │ │ └── schema_test.go
│ │ │ │ └── provider.go
│ │ │ ├── debug.go
│ │ │ ├── download_source.go
│ │ │ ├── download_source_test.go
│ │ │ ├── errors.go
│ │ │ ├── file_copy_getter.go
│ │ │ ├── hook.go
│ │ │ ├── hook_internal_test.go
│ │ │ ├── options.go
│ │ │ ├── prepare_internal_test.go
│ │ │ ├── run.go
│ │ │ ├── run_test.go
│ │ │ ├── symlink_preserving_git_getter.go
│ │ │ ├── tofu_extensions_test.go
│ │ │ ├── version_check.go
│ │ │ ├── version_check_internal_test.go
│ │ │ └── version_check_test.go
│ │ ├── runall/
│ │ │ ├── errors.go
│ │ │ ├── runall.go
│ │ │ └── runall_test.go
│ │ ├── runcfg/
│ │ │ ├── types.go
│ │ │ ├── util.go
│ │ │ └── util_test.go
│ │ ├── runner.go
│ │ └── runnerpool/
│ │ ├── builder.go
│ │ ├── builder_helpers.go
│ │ ├── controller.go
│ │ ├── controller_test.go
│ │ ├── errors.go
│ │ ├── graph_fallback_test.go
│ │ ├── helpers_test.go
│ │ ├── runner.go
│ │ ├── runner_test.go
│ │ ├── writer.go
│ │ └── writer_test.go
│ ├── services/
│ │ └── catalog/
│ │ ├── catalog.go
│ │ ├── catalog_test.go
│ │ └── module/
│ │ ├── doc.go
│ │ ├── doc_test.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── repo.go
│ │ ├── repo_test.go
│ │ └── testdata/
│ │ └── find_modules/
│ │ ├── gitdir/
│ │ │ ├── HEAD
│ │ │ └── config
│ │ └── modules/
│ │ ├── eks-alb-ingress-controller/
│ │ │ ├── README.md
│ │ │ ├── main.tf
│ │ │ └── variables.tf
│ │ ├── eks-alb-ingress-controller-iam-policy/
│ │ │ ├── README.md
│ │ │ ├── main.tf
│ │ │ └── variables.tf
│ │ └── eks-aws-auth-merger/
│ │ ├── README.adoc
│ │ ├── core-concepts.md
│ │ ├── main.tf
│ │ └── variables.tf
│ ├── shell/
│ │ ├── error_explainer.go
│ │ ├── error_explainer_test.go
│ │ ├── git.go
│ │ ├── prompt.go
│ │ ├── run_cmd.go
│ │ ├── run_cmd_output_test.go
│ │ ├── run_cmd_test.go
│ │ ├── run_cmd_unix_test.go
│ │ ├── run_cmd_windows_test.go
│ │ └── testdata/
│ │ ├── test_outputs.sh
│ │ ├── test_sigint_wait.bat
│ │ └── test_sigint_wait.sh
│ ├── stacks/
│ │ ├── clean/
│ │ │ └── clean.go
│ │ ├── generate/
│ │ │ └── generate.go
│ │ └── output/
│ │ └── output.go
│ ├── strict/
│ │ ├── category.go
│ │ ├── control.go
│ │ ├── control_test.go
│ │ ├── controls/
│ │ │ ├── control.go
│ │ │ ├── controls.go
│ │ │ ├── deprecated_command.go
│ │ │ ├── deprecated_env_var.go
│ │ │ └── deprecated_flag_name.go
│ │ ├── errors.go
│ │ ├── status.go
│ │ ├── strict.go
│ │ └── view/
│ │ ├── plaintext/
│ │ │ ├── plaintext.go
│ │ │ ├── render.go
│ │ │ └── template.go
│ │ ├── render.go
│ │ ├── view.go
│ │ └── writer.go
│ ├── telemetry/
│ │ ├── context.go
│ │ ├── errors.go
│ │ ├── meter.go
│ │ ├── meter_test.go
│ │ ├── opts.go
│ │ ├── telemeter.go
│ │ ├── tracer.go
│ │ ├── tracer_test.go
│ │ └── util.go
│ ├── tf/
│ │ ├── cache/
│ │ │ ├── config.go
│ │ │ ├── controllers/
│ │ │ │ ├── discovery.go
│ │ │ │ ├── downloader.go
│ │ │ │ └── provider.go
│ │ │ ├── handlers/
│ │ │ │ ├── common_provider.go
│ │ │ │ ├── direct_provider.go
│ │ │ │ ├── errors.go
│ │ │ │ ├── filesystem_mirror_provider.go
│ │ │ │ ├── network_mirror_provider.go
│ │ │ │ ├── provider.go
│ │ │ │ ├── provider_test.go
│ │ │ │ ├── proxy_provider.go
│ │ │ │ └── registry_urls.go
│ │ │ ├── helpers/
│ │ │ │ ├── client.go
│ │ │ │ ├── http.go
│ │ │ │ └── reverse_proxy.go
│ │ │ ├── middleware/
│ │ │ │ ├── key_auth.go
│ │ │ │ ├── logger.go
│ │ │ │ ├── package.go
│ │ │ │ └── recover.go
│ │ │ ├── models/
│ │ │ │ ├── helper.go
│ │ │ │ ├── provider.go
│ │ │ │ └── provider_test.go
│ │ │ ├── router/
│ │ │ │ ├── controller.go
│ │ │ │ └── router.go
│ │ │ ├── server.go
│ │ │ └── services/
│ │ │ ├── provider_cache.go
│ │ │ └── service.go
│ │ ├── cliconfig/
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── credentials.go
│ │ │ ├── provider_installation.go
│ │ │ └── user_config.go
│ │ ├── context.go
│ │ ├── detailed_exitcode.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── getproviders/
│ │ │ ├── constraints.go
│ │ │ ├── constraints_test.go
│ │ │ ├── hash.go
│ │ │ ├── hash_test.go
│ │ │ ├── lock.go
│ │ │ ├── lock_test.go
│ │ │ ├── mocks/
│ │ │ │ ├── mock_lock.go
│ │ │ │ └── mock_provider.go
│ │ │ ├── package_authentication.go
│ │ │ ├── package_authentication_test.go
│ │ │ ├── provider.go
│ │ │ ├── public_keys.go
│ │ │ └── testdata/
│ │ │ └── filesystem-mirror/
│ │ │ └── tfe.example.com/
│ │ │ └── AwesomeCorp/
│ │ │ └── happycloud/
│ │ │ └── 0.1.0-alpha.2/
│ │ │ └── darwin_amd64/
│ │ │ ├── extra-data.txt
│ │ │ └── terraform-provider-happycloud
│ │ ├── getter.go
│ │ ├── getter_test.go
│ │ ├── log.go
│ │ ├── run_cmd.go
│ │ ├── run_cmd_test.go
│ │ ├── source.go
│ │ ├── source_test.go
│ │ ├── testdata/
│ │ │ └── test_outputs.sh
│ │ ├── tf.go
│ │ └── tf_test.go
│ ├── tfimpl/
│ │ └── tfimpl.go
│ ├── tflint/
│ │ ├── README.md
│ │ ├── tflint.go
│ │ └── tflint_test.go
│ ├── tips/
│ │ ├── errors.go
│ │ ├── tip.go
│ │ ├── tip_test.go
│ │ └── tips.go
│ ├── util/
│ │ ├── collections.go
│ │ ├── collections_test.go
│ │ ├── datetime.go
│ │ ├── datetime_test.go
│ │ ├── dirs.go
│ │ ├── file.go
│ │ ├── file_test.go
│ │ ├── file_tofu_test.go
│ │ ├── hash.go
│ │ ├── jsons.go
│ │ ├── jsons_test.go
│ │ ├── lockfile.go
│ │ ├── locks.go
│ │ ├── locks_test.go
│ │ ├── random.go
│ │ ├── random_test.go
│ │ ├── reflect.go
│ │ ├── reflect_test.go
│ │ ├── retry.go
│ │ ├── shell.go
│ │ ├── shell_test.go
│ │ ├── sync_writer.go
│ │ ├── testdata/
│ │ │ ├── fixture-glob-canonical/
│ │ │ │ ├── module-a/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── module-b/
│ │ │ │ ├── module-b-child/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── fixture-sanitize-path/
│ │ │ └── env/
│ │ │ └── unit/
│ │ │ └── .terraform-version
│ │ ├── trap_writer.go
│ │ ├── util.go
│ │ └── writer_notifier.go
│ ├── vfs/
│ │ ├── vfs.go
│ │ └── vfs_test.go
│ ├── view/
│ │ ├── diagnostic/
│ │ │ ├── diagnostic.go
│ │ │ ├── expression_value.go
│ │ │ ├── extra.go
│ │ │ ├── function.go
│ │ │ ├── range.go
│ │ │ ├── servity.go
│ │ │ └── snippet.go
│ │ ├── human_render.go
│ │ ├── json_render.go
│ │ ├── view.go
│ │ └── writer.go
│ ├── worker/
│ │ ├── worker.go
│ │ └── worker_test.go
│ ├── worktrees/
│ │ ├── worktrees.go
│ │ └── worktrees_test.go
│ └── writer/
│ └── writer.go
├── main.go
├── mise.cicd.toml
├── mise.toml
├── pkg/
│ ├── config/
│ │ ├── cache_test.go
│ │ ├── catalog.go
│ │ ├── catalog_test.go
│ │ ├── config.go
│ │ ├── config_as_cty.go
│ │ ├── config_as_cty_test.go
│ │ ├── config_helpers.go
│ │ ├── config_helpers_test.go
│ │ ├── config_partial.go
│ │ ├── config_partial_test.go
│ │ ├── config_test.go
│ │ ├── context.go
│ │ ├── cty_helpers.go
│ │ ├── dependency.go
│ │ ├── dependency_inputs_test.go
│ │ ├── dependency_test.go
│ │ ├── engine.go
│ │ ├── errors.go
│ │ ├── errors_block.go
│ │ ├── exclude.go
│ │ ├── external_test.go
│ │ ├── feature_flag.go
│ │ ├── hclparse/
│ │ │ ├── attributes.go
│ │ │ ├── block.go
│ │ │ ├── errors.go
│ │ │ ├── file.go
│ │ │ ├── options.go
│ │ │ └── parser.go
│ │ ├── include.go
│ │ ├── include_test.go
│ │ ├── locals.go
│ │ ├── locals_test.go
│ │ ├── options.go
│ │ ├── parsing_context.go
│ │ ├── sops_race_test.go
│ │ ├── sops_test.go
│ │ ├── stack.go
│ │ ├── stack_test.go
│ │ ├── stack_validation.go
│ │ ├── stack_validation_test.go
│ │ ├── telemetry.go
│ │ ├── translate.go
│ │ ├── util.go
│ │ ├── variable.go
│ │ └── variable_test.go
│ ├── log/
│ │ ├── context.go
│ │ ├── context_test.go
│ │ ├── external_test.go
│ │ ├── fields.go
│ │ ├── force_level_hook.go
│ │ ├── force_level_hook_test.go
│ │ ├── format/
│ │ │ ├── format.go
│ │ │ ├── format_test.go
│ │ │ ├── formatter.go
│ │ │ ├── options/
│ │ │ │ ├── align.go
│ │ │ │ ├── case.go
│ │ │ │ ├── color.go
│ │ │ │ ├── common.go
│ │ │ │ ├── content.go
│ │ │ │ ├── errors.go
│ │ │ │ ├── escape.go
│ │ │ │ ├── level_format.go
│ │ │ │ ├── option.go
│ │ │ │ ├── path_format.go
│ │ │ │ ├── prefix.go
│ │ │ │ ├── suffix.go
│ │ │ │ ├── time_format.go
│ │ │ │ ├── util.go
│ │ │ │ └── width.go
│ │ │ └── placeholders/
│ │ │ ├── common.go
│ │ │ ├── errors.go
│ │ │ ├── field.go
│ │ │ ├── interval.go
│ │ │ ├── level.go
│ │ │ ├── message.go
│ │ │ ├── placeholder.go
│ │ │ ├── placeholder_test.go
│ │ │ ├── plaintext.go
│ │ │ └── time.go
│ │ ├── formatter.go
│ │ ├── level.go
│ │ ├── level_test.go
│ │ ├── log.go
│ │ ├── logger.go
│ │ ├── logger_test.go
│ │ ├── options.go
│ │ ├── util.go
│ │ ├── util_test.go
│ │ └── writer/
│ │ ├── options.go
│ │ ├── writer.go
│ │ └── writer_test.go
│ ├── options/
│ │ ├── auto_retry_options.go
│ │ ├── options.go
│ │ └── options_test.go
│ └── pkg.go
└── test/
├── benchmarks/
│ ├── .gitignore
│ ├── helpers/
│ │ └── helpers.go
│ ├── integration_auto_provider_cache_dir_bench_test.go
│ ├── integration_bench_test.go
│ └── integration_cas_bench_test.go
├── cliconfig.go
├── fixtures/
│ ├── assume-role/
│ │ ├── duration/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── external-id/
│ │ │ └── terragrunt.hcl
│ │ └── external-id-with-comma/
│ │ └── terragrunt.hcl
│ ├── assume-role-web-identity/
│ │ └── file-path/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── auth-provider-cmd/
│ │ ├── creds-for-dependency/
│ │ │ ├── dependency/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dependent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── creds.config
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mock-auth-cmd.sh
│ │ ├── multiple-apps/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── creds.config
│ │ │ ├── root.hcl
│ │ │ └── test-creds.sh
│ │ ├── oidc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── mock-auth-cmd.sh
│ │ │ └── terragrunt.hcl
│ │ ├── remote-state/
│ │ │ ├── creds.config
│ │ │ └── terragrunt.hcl
│ │ ├── remote-state-w-oidc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── mock-auth-cmd.sh
│ │ │ └── terragrunt.hcl
│ │ └── sops/
│ │ ├── .terraform.lock.hcl
│ │ ├── creds.config
│ │ ├── main.tf
│ │ ├── secrets.json
│ │ └── terragrunt.hcl
│ ├── auth-provider-parallel/
│ │ ├── auth-provider.sh
│ │ ├── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── auto-provider-cache-dir/
│ │ ├── basic/
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── heavy/
│ │ └── unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── aws-provider-patch/
│ │ ├── example-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── broken-dependency/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── broken-locals/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── buffer-module-output/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app3/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── catalog/
│ │ ├── complex/
│ │ │ ├── common.hcl
│ │ │ ├── dev/
│ │ │ │ ├── account.hcl
│ │ │ │ └── us-west-1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── modules/
│ │ │ │ │ └── terraform-aws-eks/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ ├── region.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── prod/
│ │ │ │ ├── account.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── root.hcl
│ │ │ └── stage/
│ │ │ ├── account.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── complex-legacy-root/
│ │ │ ├── common.hcl
│ │ │ ├── dev/
│ │ │ │ ├── account.hcl
│ │ │ │ └── us-west-1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── modules/
│ │ │ │ │ └── terraform-aws-eks/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ ├── region.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── prod/
│ │ │ │ ├── account.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── stage/
│ │ │ │ ├── account.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── config1.hcl
│ │ ├── config2.hcl
│ │ ├── config3.hcl
│ │ ├── config4.hcl
│ │ ├── local-template/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ ├── custom-template.txt
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app/
│ │ │ │ └── .gitkeep
│ │ │ └── root.hcl
│ │ └── terraform-aws-eks/
│ │ └── README.md
│ ├── cli-flag-hints/
│ │ └── terragrunt.hcl
│ ├── codegen/
│ │ ├── generate-attr/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── terragrunt.hcl
│ │ │ └── test.tf
│ │ ├── generate-block/
│ │ │ ├── disable/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── disable-signature/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── enable/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── nested/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── child_inherit/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── backend.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── child_overwrite/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ ├── overwrite/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── overwrite_terragrunt/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── overwrite_terragrunt_error/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── same_name_error/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── same_name_includes_error/
│ │ │ │ ├── app1.hcl
│ │ │ │ ├── app2.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── same_name_pair_error/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── skip/
│ │ │ └── terragrunt.hcl
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── remote-state/
│ │ │ ├── base/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── error/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── overwrite/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── s3/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ └── skip/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ └── terragrunt.hcl
│ │ └── remove-file/
│ │ ├── remove/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── remove_terragrunt/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── remove_terragrunt_error/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── skip/
│ │ ├── .terraform.lock.hcl
│ │ ├── backend.tf
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── commands-that-need-input/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── config-files/
│ │ ├── ignore-cached-config/
│ │ │ └── terragrunt.hcl
│ │ ├── ignore-terraform-data-dir/
│ │ │ ├── .tf_data/
│ │ │ │ └── modules/
│ │ │ │ └── mod/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── root.hcl
│ │ │ └── subdir/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── .tf_data/
│ │ │ │ └── modules/
│ │ │ │ └── mod/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-configs/
│ │ │ ├── subdir-1/
│ │ │ │ └── empty.txt
│ │ │ ├── subdir-2/
│ │ │ │ └── subdir/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── subdir-3/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-json-configs/
│ │ │ ├── subdir-1/
│ │ │ │ └── empty.txt
│ │ │ ├── subdir-2/
│ │ │ │ └── subdir/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ ├── subdir-3/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── terragrunt.hcl.json
│ │ ├── multiple-mixed-configs/
│ │ │ ├── subdir-1/
│ │ │ │ └── empty.txt
│ │ │ ├── subdir-2/
│ │ │ │ └── subdir/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── subdir-3/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── terragrunt.hcl.json
│ │ ├── none/
│ │ │ ├── empty.txt
│ │ │ └── subdir/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── one-config/
│ │ │ ├── empty.txt
│ │ │ └── subdir/
│ │ │ └── terragrunt.hcl
│ │ ├── one-json-config/
│ │ │ ├── empty.txt
│ │ │ └── subdir/
│ │ │ └── terragrunt.hcl.json
│ │ ├── single-json-config/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl.json
│ │ └── with-non-default-names/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.hcl
│ │ │ └── main.tf
│ │ ├── common.hcl
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── another-name.hcl
│ │ │ └── main.tf
│ │ └── parent.hcl
│ ├── config-terraform-functions/
│ │ ├── other-file.txt
│ │ └── terragrunt.hcl
│ ├── dag-graph/
│ │ ├── region-1/
│ │ │ └── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── region-2/
│ │ │ └── unit-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl.hcl
│ ├── dependency-optimisation/
│ │ ├── module-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── dependency-output/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── destroy-dependent-module/
│ │ ├── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── destroy-dependent-module-errors/
│ │ ├── dev/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── env.hcl
│ │ └── prod/
│ │ ├── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── sops.yaml
│ │ └── terragrunt.hcl
│ ├── destroy-order/
│ │ ├── app/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module-e/
│ │ │ └── terragrunt.hcl
│ │ └── hello/
│ │ ├── .terraform.lock.hcl
│ │ ├── hello/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── main.tf
│ ├── destroy-warning/
│ │ ├── app-v1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── app-v2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── detailed-exitcode/
│ │ ├── changes/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── changes-with-source/
│ │ │ └── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── error/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── fail-on-first-run/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── fail-on-first-run-with-status/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── runall-retry-after-drift/
│ │ ├── app_drift/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app_flaky/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── dirs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── disabled/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-disabled/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-enabled/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-without-enabled/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── disabled-path/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── docs/
│ │ ├── 01-quick-start/
│ │ │ ├── step-01/
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-01.1/
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-02/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-03/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-04/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-05/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-05.1/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-06/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── output.tf
│ │ │ ├── step-07/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── output.tf
│ │ │ └── step-07.1/
│ │ │ ├── .gitignore
│ │ │ ├── bar/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── foo/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── shared/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── output.tf
│ │ ├── 02-overview/
│ │ │ ├── step-01-terragrunt.hcl/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-02-dependencies/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── root.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-03-mock-outputs/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── root.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-04-configuration-hierarchy/
│ │ │ │ ├── root.hcl
│ │ │ │ └── us-east-1/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── region.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── step-05-exposed-includes/
│ │ │ ├── root.hcl
│ │ │ ├── us-east-1/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── region.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── us-west-2/
│ │ │ ├── ec2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── region.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ └── 03-stacks-with-local-state/
│ │ ├── .gitignore
│ │ ├── live/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── root.hcl
│ │ └── units/
│ │ └── basic/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── download/
│ │ ├── custom-lock-file-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── custom-lock-file-terraform/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── custom-lock-file-tofu/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── extra-args/
│ │ │ └── common.tfvars
│ │ ├── hello-world/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── hello/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── main.tf
│ │ ├── hello-world-no-remote/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── hello-world-with-backend/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── init-on-source-change/
│ │ │ └── terragrunt.hcl
│ │ ├── invalid-path/
│ │ │ └── terragrunt.hcl
│ │ ├── local/
│ │ │ └── terragrunt.hcl
│ │ ├── local-disable-copy-terraform-lock-file/
│ │ │ └── terragrunt.hcl
│ │ ├── local-include-disable-copy-lock-file/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── local-include-with-prevent-destroy-dependencies/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── local-no-source/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── local-relative/
│ │ │ └── terragrunt.hcl
│ │ ├── local-relative-extra-args-unix/
│ │ │ └── terragrunt.hcl
│ │ ├── local-windows/
│ │ │ ├── JZwoL6Viko8bzuRvTOQFx3Jh8vs/
│ │ │ │ └── 3mU4huxMLOXOW5ZgJOFXGUFDKc8/
│ │ │ │ ├── hello/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-allowed-hidden/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── modules/
│ │ │ ├── .nonce
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── local-with-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-exclude-dir/
│ │ │ ├── integration-env/
│ │ │ │ ├── aws/
│ │ │ │ │ └── module-aws-a/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── gce/
│ │ │ │ ├── module-gce-b/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── module-gce-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── production-env/
│ │ │ ├── aws/
│ │ │ │ └── module-aws-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── gce/
│ │ │ └── module-gce-e/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-hidden-folder/
│ │ │ ├── .hidden-folder/
│ │ │ │ └── README.md
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-include-dir/
│ │ │ ├── integration-env/
│ │ │ │ ├── aws/
│ │ │ │ │ └── module-aws-a/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── gce/
│ │ │ │ ├── module-gce-b/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── module-gce-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── production-env/
│ │ │ ├── aws/
│ │ │ │ └── module-aws-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── gce/
│ │ │ └── module-gce-e/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-missing-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-prevent-destroy/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-prevent-destroy-dependencies/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module-e/
│ │ │ └── terragrunt.hcl
│ │ ├── override/
│ │ │ └── terragrunt.hcl
│ │ ├── relative/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── remote/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-invalid/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-invalid-with-retries/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-module-in-root/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-ref/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-relative/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-relative-with-slash/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-with-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── stdout/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── stdout-test/
│ │ ├── .terraform.lock.hcl
│ │ └── terragrunt.hcl
│ ├── download-source/
│ │ ├── download-dir-version-file/
│ │ │ └── version-file.txt
│ │ ├── download-dir-version-file-local-hash/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── download-dir-version-file-no-query/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── download-dir-version-file-tf-code/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── hello-world/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── hello-world-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── hello-world-local-hash/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── hello-world-local-hash-failed/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── hello-world-version-remote/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── version-file.txt
│ ├── empty-state/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── endswith/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── engine/
│ │ ├── engine-dependencies/
│ │ │ ├── .gitignore
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── local-engine/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── opentofu-engine/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── opentofu-latest-run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app4/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app5/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── opentofu-run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app4/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app5/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── remote-engine/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── trace-parent/
│ │ ├── .terraform.lock.hcl
│ │ ├── get_traceparent.sh
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── env-vars-block/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── ephemeral-inputs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── error-print/
│ │ ├── .terraform.lock.hcl
│ │ ├── custom-tf-script.sh
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── errors/
│ │ ├── default/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── get-default-errors/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── ignore/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── ignore-negative-pattern/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── ignore-signal/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multi-line/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── script.sh
│ │ │ └── terragrunt.hcl
│ │ ├── no-auto-retry/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── retry/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── script.sh
│ │ │ └── terragrunt.hcl
│ │ ├── retry-fail/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── script.sh
│ │ │ └── terragrunt.hcl
│ │ ├── run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── script.sh
│ │ │ │ └── terragrunt.hcl
│ │ │ └── common.hcl
│ │ └── run-all-ignore/
│ │ ├── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── exclude/
│ │ ├── basic/
│ │ │ ├── unit1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unit2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit3/
│ │ │ └── terragrunt.hcl
│ │ └── comprehensive/
│ │ ├── action-mismatch/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── always-excluded/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── conditional-flag/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── conditional-no-run/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dep-unit/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-all-except-output/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-apply-only/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-plan-only/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── flags.hcl
│ │ ├── never-excluded/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-run-false/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-run-not-set/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-run-true/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── normal-unit/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── with-dep/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── exclude-by-default/
│ │ ├── _stacks/
│ │ │ └── terragrunt.stack.hcl
│ │ └── unit1/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── excludes-file/
│ │ ├── .terragrunt-excludes
│ │ ├── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── d/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── excludes-file-pass-as-flag
│ ├── exec-cmd/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── script.sh
│ ├── exec-cmd-tf-path/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── script.sh
│ │ ├── terraform-output-json.sh
│ │ └── tofu-output-json.sh
│ ├── external-dependencies/
│ │ ├── module-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── module-b/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── external-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── extra-args/
│ │ ├── .terraform.lock.hcl
│ │ ├── dev.tfvars
│ │ ├── extra.tfvars
│ │ ├── main.tf
│ │ ├── terragrunt.hcl
│ │ └── us-west-2.tfvars
│ ├── fail-fast/
│ │ ├── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── fail-fast-early-exit/
│ │ ├── depends-on-failing/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depends-on-succeeding/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── failing-unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── succeeding-unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── failure/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── missingvars/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── submod/
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── submod/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── feature-flags/
│ │ ├── error-empty-flag/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── include-flag/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── common.hcl
│ │ └── simple-flag/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── filter/
│ │ ├── mark-as-read/
│ │ │ ├── unit-duplicate/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unit-empty/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unit-no-mark/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit-normal/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── minimize-parsing/
│ │ │ ├── dependency-unit/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── excluded-unit-1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── excluded-unit-2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── excluded-unit-3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── target-unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── minimize-parsing-destroy/
│ │ ├── landmine-unit-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── landmine-unit-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-b/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── filter-source/
│ │ ├── github-acme-bar/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── github-acme-foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── gitlab-example-baz/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── local-module/
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── find/
│ │ ├── basic/
│ │ │ ├── stack/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ └── terragrunt.hcl
│ │ ├── dag/
│ │ │ ├── a-dependent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── b-dependency/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── c-mixed-deps/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── d-dependencies-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── hidden/
│ │ │ ├── .hide/
│ │ │ │ └── unit/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── stack/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ └── terragrunt.hcl
│ │ ├── include/
│ │ │ ├── bar/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── cloud.hcl
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── internal-v-external/
│ │ │ ├── external/
│ │ │ │ └── c-dependency/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── internal/
│ │ │ ├── a-dependent/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── b-dependency/
│ │ │ └── terragrunt.hcl
│ │ └── read-terragrunt-config/
│ │ ├── .terraform.lock.hcl
│ │ ├── common_deps.hcl
│ │ ├── main.tf
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── find-parent/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── find-parent-with-deprecated-root/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── gcs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-backend/
│ │ ├── common.hcl
│ │ ├── unit1/
│ │ │ └── terragrunt.hcl
│ │ └── unit2/
│ │ └── terragrunt.hcl
│ ├── gcs-byo-bucket/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-impersonate/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-no-bucket/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-no-prefix/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-parallel-state-init/
│ │ ├── root.hcl
│ │ └── template/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-aws-account-alias/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-aws-caller-identity/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-output/
│ │ ├── cycle/
│ │ │ ├── aa/
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── aba/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── abca/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── baz/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── abcda/
│ │ │ ├── bar/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── baz/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── car/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── download-dir/
│ │ │ ├── in-config/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── not-set/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── integration/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── empty/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── localstate/
│ │ │ ├── live/
│ │ │ │ ├── child/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── parent/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── modules/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── parent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── mock-outputs/
│ │ │ ├── dependent1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependent2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependent3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── source/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mock-outputs-merge-strategy-with-state/
│ │ │ ├── merge-strategy-with-state-compat-conflict/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-compat-false/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-compat-true/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-deep-map-only/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-default/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-no-merge/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── merge-strategy-with-state-shallow/
│ │ │ ├── live/
│ │ │ │ ├── child/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── parent/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── modules/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── parent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── mock-outputs-merge-with-state/
│ │ │ ├── merge-with-state-default/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-with-state-false/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-with-state-no-override/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-with-state-true/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── merge-with-state-true-validate-only/
│ │ │ ├── live/
│ │ │ │ ├── child/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── parent/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── modules/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── parent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── nested-mocks/
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── live/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── nested-optimization/
│ │ │ ├── .gitignore
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── live/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── nested-optimization-disable/
│ │ │ ├── .gitignore
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── live/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── nested-optimization-nogen/
│ │ │ ├── .gitignore
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── live/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── regression-1102/
│ │ │ ├── .gitignore
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── regression-1124/
│ │ │ ├── live/
│ │ │ │ ├── app/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── dependency/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── modules/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── regression-1273/
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── main/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── regression-854/
│ │ │ └── root/
│ │ │ ├── environments/
│ │ │ │ ├── network/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── web/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── sg/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── regression-906/
│ │ │ ├── a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── c/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── common-dep/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── d/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── e/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── f/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── g/
│ │ │ └── terragrunt.hcl
│ │ ├── run-all-source/
│ │ │ ├── live/
│ │ │ │ ├── unit1/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── unit2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── modules-default/
│ │ │ │ ├── module1/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── module2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── modules-marked/
│ │ │ ├── module1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── MODULE1_MARKER
│ │ │ │ └── main.tf
│ │ │ └── module2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── MODULE2_MARKER
│ │ │ └── main.tf
│ │ └── type-conversion/
│ │ └── terragrunt.hcl
│ ├── get-path/
│ │ ├── get-path-from-repo-root/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── get-path-to-repo-root/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── path_relative_from_include/
│ │ ├── lives/
│ │ │ ├── dev/
│ │ │ │ ├── base/
│ │ │ │ │ ├── terragrunt.hcl
│ │ │ │ │ └── tier.hcl
│ │ │ │ ├── cluster/
│ │ │ │ │ ├── terragrunt.hcl
│ │ │ │ │ └── tier.hcl
│ │ │ │ └── env.hcl
│ │ │ ├── org.hcl
│ │ │ └── root.hcl
│ │ └── modules/
│ │ ├── base/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── cluster/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── get-platform/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-repo-root/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-terragrunt-source-cli/
│ │ ├── terraform_config_cli/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── get-terragrunt-source-hcl/
│ │ ├── terraform_config_hcl/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── get-working-dir/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── modules/
│ │ │ └── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── graph/
│ │ ├── eks/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── lambda/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── services/
│ │ ├── eks-service-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-2-v2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-3-v2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-3-v3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-4/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-5/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── lambda-service-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── lambda-service-2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── graph-dependencies/
│ │ ├── root/
│ │ │ ├── backend-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── frontend-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── mysql/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── redis/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── hcl-filter/
│ │ ├── fmt/
│ │ │ ├── already-formatted/
│ │ │ │ ├── app1/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── app2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── needs-formatting/
│ │ │ │ ├── db/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── nested/
│ │ │ │ ├── api/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── deep/
│ │ │ │ └── web/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── stacks/
│ │ │ ├── already-formatted/
│ │ │ │ └── stack2/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── needs-formatting/
│ │ │ └── stack1/
│ │ │ └── terragrunt.stack.hcl
│ │ └── validate/
│ │ ├── semantic-error/
│ │ │ ├── incomplete-block/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── missing-value/
│ │ │ └── terragrunt.hcl
│ │ ├── stacks/
│ │ │ ├── syntax-error/
│ │ │ │ └── stack2/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── valid/
│ │ │ └── stack1/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── syntax-error/
│ │ │ ├── invalid-char/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── invalid-key/
│ │ │ └── terragrunt.hcl
│ │ └── valid/
│ │ ├── db/
│ │ │ └── terragrunt.hcl
│ │ └── nested/
│ │ ├── api/
│ │ │ └── terragrunt.hcl
│ │ └── deep/
│ │ └── web/
│ │ └── terragrunt.hcl
│ ├── hclfmt-check/
│ │ ├── a/
│ │ │ ├── b/
│ │ │ │ └── c/
│ │ │ │ ├── d/
│ │ │ │ │ ├── e/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── services.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclfmt-check-errors/
│ │ ├── a/
│ │ │ ├── b/
│ │ │ │ └── c/
│ │ │ │ ├── d/
│ │ │ │ │ ├── e/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── services.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclfmt-diff/
│ │ ├── expected.diff
│ │ └── terragrunt.hcl
│ ├── hclfmt-errors/
│ │ ├── dangling-attribute/
│ │ │ └── terragrunt.hcl
│ │ ├── invalid-character/
│ │ │ └── terragrunt.hcl
│ │ └── invalid-key/
│ │ └── terragrunt.hcl
│ ├── hclfmt-heredoc/
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclfmt-stdin/
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclvalidate/
│ │ ├── first/
│ │ │ └── b/
│ │ │ └── terragrunt.hcl
│ │ ├── second/
│ │ │ ├── a/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── c/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── d/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── valid/
│ │ ├── circular-reference/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── invalid-local/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── single-required-input/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── validation-block/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── var-in-source/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── var-in-version/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── hidden-runall/
│ │ └── .cloud/
│ │ └── terraform/
│ │ ├── app1/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app2/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── hooks/
│ │ ├── after-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── all/
│ │ │ ├── after-only/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── before-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── bad-arg-action/
│ │ │ ├── empty-command-list/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── empty-string-command/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── before-after-and-error-merge/
│ │ │ ├── qa/
│ │ │ │ └── my-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── before-after-and-on-error/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── before-and-after/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── hook.sh
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── before-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── error-hooks/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── terragrunt.hcl
│ │ │ └── tf.sh
│ │ ├── error-hooks-source-download-fail/
│ │ │ └── terragrunt.hcl
│ │ ├── exit-code-error/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── if-parameter/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── init-once/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── base-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── no-source-no-backend/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── no-source-with-backend/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── with-source-no-backend/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── with-source-no-backend-suppress-hook-stdout/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── with-source-with-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── interpolations/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── one-arg-action/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── path-preservation/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── skip-on-error/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── working_dir/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── mydir/
│ │ │ └── hello_world
│ │ └── terragrunt.hcl
│ ├── include/
│ │ ├── qa/
│ │ │ └── my-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── stage/
│ │ └── my-app/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── include-deep/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── include-expose/
│ │ ├── mixed-with-bare/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ ├── single/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── single-bare/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── terragrunt_env.hcl
│ │ ├── with-dependency/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── with-dependency-reference-input/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── include-multiple/
│ │ ├── deep-merge-nonoverlapping/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── deep-merge-overlapping/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── expose/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── has-bare-include/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── json/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── modules/
│ │ │ ├── empty/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── reflect/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── shallow-deep-merge-overlapping/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── shallow-merge/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── terragrunt_inputs.hcl
│ │ ├── terragrunt_inputs_final.hcl
│ │ ├── terragrunt_inputs_override.hcl
│ │ ├── terragrunt_vpc_dep.hcl
│ │ ├── terragrunt_vpc_dep_for_expose.hcl
│ │ └── terragrunt_vpc_dep_override.hcl
│ ├── include-parent/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── common.hcl
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── parent.hcl
│ ├── include-runall/
│ │ ├── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── alpha.hcl
│ │ ├── b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── init-cache/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── init-error/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── init-once/
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── inputs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── inputs-defaults/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── inputs-interpolation/
│ │ ├── main.tf
│ │ ├── stuff.json
│ │ └── terragrunt.hcl
│ ├── list/
│ │ ├── basic/
│ │ │ ├── a-unit/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── b-unit/
│ │ │ └── terragrunt.hcl
│ │ ├── dag/
│ │ │ ├── stacks/
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── live/
│ │ │ ├── dev/
│ │ │ │ ├── db/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── prod/
│ │ │ ├── db/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── ec2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ └── long/
│ │ ├── unit-0/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-1/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-2/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-3/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-4/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-5/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-6/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-7/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-8/
│ │ │ └── terragrunt.hcl
│ │ └── unit-9/
│ │ └── terragrunt.hcl
│ ├── locals/
│ │ ├── canonical/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── contents.txt
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── local-in-include/
│ │ │ ├── qa/
│ │ │ │ └── my-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── run-multiple/
│ │ │ └── terragrunt.hcl
│ │ └── run-once/
│ │ └── terragrunt.hcl
│ ├── locals-errors/
│ │ ├── undefined-local/
│ │ │ └── terragrunt.hcl
│ │ └── undefined-local-but-input/
│ │ └── terragrunt.hcl
│ ├── log/
│ │ ├── formatter/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── levels/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── rel-paths/
│ │ └── duplicate-dir-names/
│ │ └── workspace/
│ │ └── one/
│ │ └── two/
│ │ ├── aaa/
│ │ │ └── bbb/
│ │ │ └── ccc/
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── workspace/
│ │ │ └── terragrunt.hcl
│ │ └── tf/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── manifest/
│ │ ├── version-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── stale.tf
│ │ ├── version-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── version-3-subfolder/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── sub/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── version-4-subfolder-empty/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── version-5-not-empty-subfolder/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── sub2/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── manifest-removal/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── missing-dependencies/
│ │ ├── main/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── module-a/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── mixed-config/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── stack/
│ │ │ └── terragrunt.stack.hcl
│ │ └── unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── module-path-in-error/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── d1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── provider.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── modules/
│ │ ├── hcl-module-b/
│ │ │ ├── module-b-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl.json
│ │ ├── hcl-module-c/
│ │ │ └── terragrunt.hcl
│ │ ├── json-module-a/
│ │ │ └── terragrunt.hcl.json
│ │ ├── json-module-b/
│ │ │ ├── module-b-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── root.hcl
│ │ ├── json-module-c/
│ │ │ └── terragrunt.hcl.json
│ │ ├── json-module-d/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl.json
│ │ ├── module-a/
│ │ │ └── terragrunt.hcl
│ │ ├── module-abba/
│ │ │ └── terragrunt.hcl
│ │ ├── module-b/
│ │ │ ├── module-b-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── module-c/
│ │ │ └── terragrunt.hcl
│ │ ├── module-d/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-e/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── module-e-child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── module-f/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-g/
│ │ │ └── terragrunt.hcl
│ │ ├── module-h/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-i/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── terragrunt.hcl
│ │ │ └── test.tf
│ │ ├── module-j/
│ │ │ └── terragrunt.hcl
│ │ ├── module-k/
│ │ │ └── terragrunt.hcl
│ │ ├── module-l/
│ │ │ └── terragrunt.hcl
│ │ ├── module-m/
│ │ │ ├── env.hcl
│ │ │ ├── module-m-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── terragrunt.hcl
│ │ │ │ └── tier.hcl
│ │ │ └── root.hcl
│ │ └── module-missing-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── multiinclude-dependency/
│ │ ├── depa/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depa.hcl
│ │ ├── depb/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depb.hcl
│ │ ├── depc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depc.hcl
│ │ ├── main/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── no-color/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── no-color-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── terragrunt.hcl
│ │ └── y/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── no-submodules/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── null-values/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── out-dir/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── output-all/
│ │ ├── env1/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── output-from-dependency/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── terragrunt.hcl
│ │ └── variables.tf
│ ├── output-from-remote-state/
│ │ ├── env1/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── terragrunt.hcl
│ │ │ │ └── variables.tf
│ │ │ └── app3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── output-module-groups/
│ │ └── root/
│ │ ├── backend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── frontend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mysql/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── redis/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── parallel-run/
│ │ ├── .tflint.hcl
│ │ ├── common/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── dev/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── parallel-state-init/
│ │ ├── root.hcl
│ │ └── template/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── parallelism/
│ │ ├── template/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── parent-folders/
│ │ ├── in-another-subfolder/
│ │ │ ├── common/
│ │ │ │ └── foo.txt
│ │ │ └── live/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-terragrunt-in-parents/
│ │ │ ├── child/
│ │ │ │ ├── root.hcl
│ │ │ │ └── sub-child/
│ │ │ │ ├── root.hcl
│ │ │ │ └── sub-sub-child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── no-terragrunt-in-root/
│ │ │ └── child/
│ │ │ └── sub-child/
│ │ │ └── terragrunt.hcl
│ │ ├── other-file-names/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── foo.txt
│ │ ├── terragrunt-in-root/
│ │ │ ├── child/
│ │ │ │ └── sub-child/
│ │ │ │ └── sub-sub-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── override/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── with-params/
│ │ └── tfwork/
│ │ ├── test-var/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── providers.tf
│ │ └── tg/
│ │ └── terragrunt.hcl
│ ├── parsing/
│ │ └── exposed-include-with-deprecated-inputs/
│ │ ├── child/
│ │ │ └── terragrunt.hcl
│ │ ├── compcommon.hcl
│ │ ├── dep/
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── partial-parse/
│ │ ├── ignore-bad-block-in-parent/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── partial-inheritance/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── terragrunt-version-constraint/
│ │ └── terragrunt.hcl
│ ├── planfile-order-test/
│ │ ├── .gitignore
│ │ ├── .terraform.lock.hcl
│ │ ├── inputs.tf
│ │ ├── resource.tf
│ │ ├── terragrunt.hcl
│ │ └── vars/
│ │ └── variables.tfvars
│ ├── prevent-destroy-not-set/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── prevent-destroy-override/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── private-registry/
│ │ ├── env.tfrc
│ │ └── terragrunt.hcl
│ ├── provider-cache/
│ │ ├── dependency/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dep/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── direct/
│ │ │ ├── .gitignore
│ │ │ ├── first/
│ │ │ │ ├── app/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app1/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app2/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app4/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app5/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app6/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app7/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app8/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── app9/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── second/
│ │ │ ├── app/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app1/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app4/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app5/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app6/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app7/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app8/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app9/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── filesystem-mirror/
│ │ │ └── app/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-platforms/
│ │ │ ├── .gitignore
│ │ │ ├── app1/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app3/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── network-mirror/
│ │ │ └── apps/
│ │ │ ├── app0/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app1/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── weak-constraint/
│ │ ├── .gitignore
│ │ └── app/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── queue-strict-include/
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── transitive-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── queue-strict-include-units-reading/
│ │ ├── live/
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── sources/
│ │ └── source.hcl
│ ├── read-config/
│ │ ├── from_dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── terragrunt.hcl
│ │ │ │ └── vars.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── full/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── source.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── iam_role_in_file/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── iam_roles_multiple_modules/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── component1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── component2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── with_constraints/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── with_default/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── with_dependency/
│ │ │ ├── dep/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ └── with_original_terragrunt_dir/
│ │ ├── .terraform.lock.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── foo/
│ │ │ └── bar.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── read-tf-vars/
│ │ ├── empty.tfvars
│ │ ├── my.tfvars
│ │ ├── my.tfvars.json
│ │ ├── only-comments.tfvars
│ │ └── terragrunt.hcl
│ ├── regressions/
│ │ ├── 5195-scope-escape/
│ │ │ ├── bastion/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── accesslogging-bucket/
│ │ │ ├── no-target-prefix-input/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── remote_terragrunt.hcl
│ │ │ └── with-target-prefix-input/
│ │ │ ├── .gitignore
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── remote_terragrunt.hcl
│ │ ├── apply-all-envvar/
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── no-require-envvar/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── require-envvar/
│ │ │ └── terragrunt.hcl
│ │ ├── benchmark-parsing/
│ │ │ ├── modules/
│ │ │ │ └── dummy-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── variables.tf
│ │ │ │ └── versions.tf
│ │ │ ├── production/
│ │ │ │ ├── dependency-group-template/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── deployment-group-1/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── environment.hcl
│ │ │ └── root-terragrunt.hcl
│ │ ├── benchmark-parsing-includes/
│ │ │ ├── modules/
│ │ │ │ └── dummy-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── variables.tf
│ │ │ │ └── versions.tf
│ │ │ ├── production/
│ │ │ │ ├── dependency-group-template/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── deployment-group-1/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── environment.hcl
│ │ │ └── root-terragrunt.hcl
│ │ ├── dependency-empty-config-path/
│ │ │ ├── _source/
│ │ │ │ └── units/
│ │ │ │ └── consumer/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── live/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── dependency-generate/
│ │ │ ├── modules/
│ │ │ │ ├── other-module/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── test-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── other/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── testing/
│ │ │ └── terragrunt.hcl
│ │ ├── dependency-include-error/
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── layer.hcl
│ │ │ ├── root.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── disabled-dependency-empty-config-path/
│ │ │ ├── modules/
│ │ │ │ └── id/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── root.hcl
│ │ │ ├── unit-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit-b/
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-dependency/
│ │ │ ├── amazing-app/
│ │ │ │ └── k8s/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── clusters/
│ │ │ │ └── eks/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── modules/
│ │ │ │ ├── eks/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── k8s/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── root.hcl
│ │ │ └── testapp/
│ │ │ └── k8s/
│ │ │ └── terragrunt.hcl
│ │ ├── include-error/
│ │ │ ├── _envcommon.hcl
│ │ │ └── project/
│ │ │ ├── app/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── eng_teams.hcl
│ │ ├── mocks-merge-with-state/
│ │ │ ├── deep-map/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── shallow/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-dependency-load-sync/
│ │ │ ├── dep1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── main/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── modules/
│ │ │ │ └── dummy-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── variables.tf
│ │ │ │ └── versions.tf
│ │ │ └── root-terragrunt.hcl
│ │ ├── multiple-stacks/
│ │ │ ├── live/
│ │ │ │ ├── appv2.terragrunt.stack.hcl
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── template/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── not-existing-dependency/
│ │ │ ├── invalid-path/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── parent-find-fail/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── parsing-run-all-with-generate/
│ │ │ ├── root.hcl
│ │ │ ├── services/
│ │ │ │ └── test1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── services-info/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── run-cmd-include-output/
│ │ │ ├── root.hcl
│ │ │ ├── scripts/
│ │ │ │ └── emit_output.sh
│ │ │ ├── unit-a/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit-b/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── sensitive-values/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── dev.enc.yaml
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── skip-init/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── skip-versioning/
│ │ │ ├── .gitignore
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── local_terragrunt.hcl
│ │ │ ├── main.tf
│ │ │ └── remote_terragrunt.hcl
│ │ └── yamldecode/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── relative-include-cmd/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── app.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt-test.hcl
│ ├── render-json/
│ │ ├── common_vars.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── main/
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── render-json-inputs/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── render-json-metadata/
│ │ ├── attributes/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependencies/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── include.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependency1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dependency2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependency/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependency/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dependency2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── includes/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── generate.hcl
│ │ │ │ ├── inputs.hcl
│ │ │ │ ├── locals.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── common/
│ │ │ └── common.hcl
│ │ └── terraform-remote-state/
│ │ ├── app/
│ │ │ └── terragrunt.hcl
│ │ ├── common/
│ │ │ ├── remote_state.hcl
│ │ │ └── terraform.hcl
│ │ └── terraform/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── render-json-mock-outputs/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── render-json-regression/
│ │ ├── bar/
│ │ │ └── terragrunt.hcl
│ │ ├── baz/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── render-json-with-encryption/
│ │ ├── common_vars.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── main/
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── report/
│ │ ├── chain-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── chain-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── chain-c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── error-ignore/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-early-exit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-exclude/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-failure/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-success/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── retry-success/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── second-early-exit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── second-exclude/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── second-failure/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── second-success/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── root-terragrunt-hcl-regression/
│ │ ├── bar/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── baz/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── run-cmd-flags/
│ │ ├── module-conflict/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-global-cache-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-global-cache-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-no-cache/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-quiet/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── scripts/
│ │ ├── .gitignore
│ │ ├── emit_secret.sh
│ │ ├── global_counter.sh
│ │ └── no_cache_counter.sh
│ ├── run-filter/
│ │ ├── cache/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── db/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── service/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── runner-pool-remote-source/
│ │ ├── unit-a/
│ │ │ └── terragrunt.hcl
│ │ └── unit-b/
│ │ └── terragrunt.hcl
│ ├── s3-backend/
│ │ ├── common.hcl
│ │ ├── dual-locking/
│ │ │ └── terragrunt.hcl
│ │ ├── unit1/
│ │ │ └── terragrunt.hcl
│ │ ├── unit2/
│ │ │ └── terragrunt.hcl
│ │ └── use-lockfile/
│ │ └── terragrunt.hcl
│ ├── s3-backend-disable-init/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── s3-backend-migrate/
│ │ ├── unit1/
│ │ │ └── terragrunt.hcl
│ │ └── unit2/
│ │ └── terragrunt.hcl
│ ├── s3-encryption/
│ │ ├── basic-encryption/
│ │ │ └── terragrunt.hcl
│ │ ├── custom-key/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── sse-aes/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── sse-kms/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── s3-errors/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── scaffold/
│ │ ├── catalog-config-test/
│ │ │ └── terragrunt.hcl
│ │ ├── custom-default-template/
│ │ │ ├── root.hcl
│ │ │ └── unit/
│ │ │ └── .gitkeep
│ │ ├── dependency-prompt-template/
│ │ │ ├── .boilerplate/
│ │ │ │ └── boilerplate.yml
│ │ │ ├── base/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── test.hcl
│ │ │ └── leaf/
│ │ │ ├── boilerplate.yml
│ │ │ └── terragrunt.hcl
│ │ ├── external-template/
│ │ │ ├── dependency/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── dependency.txt
│ │ │ └── template/
│ │ │ ├── boilerplate.yml
│ │ │ ├── external-template.txt
│ │ │ └── terragrunt.hcl
│ │ ├── module-with-template/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ ├── template-file.txt
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── root-hcl/
│ │ │ ├── root.hcl
│ │ │ └── unit/
│ │ │ └── .gitkeep
│ │ ├── scaffold-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── variables.tf
│ │ ├── scaffold-module-tofu/
│ │ │ ├── main.tofu
│ │ │ └── variables.tofu
│ │ ├── with-hooks/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── with-shell-and-hooks/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── with-shell-commands/
│ │ ├── .boilerplate/
│ │ │ ├── boilerplate.yml
│ │ │ └── terragrunt.hcl
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── skip/
│ │ ├── base-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── skip-false/
│ │ │ ├── resource1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── resource2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── skip-true/
│ │ ├── resource1/
│ │ │ └── terragrunt.hcl
│ │ ├── resource2/
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── skip-dependencies/
│ │ ├── first/
│ │ │ ├── foo.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── second/
│ │ └── terragrunt.hcl
│ ├── skip-legacy-root/
│ │ ├── base-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── skip-false/
│ │ │ ├── resource1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── resource2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ └── skip-true/
│ │ ├── resource1/
│ │ │ └── terragrunt.hcl
│ │ ├── resource2/
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── sops/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── secrets.env
│ │ ├── secrets.ini
│ │ ├── secrets.json
│ │ ├── secrets.txt
│ │ ├── secrets.yaml
│ │ ├── terragrunt.hcl
│ │ └── test_pgp_key.asc
│ ├── sops-errors/
│ │ ├── .terraform.lock.hcl
│ │ ├── file.yaml
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── sops-kms/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── secrets.env
│ │ ├── secrets.ini
│ │ ├── secrets.json
│ │ ├── secrets.txt
│ │ ├── secrets.yaml
│ │ └── terragrunt.hcl
│ ├── sops-missing/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── source-map/
│ │ ├── modules/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── vpc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── multiple-match/
│ │ │ ├── terragrunt-vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terratest-vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-only-one-match/
│ │ │ ├── terragrunt-vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terratest-vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-with-dependency/
│ │ │ ├── app/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-with-dependency-same-url/
│ │ │ ├── app/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── single/
│ │ │ └── terragrunt.hcl
│ │ └── slashes-in-ref/
│ │ └── terragrunt.hcl
│ ├── stack/
│ │ ├── disjoint/
│ │ │ ├── a/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── b/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── disjoint-symlinks/
│ │ │ ├── a/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── mgmt/
│ │ │ ├── bastion-host/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── kms-master-key/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── stage/
│ │ ├── backend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── frontend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mysql/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── redis/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── search-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── example-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── stacks/
│ │ ├── all-no-stack-dir/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── basic/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── chick/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── chicken/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── father/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── mother/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── coexist-hcl-and-stack/
│ │ │ ├── modules/
│ │ │ │ └── test/
│ │ │ │ └── main.tf
│ │ │ ├── non-prod/
│ │ │ │ └── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ └── test/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── test/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependencies/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app-with-dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── errors/
│ │ │ ├── absolute-path/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── cycles/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── stack/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── unit/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── incorrect-source/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── locals-error/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── not-existing-path/
│ │ │ │ └── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── relative-path-outside-of-stack/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── stack-empty-path/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── unit-empty-path/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unknown-value/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── bad-unit/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── validation-stack/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── stacks/
│ │ │ │ │ └── v1/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── validation-unit/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── v1/
│ │ │ ├── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── db/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── web/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── find-in-parent-folders/
│ │ │ ├── live/
│ │ │ │ └── stack/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── mock.hcl
│ │ │ └── units/
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── get-original-terragrunt-dir/
│ │ │ ├── live/
│ │ │ │ ├── account1/
│ │ │ │ │ ├── no-locals-nested/
│ │ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ ├── read-config/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ └── with-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ ├── non-nested/
│ │ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ ├── read-config/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ └── with-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ ├── read-config-nested/
│ │ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ ├── read-config/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ └── with-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ └── with-locals-nested/
│ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ ├── read-config/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ └── with-locals/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── common/
│ │ │ │ └── stack_config.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── no-locals/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── read-config/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── with-locals/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── terragrunt.hcl
│ │ ├── inputs/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── locals/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── chick/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── chicken/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── father/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── mother/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-stacks/
│ │ │ ├── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── nested/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── live-v2/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── db/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── web/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── nested-outputs/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── v1/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── v2/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── v3/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-dot-terragrunt-stack-output/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-stack/
│ │ │ ├── config/
│ │ │ │ └── config.txt
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ └── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── db/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── web/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-stack-dir/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-validation/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ └── stack1/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app1/
│ │ │ └── code/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── outputs/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── read-stack/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── remote/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── self-include/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit/
│ │ │ └── terragrunt.hcl
│ │ ├── source-map/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── tf/
│ │ │ │ └── modules/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── units/
│ │ │ └── app/
│ │ │ └── terragrunt.hcl
│ │ ├── stack-values/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── terragrunt-dir/
│ │ │ ├── live/
│ │ │ │ ├── root.hcl
│ │ │ │ └── tennant_1/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit_a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-values/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── version-constraints/
│ │ ├── live/
│ │ │ └── terragrunt.stack.hcl
│ │ └── unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── startswith/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── strcontains/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── streaming/
│ │ ├── unit1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── strict-bare-include/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── parent.hcl
│ │ └── terragrunt.hcl
│ ├── terragrunt-info-error/
│ │ ├── module-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│
================================================
FILE CONTENTS
================================================
================================================
FILE: .coderabbit.yaml
================================================
# https://docs.coderabbit.ai/guides/configure-coderabbit
language: "en-US"
early_access: false
chat: { auto_reply: true }
reviews:
profile: chill
high_level_summary: true
poem: false
collapse_walkthrough: true
sequence_diagrams: true
path_instructions:
- path: 'docs/**/*.md'
instructions: >-
Review the documentation for clarity, grammar, and spelling.
Make sure that the documentation is easy to understand and follow.
There is currently a migration underway from the Jekyll based documentation in `docs` to the Starlight + Astro based documentation in `docs`. Whenever changes are made to the `docs` directory, ensure that an equivalent change is made in the `docs` directory to keep the `docs` documentation accurate.
- path: 'docs/**/*.md*'
instructions: >-
Review the documentation for clarity, grammar, and spelling.
Make sure that the documentation is easy to understand and follow.
There is currently a migration underway from the Jekyll based documentation in `docs` to the Starlight + Astro based documentation in `docs`. Make sure that the `docs` documentation is accurate and up-to-date with the `docs` documentation, and that any difference between them results in an improvement in the `docs` documentation.
- path: 'docs/**/*.astro'
instructions: >-
Review the Astro code in the `docs` directory for quality and correctness.
Make sure that the Astro code follows best practices and is easy to understand, maintain, and follows best practices.
When possible, suggest improvements to the Astro code to make it better.
- path: '**/*.go'
instructions: >-
Review the Go code for quality and correctness.
Make sure that the Go code follows best practices, is performant, and is easy to understand and maintain.
tools:
languagetool:
enabled: true
level: default
================================================
FILE: .codespellrc
================================================
[codespell]
skip = go.mod,go.sum,*.svg,Gemfile.lock,bun.lock,package-lock.json,node_modules,dist
ignore-words-list = dRan,implementors
================================================
FILE: .gitattributes
================================================
# Ensure golden test files are not treated as text files to prevent line ending conversions
*.golden -text
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: gruntwork-io
================================================
FILE: .github/ISSUE_TEMPLATE/01-bug_report.md
================================================
---
name: Bug report
about: Create a bug report to help us improve Terragrunt.
title: ''
labels: bug
assignees: ''
---
## Describe the bug
A clear and concise description of what the bug is.
## Reproducing bugs
It is vital when reporting bugs that you provide the exact steps that _anyone_ would be able to follow to reproduce the bug you are seeing.
Without this information, it is much less likely that maintainers will invest time in investigating and fixing the bug, and maintainers may not know if they have actually fixed the bug once a fix is made.
The exceptions to requiring steps to reproduce are:
1. You are reporting a bug that you don't know how to reproduce, but you are reporting it so that others in the community are aware of it.
2. You are willing to fix the bug yourself, and you accept the responsibility of ensuring that the bug is valid, and that the fix is well tested.
How to provide steps for reproduction:
The most common way to provide steps for reproduction is to create a minimal example that reproduces the bug, and steps to run that example to reproduce the issue. Maintainers will refer to this example as a "fixture" when asking questions about reproduction.
You can either do so with code snippets in this issue, or by creating a public Git repository that contains the minimal example, with instructions for running the example.
You can delete this section right before submitting the issue, if you like.
## Steps To Reproduce
Steps to reproduce the behavior, code snippets and examples which can be used to reproduce the issue.
Be sure that the maintainers can actually reproduce the issue. Bug reports that are too vague or hard to reproduce are hard to troubleshoot and fix.
```hcl
// paste code snippets here
```
## Expected behavior
A clear and concise description of what you expected to happen.
## Must haves
- [ ] Steps for reproduction provided.
## Nice to haves
- [ ] Terminal output
- [ ] Screenshots
## Versions
- Terragrunt version:
- OpenTofu/Terraform version:
- Environment details (Ubuntu 20.04, Windows 10, etc.):
## Additional context
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/02-bad_error_message.md
================================================
---
name: Bad Error Message Report
about: Report an error message that is unclear, unhelpful, or confusing to users.
title: ''
labels:
- bug
- error-message
assignees: ''
---
## Error Message Details
### The Error Message
Please paste the exact error message you received:
```bash
// Paste the complete error message here
```
## Why This Error Message is Unhelpful
### Current Problems
Please explain why this error message is not helpful.
## Recommended Improvement
### What the Error Message Should Say
Please suggest how the error message could be improved:
```bash
// Example of what a better error message might look like
```
## Error Reproduction Steps
Provide the exact steps required for _anyone_ to successfully reproduce the error.
This includes the Terragrunt command and any relevant configuration files required to reproduce the error. If you need a large amount of Terragrunt configuration to reproduce the error, consider creating a minimal reproduction repository.
### Steps to Reproduce
1.
2.
3.
## Environment Information
- **Terragrunt version**:
- **OpenTofu/Terraform version**:
- **Operating system**:
## Additional Context
Any other information that might help improve the error message.
================================================
FILE: .github/ISSUE_TEMPLATE/03-rfc.yml
================================================
# Inspired by:
# - The previous RFC template.
# - the OpenTofu RFC template: https://raw.githubusercontent.com/opentofu/opentofu/main/.github/ISSUE_TEMPLATE/rfc.yml
name: RFC
description: Submit a Request For Comments (RFC) to significantly change Terragrunt.
labels: ["rfc", "pending-decision"]
body:
- type: markdown
attributes:
value: |
# Request For Comments
This form will guide you through the process for submitting a Request For Comments (RFC) for a change.
## Before you start
- Make sure you search for an issue that would already cover your RFC in the [issues tab](https://github.com/gruntwork-io/terragrunt/issues?q=is%3Aissue).
- Search through [Terragrunt documentation](https://docs.terragrunt.com/) to see if your RFC is already supported.
## After you submit
- Share your RFC with your community for feedback and reactions! The more activity and feedback you get, the more likely it is to be reviewed by the maintainers.
- If your RFC has enough traction, it will be reviewed by the maintainers and a decision will be made.
- Once a decision is made, one of two things will happen:
1. If the RFC is accepted, the `pending-decision` label will be replaced with the `accepted` label. At this stage, pull requests can be submitted by maintainers or the community to implement the RFC, with a description including `Closes #<RFC number>`.
2. If the RFC is rejected, the `pending-decision` label will be replaced with the `rejected` label. The maintainers will provide a reason for the rejection. If applicable, it might be made clear that a new RFC with changes is welcome.
- type: textarea
id: summary
attributes:
label: Summary
description: A brief summary of the RFC.
validations:
required: true
- type: textarea
id: motivation
attributes:
label: Motivation
description: What is the problem you're trying to solve? What are the goals you're trying to achieve?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposal
description: |
In a manner that is as specific as possible, describe the proposal you have in mind. This should include:
- As minimally technical a description of the proposal as possible.
- An explanation of how the proposal addresses the motivation above.
- Examples of how the proposal might present itself to a user if implemented.
validations:
required: true
- type: textarea
id: technical-details
attributes:
label: Technical Details
description: |
Provide technical details for the proposal. This should include:
- List of components that will be affected by the proposal.
- How those components will be affected.
- Any documentation that will help in understanding or developing a solution to the proposal.
validations:
required: true
- type: textarea
id: press-release
attributes:
label: Press Release
description: If this RFC were implemented, how would you describe it to the community in a mock press release?
validations:
required: true
- type: textarea
id: drawbacks
attributes:
label: Drawbacks
description: What are the drawbacks of the proposal, if any?
validations:
required: false
- type: textarea
id: alternatives
attributes:
label: Alternatives
description: What are the alternatives to the proposal, if any?
validations:
required: false
- type: textarea
id: migration-strategy
attributes:
label: Migration Strategy
description: If this proposal requires a migration strategy for existing code bases, what is it?
validations:
required: false
- type: textarea
id: unresolved-questions
attributes:
label: Unresolved Questions
description: |
What parts of the proposal are still unresolved?
- Is there anything that you're unsure about?
- Are there any questions that you have that you haven't answered yet?
- Would you like to encourage feedback on any particular part of the proposal you haven't fully fleshed out?
validations:
required: false
- type: textarea
id: references
attributes:
label: References
description: |
Are there any references that should be linked here?
- Links to other RFCs, issues, or documentation.
validations:
required: false
- type: textarea
id: poc-pull-request
attributes:
label: Proof of Concept Pull Request
description: If you have a proof of concept or an in-draft pull request that demonstrates the proposal, please link it here.
validations:
required: false
- type: checkboxes
id: support
attributes:
label: Support Level
description: Please let us know if you are a paying customer. This helps us prioritize RFCs that are important to our customers.
options:
- label: I have Terragrunt Enterprise Support
required: false
- label: I am a paying Gruntwork customer
required: false
- type: input
id: customer-name
attributes:
label: Customer Name
description: If you are a paying Gruntwork customer, please provide your name.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/04-feature-request.md
================================================
---
name: Enhancement
about: Request a simple feature or enhancement.
title: ''
labels: enhancement
assignees: ''
---
## Describe the enhancement
A clear and concise description of what the enhancement is.
## Additional context
Add any other context about the enhancement here.
Things you might want to address include:
- [ ] Changes required.
- [ ] Implications of the feature.
- [ ] Alternatives considered.
- [ ] Level of effort.
## PoC (Proof of Concept)
Link to a Proof of Concept if you have one:
- [ ] [PoC]()
Including a PoC can help others understand the feature better and implement it faster.
## RFC Not Needed
- [ ] I have evaluated the complexity of this enhancement, and I believe it does not require an RFC.
================================================
FILE: .github/assets/release-assets-config.json
================================================
{
"platforms": [
{
"os": "darwin",
"arch": "amd64",
"signed": true,
"binary": "terragrunt_darwin_amd64"
},
{
"os": "darwin",
"arch": "arm64",
"signed": true,
"binary": "terragrunt_darwin_arm64"
},
{
"os": "linux",
"arch": "386",
"signed": false,
"binary": "terragrunt_linux_386"
},
{
"os": "linux",
"arch": "amd64",
"signed": false,
"binary": "terragrunt_linux_amd64"
},
{
"os": "linux",
"arch": "arm64",
"signed": false,
"binary": "terragrunt_linux_arm64"
},
{
"os": "windows",
"arch": "386",
"signed": false,
"binary": "terragrunt_windows_386.exe"
},
{
"os": "windows",
"arch": "amd64",
"signed": true,
"binary": "terragrunt_windows_amd64.exe"
}
],
"archive_formats": [
{
"extension": "zip",
"description": "ZIP archive"
},
{
"extension": "tar.gz",
"description": "TAR.GZ archive"
}
],
"additional_files": [
{
"name": "SHA256SUMS",
"description": "Checksums for all files"
},
{
"name": "SHA256SUMS.gpgsig",
"description": "GPG detached signature"
},
{
"name": "SHA256SUMS.sigstore.json",
"description": "Cosign sigstore bundle"
},
{
"name": "SHA256SUMS.sig",
"description": "Cosign signature (legacy)"
},
{
"name": "SHA256SUMS.pem",
"description": "Cosign certificate (legacy)"
},
{
"name": "terragrunt-signing-key.asc",
"description": "GPG public key for signature verification"
}
]
}
================================================
FILE: .github/cloud-nuke/config.yml
================================================
s3:
timeout: 1h
include:
names_regex:
- "^terragrunt-test-bucket-[a-zA-Z0-9]{6}.*"
vpc:
include:
name_regex:
- "^vpc-.*"
- "^step-.*"
ec2:
include:
name_regex:
- "^single-instance$"
dynamodb:
include:
table_names_regex:
- "^terragrunt-test.*"
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
groups:
go-dependencies:
patterns:
- "*"
labels:
- "go"
- "dependencies"
ignore:
- dependency-name: "github.com/charmbracelet/glamour"
versions: ["<= 0.10.1"]
- dependency-name: "github.com/charmbracelet/x/ansi"
# https://github.com/charmbracelet/bubbletea/issues/1448#issuecomment-3105363044
- package-ecosystem: "bun"
directories:
- "**/*"
schedule:
interval: "weekly"
groups:
js-dependencies:
patterns:
- "*"
labels:
- "javascript"
- "dependencies"
ignore:
- dependency-name: "@astrojs/starlight"
# Custom patch applied - manual updates required
# When updating, you have to manually update the patch in the docs/package.json
================================================
FILE: .github/pull_request_template.md
================================================
<!-- Prepend '[WIP]' to the title if this PR is still a work-in-progress. Remove it when it is ready for review! -->
## Description
Fixes #000.
<!-- Description of the changes introduced by this PR. -->
## TODOs
Read the [Gruntwork contribution guidelines](https://gruntwork.notion.site/Gruntwork-Coding-Methodology-02fdcd6e4b004e818553684760bf691e).
- [ ] I authored this code entirely myself
- [ ] I am submitting code based on open source software (e.g. MIT, MPL-2.0, Apache)]
- [ ] I am adding or upgrading a dependency or adapted code and confirm it has a compatible open source license
- [ ] Update the docs.
- [ ] Run the relevant tests successfully, including pre-commit checks.
- [ ] Include release notes. If this PR is backward incompatible, include a migration guide.
## Release Notes (draft)
<!-- One-line description of the PR that can be included in the final release notes. -->
Added / Removed / Updated [X].
### Migration Guide
<!-- Important: If you made any backward incompatible changes, then you must write a migration guide! -->
================================================
FILE: .github/scripts/announce-release.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
URL="${URL:?Required environment variable URL}"
REPO="${REPO:?Required environment variable REPO}"
TAG_NAME="${TAG_NAME:?Required environment variable TAG_NAME}"
ROLE_ID="${ROLE_ID:?Required environment variable ROLE_ID}"
USERNAME="${USERNAME:?Required environment variable USERNAME}"
AVATAR_URL="${AVATAR_URL:?Required environment variable AVATAR_URL}"
if RELEASE_JSON=$(gh -R "$REPO" release view "$TAG_NAME" --json body --json url --json name); then
RELEASE_NOTES_LENGTH=$(jq '.body | length' <<<"$RELEASE_JSON")
RELEASE_NOTES=$(jq '.body' <<<"$RELEASE_JSON")
# This math is a little weird.
# We have a budget of 200 characters for everything we add around the release notes.
# We also lower the budget by 3 characters for the ellipsis we add at the end when truncating.
# So, it's 2000 characters for the release notes,
# minus 200 characters for everything else,
# minus 3 characters for the ellipsis
# = 1797 characters.
if [[ "$RELEASE_NOTES_LENGTH" -gt 1800 ]]; then
echo "Release notes are too long ($RELEASE_NOTES_LENGTH characters), truncating to 1797 characters, truncating the last line, then appending '…'"
RELEASE_NOTES=$(jq '.body |= .[:1797]' <<<"$RELEASE_JSON" | jq '.body | split("\r\n") | del(.[-1]) | join("\r\n")' | jq '. + "\r\n…"')
fi
PAYLOAD=$(
jq \
--argjson release_notes "$RELEASE_NOTES" \
--arg username "$USERNAME" \
--arg avatar_url "$AVATAR_URL" \
-cn '{"content": $release_notes, username: $username, avatar_url: $avatar_url, "flags": 4}'
)
tmpfile=$(mktemp)
jq '.content = "'"<@&$ROLE_ID> $(jq -r '.name' <<<"$RELEASE_JSON")\n"'>>> " + .content + "'"\n\n**[View release on GitHub]($(jq -r '.url' <<<"$RELEASE_JSON"))**"'"' <<<"$PAYLOAD" >"$tmpfile"
jq '.content' <"$tmpfile"
curl -X POST \
--data-binary "@$tmpfile" \
-H "Content-Type: application/json" \
"$URL"
fi
================================================
FILE: .github/scripts/gopls/check-for-changes.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
: "${HAS_FIXES:?}"
if [[ "$HAS_FIXES" != "true" ]]; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if git diff --staged --quiet; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "has_changes=true" >> "$GITHUB_OUTPUT"
================================================
FILE: .github/scripts/gopls/create-issue.js
================================================
const fs = require('fs');
/**
* Creates a GitHub issue for gopls quickfix problems found
* @param {Object} params - Parameters object
* @param {Object} params.github - GitHub API client
* @param {Object} params.context - GitHub Actions context
* @param {Object} params.core - GitHub Actions core utilities
* @param {string} params.fixedFilesPath - Path to the fixed files list
* @param {string} params.outputFilePath - Path to the gopls output file
* @returns {Promise<number>} The created issue number
*/
module.exports = async ({ github, context, core, fixedFilesPath, outputFilePath }) => {
try {
// Read the files that were fixed from provided paths
const fixedFiles = fs.readFileSync(fixedFilesPath, 'utf8');
const goplsOutput = fs.readFileSync(outputFilePath, 'utf8');
const issueBody = `## Gopls Quickfix Issues Found
The monthly gopls quickfix check found issues in the following files:
\`\`\`
${fixedFiles}
\`\`\`
### Details
- **Run Date**: ${new Date().toISOString()}
- **Workflow**: [${context.workflow}](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
- **Commit**: ${context.sha}
### Next Steps
A pull request will be created to address these issues automatically.
### Full Output
<details>
<summary>Click to expand gopls output</summary>
\`\`\`
${goplsOutput}
\`\`\`
</details>
`;
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `🔧 Gopls Quickfix Issues Found - ${new Date().toISOString().split('T')[0]}`,
body: issueBody,
labels: ['gopls', 'automated', 'maintenance']
});
const issueNumber = issue.data.number;
core.setOutput('issue_number', issueNumber);
console.log(`Created issue #${issueNumber}`);
return issueNumber;
} catch (error) {
core.setFailed(`Failed to create issue: ${error.message}`);
throw error;
}
};
================================================
FILE: .github/scripts/gopls/create-pr.js
================================================
const fs = require('fs');
/**
* Creates a GitHub pull request for gopls quickfixes
* @param {Object} params - Parameters object
* @param {Object} params.github - GitHub API client
* @param {Object} params.context - GitHub Actions context
* @param {Object} params.core - GitHub Actions core utilities
* @param {Object} params.exec - GitHub Actions exec utilities
* @param {string} params.issueNumber - The issue number to link to (optional)
* @param {string} params.fixedFilesPath - Path to the fixed files list
* @returns {Promise<number>} The created PR number
*/
module.exports = async ({ github, context, core, exec, issueNumber, fixedFilesPath }) => {
try {
const fixedFiles = fs.readFileSync(fixedFilesPath, 'utf8');
// Configure git
await exec.exec('git', ['config', '--local', 'user.email', 'action@github.com']);
await exec.exec('git', ['config', '--local', 'user.name', 'github-actions[bot]']);
// Create branch name
const branchName = `gopls-quickfix-${new Date().toISOString().split('T')[0].replace(/-/g, '')}`;
// Create and push branch
await exec.exec('git', ['checkout', '-b', branchName]);
await exec.exec('git', ['add', '.']);
await exec.exec('git', ['commit', '-m', '🔧 Apply gopls quickfixes']);
await exec.exec('git', ['push', 'origin', branchName]);
// Create PR
const prBody = `## 🔧 Gopls Quickfixes Applied
This PR applies automatic fixes suggested by gopls for code quality improvements.
> [!TIP]
> You might want to push an empty commit to this PR to trigger CI checks.
### Files Modified
\`\`\`
${fixedFiles}
\`\`\`
### Changes
- Applied gopls quickfixes to improve code quality
- All changes are automated and safe
- Generated by monthly gopls check workflow
### Related Issue
${issueNumber ? `Closes #${issueNumber}` : ''}
---
*This PR was automatically generated by the monthly gopls quickfix workflow.*
`;
const pr = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `🔧 Apply gopls quickfixes - ${new Date().toISOString().split('T')[0]}`,
body: prBody,
head: branchName,
base: 'main',
labels: ['gopls', 'automated', 'maintenance']
});
const prNumber = pr.data.number;
console.log(`Created PR #${prNumber}`);
// Link PR to issue if issue was created
if (issueNumber) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(issueNumber),
body: `🔗 **Pull Request Created**
A pull request has been created to address the gopls quickfix issues found in this issue.
**PR**: #${prNumber}
**Status**: Ready for review
The PR will automatically close this issue when merged.`
});
}
return prNumber;
} catch (error) {
core.setFailed(`Failed to create pull request: ${error.message}`);
throw error;
}
};
================================================
FILE: .github/scripts/gopls/run.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
mise use -g go:golang.org/x/tools/gopls@v0.18.1
gopls version
TEMP_DIR=$(mktemp -d)
FIXED_FILES="$TEMP_DIR/fixed_files.txt"
FAILURES_FILE="$TEMP_DIR/gopls_failures.txt"
OUTPUT_FILE="$TEMP_DIR/gopls_output.txt"
touch "$FIXED_FILES"
touch "$FAILURES_FILE"
touch "$OUTPUT_FILE"
while IFS= read -r file; do
echo "START: $file" | tee -a "$OUTPUT_FILE"
if gopls codeaction -kind=quickfix -write "$file"; then
echo "SUCCESS: $file" | tee -a "$OUTPUT_FILE"
else
echo "FAILED: $file" | tee -a "$FAILURES_FILE" "$OUTPUT_FILE"
echo "$file" >> "$FIXED_FILES"
fi
echo "END: $file" | tee -a "$OUTPUT_FILE"
done < gofiles.txt
printf '\n==== gopls failures (if any) ====\n' | tee -a "$OUTPUT_FILE"
tee -a "$OUTPUT_FILE" < "$FAILURES_FILE" || true
# Check if any files were modified
if [[ -s "$FIXED_FILES" ]]; then
echo "has_fixes=true" >> "$GITHUB_OUTPUT"
echo "Files with fixes:" | tee -a "$OUTPUT_FILE"
tee -a "$OUTPUT_FILE" < "$FIXED_FILES"
else
echo "has_fixes=false" >> "$GITHUB_OUTPUT"
echo "No files were modified by gopls quickfixes" | tee -a "$OUTPUT_FILE"
fi
# Output file paths for other steps to use
echo "fixed_files_path=$FIXED_FILES" >> "$GITHUB_OUTPUT"
echo "output_file_path=$OUTPUT_FILE" >> "$GITHUB_OUTPUT"
================================================
FILE: .github/scripts/release/README.md
================================================
# Release Scripts
This directory contains scripts used by the GitHub Actions release workflow to build, sign, and publish Terragrunt releases.
## Overview
All inline bash and PowerShell code from GitHub Actions workflows has been extracted into these standalone scripts for better:
- **Syntax highlighting** - Proper IDE support
- **Linting** - Can run shellcheck/PSScriptAnalyzer
- **Testing** - Scripts can be tested independently
- **Maintainability** - Easier to update and debug
- **Reusability** - Can be called from multiple workflows
## Script Overview
### Core Library
- **`lib-release-config.sh`** - Helper library to read centralized release configuration from JSON
### General Release Scripts
- **`get-version.sh`** - Extracts and validates version from git tag or workflow input
- **`check-release-exists.sh`** - Checks if GitHub release exists for a version
- **`verify-binaries-downloaded.sh`** - Verifies expected binaries were downloaded from artifacts
- **`set-permissions.sh`** - Sets executable permissions (+x) on all binaries
- **`create-archives.sh`** - Creates ZIP and TAR.GZ archives for each binary
- **`generate-checksums.sh`** - Generates SHA256SUMS file for all release files
- **`verify-files.sh`** - Verifies all required files are present before upload
- **`upload-assets.sh`** - Uploads all assets to GitHub release (with optional --clobber)
- **`verify-assets-uploaded.sh`** - Verifies uploads and retries missing files
- **`generate-upload-summary.sh`** - Generates GitHub Actions step summary with release details
### macOS Signing Scripts
- **`prepare-macos-artifacts.sh`** - Prepares macOS artifacts for signing (filters darwin_* binaries)
- **`install-gon.sh`** - Downloads and installs gon tool for macOS code signing
- **`sign-macos-binaries.sh`** - Signs macOS binaries using gon and Apple notarization
### Windows Signing Scripts
- **`prepare-windows-artifacts.ps1`** - Prepares Windows artifacts for signing
- **`install-go-winres.ps1`** - Installs go-winres tool for patching Windows resources
- **`verify-smctl.ps1`** - Verifies DigiCert smctl tool is installed and accessible
- **`restore-p12-certificate.ps1`** - Restores P12 client certificate from base64 encoding
- **`sign-windows.ps1`** - Config-driven: patches all binaries, signs only those marked `signed: true`
## Centralized Configuration
Release asset configuration is maintained in a single source of truth:
### `../assets/release-assets-config.json`
JSON file defining all platforms, binaries, archive formats, and additional files.
**Schema:**
```json
{
"platforms": [
{
"os": "darwin|linux|windows",
"arch": "386|amd64|arm64",
"signed": true|false,
"binary": "terragrunt_<os>_<arch>[.exe]"
}
],
"archive_formats": [
{
"extension": "zip|tar.gz",
"description": "Format description"
}
],
"additional_files": [
{
"name": "SHA256SUMS",
"description": "File description"
}
]
}
```
### `lib-release-config.sh`
Helper library providing functions to read the centralized configuration.
**Usage:**
```bash
#!/bin/bash
source "$(dirname "$0")/lib-release-config.sh"
# Verify config file exists
verify_config_file
# Get all binary filenames
get_all_binaries
# Get binary count
get_binary_count
# Get total expected file count
get_total_file_count
# Get archive extensions
get_archive_extensions
# Get additional files
get_additional_files
# Get all expected files (binaries + archives + additional)
get_all_expected_files
# Get platform info for specific binary
get_platform_info "terragrunt_darwin_amd64"
# Generate markdown table rows for summary
generate_platform_table_rows
```
**Scripts Using Configuration:**
- `verify-binaries-downloaded.sh` - Uses `get_binary_count()`
- `set-permissions.sh` - Uses `get_all_binaries()`
- `verify-assets-uploaded.sh` - Uses `get_all_expected_files()`, `get_total_file_count()`, `get_binary_count()`
- `generate-upload-summary.sh` - Uses `get_binary_count()`, `get_total_file_count()`, `generate_platform_table_rows()`
## General Scripts
### `get-version.sh`
Extracts version from either workflow dispatch input or git tag.
**Environment Variables:**
- `INPUT_TAG`: Tag provided via workflow_dispatch
- `EVENT_NAME`: GitHub event name (workflow_dispatch or push)
- `GITHUB_REF`: Git reference (e.g., refs/tags/v0.93.4)
- `GITHUB_OUTPUT`: Path to GitHub output file
**Usage:**
```bash
.github/scripts/release/get-version.sh
```
### `check-release-exists.sh`
Checks if a GitHub release exists for a given tag using the GitHub CLI.
**Environment Variables:**
- `VERSION`: The version/tag to check for
- `GH_TOKEN`: GitHub token for authentication
- `GITHUB_OUTPUT`: Path to GitHub output file
**Usage:**
```bash
export VERSION=v0.93.4
export GH_TOKEN=<token>
.github/scripts/release/check-release-exists.sh
```
### `verify-binaries-downloaded.sh`
Verifies all expected binaries were downloaded from build artifacts.
**Parameters:**
- `bin-directory`: Directory containing binaries (default: `bin`)
- `expected-count`: Minimum number of binaries expected (default: `7`)
**Usage:**
```bash
.github/scripts/release/verify-binaries-downloaded.sh bin 7
```
**Features:**
- Lists all downloaded binaries with details
- Counts total files using `find`
- Validates minimum expected count
- Exits with error if count is below threshold
### `set-permissions.sh`
Sets executable permissions (+x) on all Terragrunt binaries.
**Usage:**
```bash
.github/scripts/release/set-permissions.sh bin
```
### `create-archives.sh`
Creates both ZIP and TAR.GZ archives for each binary, preserving execute permissions.
**Usage:**
```bash
.github/scripts/release/create-archives.sh bin
```
**Output:**
- Creates `.zip` and `.tar.gz` for each binary
- ZIP files preserve Unix permissions
- TAR.GZ files natively preserve all file attributes
### `generate-checksums.sh`
Generates SHA256 checksums for all release files (binaries and archives).
**Usage:**
```bash
.github/scripts/release/generate-checksums.sh bin
```
**Output:**
- Creates `SHA256SUMS` file with checksums for all files
### `verify-files.sh`
Verifies all required files are present before upload.
**Usage:**
```bash
.github/scripts/release/verify-files.sh bin
```
**Checks:**
- All platform binaries (macOS, Linux, Windows)
- SHA256SUMS file
### `upload-assets.sh`
Uploads all release assets to an existing GitHub release.
**Environment Variables:**
- `VERSION`: The version/tag to upload to
- `GH_TOKEN`: GitHub token for authentication
**Usage:**
```bash
export VERSION=v0.93.4
export GH_TOKEN=<token>
.github/scripts/release/upload-assets.sh bin
```
### `verify-assets-uploaded.sh`
Verifies all assets were successfully uploaded and retries any missing files.
**Environment Variables:**
- `VERSION`: The version/tag to verify
- `GH_TOKEN`: GitHub token for authentication
- `CLOBBER`: Set to 'true' to overwrite existing assets during retry (default: false)
**Usage:**
```bash
export VERSION=v0.93.4
export GH_TOKEN=<token>
export CLOBBER=false
.github/scripts/release/verify-assets-uploaded.sh bin
```
**Features:**
- Checks for 22 expected files (7 binaries + 7 ZIPs + 7 TAR.GZ + SHA256SUMS)
- Automatically retries failed uploads (max 10 attempts)
- Verifies asset downloadability
### `generate-upload-summary.sh`
Generates a GitHub Actions step summary with release upload details.
**Environment Variables:**
- `VERSION`: Release version/tag
- `RELEASE_ID`: GitHub release ID
- `IS_DRAFT`: Whether release was a draft
- `GITHUB_STEP_SUMMARY`: Path to GitHub step summary file
**Usage:**
```bash
export VERSION=v0.93.4
export RELEASE_ID=123456
export IS_DRAFT=false
export GITHUB_STEP_SUMMARY=$GITHUB_STEP_SUMMARY
.github/scripts/release/generate-upload-summary.sh
```
**Features:**
- Creates formatted markdown summary
- Shows release details (version, ID, draft status)
- Displays platform/architecture table
- Lists archive files and totals
- Always runs (even on failure) via `if: always()` in workflow
## macOS Scripts
### `prepare-macos-artifacts.sh`
Prepares macOS artifacts for signing by copying them from the artifacts directory to the bin directory.
**Usage:**
```bash
.github/scripts/release/prepare-macos-artifacts.sh artifacts bin
```
### `install-gon.sh`
Downloads and installs the gon binary for macOS code signing and notarization.
**Environment Variables:**
- `GON_VERSION`: Version of gon to install (default: v0.0.37)
**Usage:**
```bash
export GON_VERSION=v0.0.37
.github/scripts/release/install-gon.sh
# or pass version as argument
.github/scripts/release/install-gon.sh v0.0.37
```
**Features:**
- Downloads gon from GitHub releases
- Installs to `/usr/local/bin`
- Verifies installation
- Cleans up temporary files
### `sign-macos-binaries.sh`
Signs macOS binaries using gon and Apple notarization service.
**Environment Variables:**
- `AC_PASSWORD`: Apple Connect password
- `AC_PROVIDER`: Apple Connect provider
- `AC_USERNAME`: Apple Connect username
- `MACOS_CERTIFICATE`: macOS certificate in P12 format (base64 encoded)
- `MACOS_CERTIFICATE_PASSWORD`: Certificate password
**Usage:**
```bash
export AC_PASSWORD=<password>
export AC_PROVIDER=<provider>
export AC_USERNAME=<username>
export MACOS_CERTIFICATE=<base64-cert>
export MACOS_CERTIFICATE_PASSWORD=<password>
.github/scripts/release/sign-macos-binaries.sh bin
```
**Process:**
1. Signs amd64 binary using `.gon_amd64.hcl`
2. Signs arm64 binary using `.gon_arm64.hcl`
3. Removes unsigned binaries from bin directory
4. Extracts signed binaries from ZIP archives
5. Moves signed binaries to bin directory (replacing unsigned versions)
6. Verifies signatures using `codesign -dv --verbose=4`
## Windows Scripts
### `prepare-windows-artifacts.ps1`
Prepares Windows artifacts for signing by copying them from the artifacts directory to the bin directory.
**Parameters:**
- `-ArtifactsDirectory`: Source directory (default: `artifacts`)
- `-BinDirectory`: Destination directory (default: `bin`)
**Usage:**
```powershell
.github/scripts/release/prepare-windows-artifacts.ps1 -ArtifactsDirectory artifacts -BinDirectory bin
```
### `install-go-winres.ps1`
Installs go-winres tool and adds it to PATH.
**Usage:**
```powershell
.github/scripts/release/install-go-winres.ps1
```
**Features:**
- Installs go-winres from GitHub
- Adds Go bin directory to PATH
- Exports PATH to GitHub environment
- Verifies installation with `go-winres help`
### `verify-smctl.ps1`
Verifies that DigiCert smctl tool is installed and accessible.
**Usage:**
```powershell
.github/scripts/release/verify-smctl.ps1
```
**Checks:**
- smctl.exe is in PATH
- Displays smctl version
- Confirms tool is ready for use
### `restore-p12-certificate.ps1`
Restores P12 client certificate from base64 encoding.
**Environment Variables:**
- `WINDOWS_SIGNING_P12_BASE64`: Base64 encoded P12 certificate (required)
- `RUNNER_TEMP`: Temporary directory for certificate file
- `GITHUB_ENV`: Path to GitHub environment file
**Usage:**
```powershell
$env:WINDOWS_SIGNING_P12_BASE64 = "<base64-string>"
.github/scripts/release/restore-p12-certificate.ps1
```
**Output:**
- Creates certificate file in `$RUNNER_TEMP/sm_client_auth.p12`
- Exports `SM_CLIENT_CERT_FILE` environment variable
### `sign-windows.ps1`
Comprehensive Windows binary signing script using DigiCert KeyLocker. **Fully driven by configuration**.
**Environment Variables:**
- `GITHUB_REF_NAME`: Git ref name (e.g., v0.93.4 or beta-2025111001)
- `SM_HOST`: DigiCert host URL
- `SM_API_KEY`: DigiCert API key
- `SM_CLIENT_CERT_FILE`: Path to P12 certificate file
- `SM_CLIENT_CERT_PASSWORD`: Certificate password
- `SM_KEYPAIR_ALIAS`: DigiCert keypair alias
**Parameters:**
- `-BinDirectory`: Directory containing binaries (default: `bin`)
**Usage:**
```powershell
.github/scripts/release/sign-windows.ps1 -BinDirectory bin
```
**Process:**
1. **Configuration Loading**: Reads `release-assets-config.json` to discover all Windows platforms
2. **Version Detection**: Parses git ref to extract version
- Standard: `v0.93.4` → `0.93.4`
- Pre-release: `beta-2025111001` → `2025.1110.01.0`
- Generic: `<prefix>-YYYYMMDDNN` → `YYYY.MMDD.NN.0`
3. **Resource Generation**: Dynamically generates `winres.json` with version info, icon, manifest, and metadata
4. **Binary Patching**: Uses go-winres to patch **all** Windows binaries with icon and metadata (regardless of signing status)
5. **Credential Setup**: Saves DigiCert credentials
6. **Healthcheck**: Runs smctl healthcheck
7. **Certificate Sync**: Syncs certificates from DigiCert KeyLocker
8. **Selective Signing**: For each Windows platform in config:
- If `"signed": true` → Signs with DigiCert and verifies signature
- If `"signed": false` → Skips signing (patching only)
9. **Summary**: Reports how many binaries were signed vs. patched-only
**Configuration-Driven Behavior:**
The script reads `.github/assets/release-assets-config.json` to determine:
- Which Windows binaries exist (`binary` field)
- Which binaries should be signed (`signed: true/false`)
- All patching decisions are automated based on JSON
**Example Config:**
```json
{
"platforms": [
{
"os": "windows",
"arch": "386",
"signed": false,
"binary": "terragrunt_windows_386.exe"
},
{
"os": "windows",
"arch": "amd64",
"signed": true,
"binary": "terragrunt_windows_amd64.exe"
}
]
}
```
With this config, the script will:
- Patch both binaries with icon/manifest
- Sign only the amd64 binary (conserving signature quota)
- Leave 386 unsigned
## Testing
### Bash Scripts
```bash
# Install shellcheck
sudo apt-get install shellcheck # Ubuntu/Debian
# or
brew install shellcheck # macOS
# Check all bash scripts
shellcheck .github/scripts/release/*.sh
# Test individual script
export VERSION=v0.93.4
export GH_TOKEN=<token>
.github/scripts/release/get-version.sh
```
### PowerShell Scripts
```powershell
# Install PSScriptAnalyzer
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
# Analyze all PowerShell scripts
Get-ChildItem .github/scripts/release/*.ps1 | ForEach-Object {
Invoke-ScriptAnalyzer -Path $_.FullName
}
# Test individual script
.github/scripts/release/verify-smctl.ps1
```
## Workflow Integration
These scripts are used by:
- **`.github/workflows/release.yml`** - Main release workflow
- Uses: `get-version.sh`, `check-release-exists.sh`, `set-permissions.sh`, `create-archives.sh`, `generate-checksums.sh`, `verify-files.sh`, `upload-assets.sh`, `verify-assets-uploaded.sh`
- **`.github/workflows/sign-macos.yml`** - macOS signing workflow
- Uses: `prepare-macos-artifacts.sh`, `install-gon.sh`, `sign-macos-binaries.sh`
- **`.github/workflows/sign-windows.yml`** - Windows signing workflow
- Uses: `prepare-windows-artifacts.ps1`, `install-go-winres.ps1`, `verify-smctl.ps1`, `restore-p12-certificate.ps1`, `sign-windows.ps1`
## Version Format Support
The scripts support multiple version tag formats:
| Format | Example | Windows FileVersion | Description |
|----------|--------------------|---------------------|---------------------------------|
| Standard | `v0.93.4` | `0.93.4.0` | Semantic version with v prefix |
| Beta | `beta-2025111001` | `2025.1110.01.0` | Pre-release with date timestamp |
| Alpha | `alpha-2025110301` | `2025.1103.01.0` | Alpha with date timestamp |
**Windows Version Constraints:**
- Each component must be ≤ 65535
- Format: YYYY.MMDD.NN.0 keeps all components within limits
## Security Notes
- All scripts use proper quoting to prevent command injection
- Environment variables are validated before use
- Sensitive data (tokens, passwords) passed via environment variables only
- Scripts fail fast on errors:
- Bash: `set -e`
- PowerShell: `$ErrorActionPreference = 'Stop'`
- No secrets are logged or printed to stdout
- Certificate files are stored in temporary directories
## Script Conventions
### Bash Scripts
- Use `#!/bin/bash` shebang
- Enable fail-fast: `set -e`
- Use functions for organization
- Validate environment variables with `assert_env_var_not_empty`
- Accept directory paths as arguments (default: `bin`)
- Use `printf` instead of `echo` for variable output
- Proper quoting: `"$variable"` not `$variable`
### PowerShell Scripts
- Use strict error handling: `$ErrorActionPreference = 'Stop'`
- Use parameters with defaults: `param([string]$BinDirectory = "bin")`
- Check exit codes: `if ($LASTEXITCODE -ne 0) { exit 1 }`
- Organize code into functions
- Use `Write-Host` for informational output
- Use `Write-Error` for errors
================================================
FILE: .github/scripts/release/check-release-exists.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to check if a GitHub release exists for a given tag
# Usage: check-release-exists.sh
# Environment variables:
# VERSION: The version/tag to check for
# GH_TOKEN: GitHub token for authentication
# GITHUB_OUTPUT: Path to GitHub output file
function main {
# Validate required environment variables
: "${VERSION:?ERROR: VERSION is a required environment variable}"
: "${GH_TOKEN:?ERROR: GH_TOKEN is a required environment variable}"
: "${GITHUB_OUTPUT:?ERROR: GITHUB_OUTPUT is a required environment variable}"
printf 'Checking if release exists for tag: %s\n' "$VERSION"
# Check if release exists using gh CLI (only care about exit code)
if ! gh release view "$VERSION" > /dev/null 2>&1; then
printf 'exists=false\n' >> "$GITHUB_OUTPUT"
printf 'Release not found for tag %s\n' "$VERSION"
exit 1
fi
# Get release details
local release_json
release_json=$(gh release view "$VERSION" --json 'id,uploadUrl,isDraft')
local release_id
local upload_url
local is_draft
release_id=$(jq -r '.id' <<< "$release_json")
upload_url=$(jq -r '.uploadUrl' <<< "$release_json")
is_draft=$(jq -r '.isDraft' <<< "$release_json")
# Write to GitHub output
printf 'exists=true\n' >> "$GITHUB_OUTPUT"
printf 'release_id=%s\n' "$release_id" >> "$GITHUB_OUTPUT"
printf 'upload_url=%s\n' "$upload_url" >> "$GITHUB_OUTPUT"
printf 'is_draft=%s\n' "$is_draft" >> "$GITHUB_OUTPUT"
echo "Found existing release:"
printf ' Release ID: %s\n' "$release_id"
printf ' Draft: %s\n' "$is_draft"
printf ' Upload URL: %s\n' "${upload_url%\{*}"
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/create-archives.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to create ZIP and TAR.GZ archives for each binary
# Usage: create-archives.sh <bin-directory>
function main {
local -r bin_dir="${1:-bin}"
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
# Use pushd/popd to avoid side effects on caller's working directory
pushd "$bin_dir" || return 1
echo "Creating individual archives for each binary..."
# Create individual ZIP and TAR.GZ archives for each binary (preserving execute permissions)
for binary in terragrunt_*; do
# Skip if it's already an archive file
if [[ "$binary" == *.zip ]] || [[ "$binary" == *.tar.gz ]]; then
continue
fi
# Create ZIP archive
zip "$binary.zip" "$binary"
echo "Created: $binary.zip"
# Create TAR.GZ archive (preserves Unix permissions including +x)
tar -czf "$binary.tar.gz" "$binary"
echo "Created: $binary.tar.gz"
done
echo ""
echo "All individual archives created:"
echo "ZIP archives:"
ls -lh *.zip
echo ""
echo "TAR.GZ archives:"
ls -lh *.tar.gz
# Return to original directory
popd || return 1
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/generate-checksums.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to generate SHA256 checksums for all release files
# Usage: generate-checksums.sh <bin-directory>
function main {
local -r bin_dir="${1:-bin}"
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
# Use pushd/popd to avoid side effects on caller's working directory
pushd "$bin_dir" || return 1
# Generate checksums for all files including individual ZIPs and TAR.GZ archives
sha256sum terragrunt_* > SHA256SUMS
echo "SHA256SUMS generated:"
cat SHA256SUMS
echo ""
echo "Total files with checksums: $(wc -l < SHA256SUMS)"
# Return to original directory
popd || return 1
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/generate-upload-summary.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to generate GitHub Actions step summary for release uploads
# Usage: generate-upload-summary.sh
# Environment variables:
# VERSION: Release version/tag
# RELEASE_ID: GitHub release ID
# IS_DRAFT: Whether release was a draft
# GITHUB_STEP_SUMMARY: Path to GitHub step summary file
# Source configuration library
# shellcheck source=lib-release-config.sh
source "$(dirname "$0")/lib-release-config.sh"
main() {
require_env_vars VERSION RELEASE_ID IS_DRAFT GITHUB_STEP_SUMMARY
verify_config_file
echo "Generating upload summary..."
local binary_count
binary_count=$(get_binary_count)
local total_count
total_count=$(get_total_file_count)
cat >>"$GITHUB_STEP_SUMMARY" <<EOF
## Release Asset Upload Summary
**Version**: $VERSION
**Release ID**: $RELEASE_ID
**Was Draft**: $IS_DRAFT
### Assets Uploaded
| Platform | Architecture | Signed | Status |
|----------|--------------|--------|--------|
EOF
# Generate platform table rows from configuration
generate_platform_table_rows >>"$GITHUB_STEP_SUMMARY"
cat >>"$GITHUB_STEP_SUMMARY" <<EOF
**Archive Files**:
- Individual ZIP archives: $binary_count files (one per binary, with +x permissions)
- Individual TAR.GZ archives: $binary_count files (one per binary, with +x permissions)
- **SHA256SUMS**: Checksums for all files
**Total Files**: $total_count ($binary_count binaries + $binary_count ZIPs + $binary_count TAR.GZ + SHA256SUMS)
All assets uploaded successfully to existing release!
EOF
echo "Upload summary generated successfully"
return 0
}
require_env_vars() {
local missing=0
for var_name in "$@"; do
if [[ -z "${!var_name:-}" ]]; then
echo "ERROR: Required environment variable $var_name not set." >&2
missing=1
fi
done
if [[ "$missing" -eq 1 ]]; then
exit 1
fi
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/get-version.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to get the version from either workflow dispatch input or git ref
# Usage: get-version.sh
# Environment variables:
# INPUT_TAG: Tag provided via workflow_dispatch
# EVENT_NAME: GitHub event name (workflow_dispatch or push)
# GITHUB_REF: Git reference (e.g., refs/tags/v0.93.4)
# GITHUB_OUTPUT: Path to GitHub output file
function resolve_version {
# Handle workflow_dispatch event (manual trigger with INPUT_TAG)
if [[ "$EVENT_NAME" = "workflow_dispatch" ]]; then
if [[ -z "$INPUT_TAG" ]]; then
echo "ERROR: INPUT_TAG is empty for workflow_dispatch event" >&2
exit 1
fi
echo "$INPUT_TAG"
return 0
fi
# Handle push event (tag push with GITHUB_REF)
if [[ -z "$GITHUB_REF" ]]; then
echo "ERROR: GITHUB_REF is empty" >&2
exit 1
fi
if [[ ! "$GITHUB_REF" =~ ^refs/tags/ ]]; then
echo "ERROR: GITHUB_REF does not start with 'refs/tags/': $GITHUB_REF" >&2
exit 1
fi
# Strip refs/tags/ prefix and return
echo "${GITHUB_REF#refs/tags/}"
return 0
}
function validate_version {
local -r version="$1"
if [[ -z "$version" ]]; then
echo "ERROR: Extracted version is empty" >&2
exit 1
fi
# Validate version matches expected pattern (tag-like: starts with letter/digit)
if [[ ! "$version" =~ ^[a-zA-Z0-9] ]]; then
echo "ERROR: Invalid version format: '$version' (must start with alphanumeric character)" >&2
exit 1
fi
return 0
}
function main {
local version
version=$(resolve_version)
validate_version "$version"
# Write to GitHub output
printf 'version=%s\n' "$version" >> "$GITHUB_OUTPUT"
printf 'Release version: %s\n' "$version"
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/install-go-winres.ps1
================================================
# Script to install go-winres tool
# Usage: install-go-winres.ps1
$ErrorActionPreference = 'Stop'
Write-Host "Installing go-winres..."
# Install go-winres
go install github.com/tc-hib/go-winres@latest
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to install go-winres"
exit 1
}
# Add Go bin to PATH
$goPath = & go env GOPATH
$goBinPath = Join-Path $goPath "bin"
$env:PATH = "$goBinPath;$env:PATH"
# Export PATH to GitHub environment
echo "$goBinPath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
Write-Host "go-winres installed to: $goBinPath"
Write-Host ""
Write-Host "Verifying go-winres installation..."
& go-winres help
if ($LASTEXITCODE -ne 0) {
Write-Error "go-winres verification failed"
exit 1
}
Write-Host ""
Write-Host "go-winres installed successfully"
================================================
FILE: .github/scripts/release/install-gon.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to download and install gon binary for macOS code signing
# Usage: install-gon.sh [gon-version]
# Environment variables:
# GON_VERSION: Version of gon to install (default: v0.0.37)
function main {
local gon_version="${1:-${GON_VERSION:-v0.0.37}}"
echo "Installing gon version $gon_version..."
# Download gon release
local download_url="https://github.com/Bearer/gon/releases/download/${gon_version}/gon_macos.zip"
echo "Downloading gon from: $download_url"
if ! curl -L -o gon.zip "$download_url"; then
echo "ERROR: Failed to download gon from $download_url" >&2
rm -f gon.zip
exit 1
fi
# Extract to specific target
echo "Extracting gon binary..."
if ! unzip -o gon.zip -d . gon; then
echo "ERROR: Failed to extract gon from gon.zip" >&2
rm -f gon.zip
exit 1
fi
# Verify extracted binary exists and is a regular file
if [[ ! -f ./gon ]]; then
echo "ERROR: Expected file './gon' not found after extraction" >&2
rm -f gon.zip
exit 1
fi
# Make executable
echo "Setting executable permissions..."
if ! chmod +x ./gon; then
echo "ERROR: Failed to set executable permissions on ./gon" >&2
rm -f gon.zip ./gon
exit 1
fi
# Verify it's executable
if [[ ! -x ./gon ]]; then
echo "ERROR: File ./gon is not executable after chmod" >&2
rm -f gon.zip ./gon
exit 1
fi
# Move to system path
echo "Moving gon to /usr/local/bin/"
if ! sudo mv ./gon /usr/local/bin/gon; then
echo "ERROR: Failed to move gon to /usr/local/bin/" >&2
rm -f gon.zip ./gon
exit 1
fi
if ! sudo chmod +x /usr/local/bin/gon; then
echo "ERROR: Failed to set executable permissions on /usr/local/bin/gon" >&2
exit 1
fi
# Verify installation
echo "Verifying gon installation..."
if ! gon --version; then
echo "ERROR: gon --version failed after installation" >&2
exit 1
fi
# Cleanup
rm -f gon.zip
echo "gon installed successfully"
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/lib-release-config.sh
================================================
#!/usr/bin/env bash
# Library script to read release assets configuration
# Usage: source .github/scripts/release/lib-release-config.sh
readonly RELEASE_CONFIG_FILE=".github/assets/release-assets-config.json"
# Get list of all binary filenames
get_all_binaries() {
jq -r '.platforms[].binary' "$RELEASE_CONFIG_FILE"
}
# Get total binary count (computed from platforms array)
get_binary_count() {
jq -r '.platforms | length' "$RELEASE_CONFIG_FILE"
}
# Get total expected file count (computed: binaries + archives + additional files)
get_total_file_count() {
jq -r '
(.platforms | length) as $binaries |
(.archive_formats | length) as $formats |
(.additional_files | length) as $additional |
$binaries + ($binaries * $formats) + $additional
' "$RELEASE_CONFIG_FILE"
}
# Get list of archive extensions
get_archive_extensions() {
jq -r '.archive_formats[].extension' "$RELEASE_CONFIG_FILE"
}
# Get list of additional files
get_additional_files() {
jq -r '.additional_files[].name' "$RELEASE_CONFIG_FILE"
}
# Generate expected files list (for verification)
get_all_expected_files() {
local binaries
# Get binaries
binaries=$(get_all_binaries)
# Generate list: binaries + archives + additional files
echo "$binaries"
# Add archives for each binary
for binary in $binaries; do
while IFS= read -r ext; do
echo "${binary}.${ext}"
done < <(get_archive_extensions)
done
# Add additional files
get_additional_files
return 0
}
# Get platform info as JSON for a specific binary
get_platform_info() {
local binary="$1"
jq --arg binary "$binary" '.platforms[] | select(.binary == $binary)' "$RELEASE_CONFIG_FILE"
}
# Generate markdown table rows for summary
generate_platform_table_rows() {
jq -r '.platforms[] | "| \(.os | ascii_downcase) | \(.arch) | \(if .signed then "Yes" else "No" end) | Uploaded |"' "$RELEASE_CONFIG_FILE" |
awk '{
# Capitalize first letter of OS
if ($2 == "darwin") $2 = "macOS"
else if ($2 == "linux") $2 = "Linux"
else if ($2 == "windows") $2 = "Windows"
print
}'
}
# Check if config file exists
verify_config_file() {
if [[ ! -f "$RELEASE_CONFIG_FILE" ]]; then
echo "ERROR: Release config file not found: $RELEASE_CONFIG_FILE" >&2
return 1
fi
return 0
}
================================================
FILE: .github/scripts/release/prepare-macos-artifacts.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to prepare macOS artifacts for signing
# Usage: prepare-macos-artifacts.sh <artifacts-dir> <bin-dir>
function main {
local -r artifacts_dir="${1:-artifacts}"
local -r bin_dir="${2:-bin}"
if [[ ! -d "$artifacts_dir" ]]; then
echo "ERROR: Artifacts directory $artifacts_dir does not exist" >&2
exit 1
fi
echo "Preparing macOS build artifacts..."
# Create bin directory
mkdir -p "$bin_dir"
# Copy only macOS artifacts (terragrunt_darwin_*) to bin directory
find "$artifacts_dir" -type f -name 'terragrunt_darwin_*' -exec cp {} "$bin_dir/" \;
# Verify we found macOS binaries
if ! ls "$bin_dir"/terragrunt_darwin_* > /dev/null 2>&1; then
echo "ERROR: No macOS binaries (terragrunt_darwin_*) found in $artifacts_dir" >&2
exit 1
fi
echo "Binary files to sign:"
ls -lahrt "$bin_dir"/*
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/prepare-windows-artifacts.ps1
================================================
# Script to prepare Windows artifacts for signing
# Usage: prepare-windows-artifacts.ps1 -ArtifactsDirectory <path> -BinDirectory <path>
param(
[Parameter(Mandatory=$false)]
[string]$ArtifactsDirectory = "artifacts",
[Parameter(Mandatory=$false)]
[string]$BinDirectory = "bin"
)
$ErrorActionPreference = 'Stop'
Write-Host "Preparing Windows build artifacts..."
# Create bin directory
New-Item -ItemType Directory -Force -Path $BinDirectory | Out-Null
# Check if artifacts directory exists
if (-not (Test-Path $ArtifactsDirectory)) {
Write-Error "Artifacts directory not found: $ArtifactsDirectory"
exit 1
}
# Copy Windows binaries to bin directory
Get-ChildItem -Path $ArtifactsDirectory -Filter "terragrunt_windows_*" -Recurse -File |
ForEach-Object {
Copy-Item $_.FullName -Destination $BinDirectory/
Write-Host "Copied: $($_.Name)"
}
Write-Host ""
Write-Host "Binary files to sign:"
Get-ChildItem -Path $BinDirectory | ForEach-Object { Write-Host $_.FullName }
Write-Host ""
Write-Host "Artifacts prepared successfully"
================================================
FILE: .github/scripts/release/restore-p12-certificate.ps1
================================================
# Script to restore P12 client certificate from base64
# Usage: restore-p12-certificate.ps1
# Environment variables:
# WINDOWS_SIGNING_P12_BASE64: Base64 encoded P12 certificate (required)
# RUNNER_TEMP: Temporary directory for certificate file
# GITHUB_ENV: Path to GitHub environment file
$ErrorActionPreference = 'Stop'
Write-Host "Restoring P12 client certificate from base64..."
# Get certificate from environment variable
$base64Certificate = $env:WINDOWS_SIGNING_P12_BASE64
if ([string]::IsNullOrEmpty($base64Certificate)) {
Write-Error "ERROR: Required environment variable WINDOWS_SIGNING_P12_BASE64 not set."
exit 1
}
# Decode base64 certificate
$bytes = [Convert]::FromBase64String($base64Certificate)
# Generate output path
$path = Join-Path $env:RUNNER_TEMP "sm_client_auth.p12"
# Write certificate to file
[IO.File]::WriteAllBytes($path, $bytes)
# Verify file was created
if (Test-Path $path) {
Write-Host "Certificate file created: $path"
$fileInfo = Get-Item $path
Write-Host "Size: $($fileInfo.Length) bytes"
} else {
Write-Error "Failed to create certificate file"
exit 1
}
# Export to GitHub environment
echo "SM_CLIENT_CERT_FILE=$path" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Host ""
Write-Host "SM_CLIENT_CERT_FILE set to: $path"
Write-Host "Certificate restored successfully"
================================================
FILE: .github/scripts/release/set-permissions.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to set execution permissions on binaries
# Usage: set-permissions.sh <bin-directory>
# Source configuration library
# shellcheck source=lib-release-config.sh
source "$(dirname "$0")/lib-release-config.sh"
function main {
local -r bin_dir="${1:-bin}"
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
verify_config_file
# Use pushd/popd to avoid side effects on caller's working directory
pushd "$bin_dir" || return 1
# Get list of all binaries from configuration
local binaries
mapfile -t binaries < <(get_all_binaries)
# Set execution permissions on all binaries
for binary in "${binaries[@]}"; do
if [[ -f "$binary" ]]; then
chmod +x "$binary"
echo "Set +x on $binary"
else
echo "Warning: Binary $binary not found, skipping" >&2
fi
done
echo "Execution permissions set on all binaries"
# Return to original directory
popd || return 1
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/sign-checksums.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to sign SHA256SUMS with GPG and Cosign
# Usage: sign-checksums.sh <bin-directory>
#
# Environment variables:
# GPG_FINGERPRINT - GPG key fingerprint for signing (required)
# SIGNING_GPG_PASSPHRASE - GPG key passphrase (required)
#
# Outputs:
# SHA256SUMS.gpgsig - GPG detached signature
# SHA256SUMS.sigstore.json - Cosign sigstore bundle
# SHA256SUMS.sig - Cosign signature (legacy, extracted from bundle)
# SHA256SUMS.pem - Cosign certificate (legacy, extracted from bundle)
function main {
local -r bin_dir="${1:-bin}"
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
if [[ -z "${GPG_FINGERPRINT}" ]]; then
echo "ERROR: GPG_FINGERPRINT environment variable is not set" >&2
exit 1
fi
if [[ -z "${SIGNING_GPG_PASSPHRASE}" ]]; then
echo "ERROR: SIGNING_GPG_PASSPHRASE environment variable is not set" >&2
exit 1
fi
# Use pushd/popd to avoid side effects on caller's working directory
pushd "$bin_dir" || exit 1
if [[ ! -f "SHA256SUMS" ]]; then
echo "ERROR: SHA256SUMS file not found in $bin_dir" >&2
popd || exit 1
exit 1
fi
# GPG signing
echo "Signing SHA256SUMS with GPG..."
gpg --batch --yes -u "${GPG_FINGERPRINT}" \
--pinentry-mode loopback \
--passphrase "${SIGNING_GPG_PASSPHRASE}" \
--output SHA256SUMS.gpgsig \
--detach-sign SHA256SUMS
echo "GPG signature created: SHA256SUMS.gpgsig"
# Cosign signing (keyless OIDC) - produces sigstore bundle
echo "Signing SHA256SUMS with Cosign..."
cosign sign-blob SHA256SUMS \
--bundle=SHA256SUMS.sigstore.json \
--yes
echo "Cosign bundle created: SHA256SUMS.sigstore.json"
# Extract legacy .sig and .pem from bundle for backward compatibility
echo "Extracting legacy signature files from bundle..."
jq -r '.messageSignature.signature' SHA256SUMS.sigstore.json > SHA256SUMS.sig
jq -r '.verificationMaterial.certificate.rawBytes' SHA256SUMS.sigstore.json | \
base64 --decode | \
openssl x509 -inform DER -outform PEM -out SHA256SUMS.pem
echo "Cosign signature created: SHA256SUMS.sig"
echo "Cosign certificate created: SHA256SUMS.pem"
echo ""
echo "All signatures generated successfully:"
ls -la SHA256SUMS*
popd || exit 1
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/sign-macos-binaries.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to sign macOS binaries using gon and Apple notarization
# Usage: sign-macos-binaries.sh <bin-dir>
# Environment variables:
# AC_PASSWORD: Apple Connect password
# AC_PROVIDER: Apple Connect provider
# AC_USERNAME: Apple Connect username
# MACOS_CERTIFICATE: macOS certificate in P12 format (base64 encoded)
# MACOS_CERTIFICATE_PASSWORD: Certificate password
function main {
local -r bin_dir="${1:-bin}"
# Validate required environment variables
: "${AC_PASSWORD:?ERROR: AC_PASSWORD is a required environment variable}"
: "${AC_PROVIDER:?ERROR: AC_PROVIDER is a required environment variable}"
: "${AC_USERNAME:?ERROR: AC_USERNAME is a required environment variable}"
: "${MACOS_CERTIFICATE:?ERROR: MACOS_CERTIFICATE is a required environment variable}"
: "${MACOS_CERTIFICATE_PASSWORD:?ERROR: MACOS_CERTIFICATE_PASSWORD is a required environment variable}"
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
echo "Signing macOS binaries..."
# Sign amd64 binary
echo "Signing amd64 binary..."
.github/scripts/setup/mac-sign.sh .gon_amd64.hcl
# Sign arm64 binary
echo "Signing arm64 binary..."
.github/scripts/setup/mac-sign.sh .gon_arm64.hcl
echo "Done signing the binaries"
# Source configuration library
# shellcheck source=lib-release-config.sh
source "$(dirname "$0")/lib-release-config.sh"
verify_config_file
# Get list of macOS binaries from config (compatible with bash 3.2+)
local macos_binaries
macos_binaries=$(jq -r '.platforms[] | select(.os == "darwin") | .binary' "$RELEASE_CONFIG_FILE")
echo "Expected macOS binaries from config: $macos_binaries"
# Remove old unsigned binaries from bin directory
echo "Removing unsigned binaries from $bin_dir..."
for binary in $macos_binaries; do
rm -f "$bin_dir/$binary"
echo " Removed: $bin_dir/$binary"
done
# Extract and verify signed binaries
echo ""
echo "Extracting and verifying signed binaries..."
for binary in $macos_binaries; do
local zip_file="${binary}.zip"
echo "Processing $binary..."
# Check ZIP file exists
[[ -f "$zip_file" ]] || {
echo "ERROR: ZIP file $zip_file not found for binary $binary" >&2
exit 1
}
echo " Found $zip_file, extracting..."
unzip -o "$zip_file"
# Check extraction succeeded
[[ -f "$binary" ]] || {
echo " ERROR: Failed to extract binary $binary from $zip_file" >&2
exit 1
}
echo " Extracted binary exists, checking signature..."
codesign -dv --verbose=4 "$binary" 2>&1 || {
echo " ERROR: Signature verification failed for binary $binary" >&2
exit 1
}
echo " Signature verified"
mv "$binary" "$bin_dir/"
echo " Moved signed binary to $bin_dir/"
# Also move the ZIP file to bin directory
mv "$zip_file" "$bin_dir/"
echo " Moved $zip_file to $bin_dir/"
echo ""
done
# Final verification of all binaries in bin directory
echo "Final verification of all binaries in $bin_dir..."
for binary in $macos_binaries; do
echo "Verifying $binary..."
[[ -f "$bin_dir/$binary" ]] || {
echo "ERROR: Binary $bin_dir/$binary not found after processing" >&2
exit 1
}
codesign -dv --verbose=4 "$bin_dir/$binary" || {
echo "ERROR: Signature verification failed for binary $bin_dir/$binary" >&2
exit 1
}
done
echo ""
echo "All macOS binaries signed and verified successfully"
# Show final contents of bin directory for debugging
echo ""
echo "Final contents of $bin_dir directory:"
ls -lah "$bin_dir/"
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/sign-windows.ps1
================================================
# Script to sign Windows binaries using DigiCert and patch with go-winres
# Usage: sign-windows.ps1 -BinDirectory <path>
# Environment variables:
# GITHUB_REF_NAME: Git ref name (e.g., v0.93.4 or beta-2025111001)
# SM_HOST: DigiCert host
# SM_API_KEY: DigiCert API key
# SM_CLIENT_CERT_FILE: Path to P12 certificate file
# SM_CLIENT_CERT_PASSWORD: Certificate password
# SM_KEYPAIR_ALIAS: DigiCert keypair alias
param(
[Parameter(Mandatory=$false)]
[string]$BinDirectory = "bin"
)
$ErrorActionPreference = 'Stop'
# Path to centralized configuration
$ConfigFile = ".github/assets/release-assets-config.json"
function Assert-EnvVar {
param([string]$Name)
$value = [Environment]::GetEnvironmentVariable($Name)
if ([string]::IsNullOrEmpty($value)) {
Write-Error "ERROR: Required environment variable $Name not set."
exit 1
}
}
function Get-WindowsPlatforms {
# Read configuration file
if (-not (Test-Path $ConfigFile)) {
Write-Error "Configuration file not found: $ConfigFile"
exit 1
}
Write-Host "Reading configuration from: $ConfigFile"
$config = Get-Content $ConfigFile -Raw | ConvertFrom-Json
# Filter Windows platforms
$windowsPlatforms = $config.platforms | Where-Object { $_.os -eq "windows" }
if ($windowsPlatforms.Count -eq 0) {
Write-Error "No Windows platforms found in configuration"
exit 1
}
Write-Host "Found $($windowsPlatforms.Count) Windows platform(s) in configuration"
return $windowsPlatforms
}
function Update-WinresVersion {
# Get version from git ref
$rawVersion = $env:GITHUB_REF_NAME
if ([string]::IsNullOrEmpty($rawVersion) -or $rawVersion -eq "refs/heads/main") {
$rawVersion = "0.0.0-dev"
}
Write-Host "Raw version from git ref: $rawVersion"
# Parse version based on tag format
$version = ""
$major = "0"
$minor = "0"
$patch = "0"
$build = "0"
if ($rawVersion -match '^v(\d+)\.(\d+)\.(\d+)') {
# Standard version tag: v0.93.4
$major = $matches[1]
$minor = $matches[2]
$patch = $matches[3]
$version = "$major.$minor.$patch"
Write-Host "Detected standard version tag: v$version"
}
elseif ($rawVersion -match '^([a-zA-Z0-9_-]+)-(\d{4})(\d{2})(\d{2})(\d{2})') {
# Generic pre-release tag: <prefix>-YYYYMMDDNN
# Examples: beta-2025111001, alpha-2025110301, rc-2025120101, dev-2025110501
# Extract prefix and date components: prefix-YYYY-MM-DD-build
$prefix = $matches[1]
$year = $matches[2]
$month = $matches[3]
$day = $matches[4]
$buildNum = $matches[5]
# Windows FileVersion components are limited to 65535
# Use format: YYYY.MMDD.NN.0 (all components within limits)
$major = $year
$minor = "$month$day"
$patch = $buildNum
$version = "$prefix-$year$month$day$buildNum"
Write-Host "Detected pre-release tag: $version (Prefix: $prefix, FileVersion will be $year.$month$day.$buildNum.0)"
}
elseif ($rawVersion -match '^\d+\.\d+') {
# Version without 'v' prefix
$version = $rawVersion
$versionParts = $version.Split('.')
$major = if ($versionParts.Length -gt 0) { $versionParts[0] } else { "0" }
$minor = if ($versionParts.Length -gt 1) { $versionParts[1] } else { "0" }
$patch = if ($versionParts.Length -gt 2) { $versionParts[2].Split('-')[0] } else { "0" }
Write-Host "Detected version without prefix: $version"
}
else {
# Branch name or dev version
$major = "0"
$minor = "0"
$patch = "0"
$version = "0.0.0-dev"
Write-Host "Using dev version: $version"
}
$fileVersion = "$major.$minor.$patch.0"
$copyrightYear = (Get-Date).Year
Write-Host "Final version: $version"
Write-Host "File version (for Windows): $fileVersion"
Write-Host ""
# Generate winres.json dynamically
Write-Host "Generating winres.json..."
$winresConfig = @{
RT_GROUP_ICON = @{
APP = @{
"0409" = ".github/assets/terragrunt.png"
}
}
RT_MANIFEST = @{
"#1" = @{
"0409" = @{
assembly = @{
identity = @{
name = "Terragrunt"
version = $fileVersion
}
description = "Terragrunt - Orchestrate OpenTofu and Terraform at Scale"
}
compatibility = @{
application = @(
@{
supportedOS = @{
Id = "{e2011457-1546-43c5-a5fe-008deee3d3f0}"
comment = "Windows Vista / Windows Server 2008"
}
},
@{
supportedOS = @{
Id = "{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"
comment = "Windows 7 / Windows Server 2008 R2"
}
},
@{
supportedOS = @{
Id = "{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"
comment = "Windows 8 / Windows Server 2012"
}
},
@{
supportedOS = @{
Id = "{1f676c76-80e1-4239-95bb-83d0f6d0da78}"
comment = "Windows 8.1 / Windows Server 2012 R2"
}
},
@{
supportedOS = @{
Id = "{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"
comment = "Windows 10, Windows 11 / Windows Server 2016, 2019, 2022"
}
}
)
}
dpiAwareness = "PerMonitorV2, PerMonitor"
}
}
}
RT_VERSION = @{
"#1" = @{
"0409" = @{
fixed = @{
file_version = $fileVersion
product_version = $fileVersion
}
info = @{
"0409" = @{
Comments = "Standardize IaC and manage growing infra complexity: define units, stacks, cut repetition with includes/hooks, execute modules in dependency order across environments"
CompanyName = "Gruntwork, Inc."
FileDescription = "Terragrunt - Orchestrate OpenTofu and Terraform at Scale"
FileVersion = $version
InternalName = "terragrunt"
LegalCopyright = "Copyright (C) $copyrightYear Gruntwork, Inc."
OriginalFilename = "terragrunt.exe"
ProductName = "Terragrunt"
ProductVersion = $version
}
}
}
}
}
}
# Write winres.json to current directory
$jsonOutput = $winresConfig | ConvertTo-Json -Depth 10 -Compress:$false
[System.IO.File]::WriteAllText("winres.json", $jsonOutput)
Write-Host "Generated winres.json:"
Get-Content winres.json
# Verify icon file exists
Write-Host ""
Write-Host "Verifying icon file..."
if (Test-Path ".github/assets/terragrunt.png") {
Write-Host "Icon file exists: .github/assets/terragrunt.png"
$iconInfo = Get-Item ".github/assets/terragrunt.png"
Write-Host "Icon size: $($iconInfo.Length) bytes"
} else {
Write-Error "Icon file not found: .github/assets/terragrunt.png"
exit 1
}
}
function Patch-Binaries {
param([array]$Platforms)
# Add Go bin to PATH
$goPath = & go env GOPATH
$goBinPath = Join-Path $goPath "bin"
$env:PATH = "$goBinPath;$env:PATH"
Write-Host "Patching Windows binaries with icon and version info..."
foreach ($platform in $Platforms) {
$binaryPath = Join-Path $BinDirectory $platform.binary
if (Test-Path $binaryPath) {
Write-Host "Patching $($platform.binary) ($($platform.arch))..."
& go-winres patch --in winres.json $binaryPath
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to patch $($platform.binary)"
exit 1
}
Write-Host "Successfully patched $($platform.binary)"
} else {
Write-Error "Binary not found: $binaryPath"
exit 1
}
}
Write-Host "All Windows binaries patched with resources"
}
function Save-Credentials {
Write-Host "Saving credentials to Windows Credential Manager..."
& smctl.exe credentials save $env:SM_API_KEY $env:SM_CLIENT_CERT_PASSWORD
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to save credentials"
exit 1
}
Write-Host "Credentials saved to Windows Credential Manager"
}
function Invoke-Healthcheck {
Write-Host "Running smctl healthcheck..."
& smctl.exe healthcheck
if ($LASTEXITCODE -ne 0) {
Write-Warning "Healthcheck failed (exit code: $LASTEXITCODE)"
Write-Warning "Continuing anyway - signing step will be the real test"
} else {
Write-Host "Healthcheck passed"
}
}
function Sync-Certificates {
Write-Host "Syncing certificates from DigiCert KeyLocker..."
& smctl.exe windows certsync --keypair-alias "$env:SM_KEYPAIR_ALIAS"
if ($LASTEXITCODE -ne 0) {
Write-Error "Certificate sync failed"
exit 1
}
Write-Host "Certificates synced to Windows store"
}
function Sign-Binary {
param([string]$BinaryPath)
Write-Host "Signing: $BinaryPath"
& smctl.exe sign `
--keypair-alias "$env:SM_KEYPAIR_ALIAS" `
--input "$BinaryPath" `
--simple `
--verbose
if ($LASTEXITCODE -ne 0) {
Write-Error "Signing failed for $BinaryPath"
exit 1
}
Write-Host "Successfully signed $BinaryPath"
}
function Verify-Signature {
param([string]$BinaryPath)
Write-Host "Verifying signature on: $BinaryPath"
& smctl.exe sign verify --input "$BinaryPath"
if ($LASTEXITCODE -ne 0) {
Write-Warning "Signature verification returned non-zero exit code (may be expected)"
} else {
Write-Host "Signature verified successfully"
}
}
function Main {
# Verify environment variables
Assert-EnvVar "SM_HOST"
Assert-EnvVar "SM_API_KEY"
Assert-EnvVar "SM_CLIENT_CERT_FILE"
Assert-EnvVar "SM_CLIENT_CERT_PASSWORD"
Assert-EnvVar "SM_KEYPAIR_ALIAS"
Assert-EnvVar "GITHUB_REF_NAME"
if (-not (Test-Path $BinDirectory)) {
Write-Error "Directory $BinDirectory does not exist"
exit 1
}
# Get Windows platforms from configuration
$windowsPlatforms = Get-WindowsPlatforms
# Update winres.json with version info
Update-WinresVersion
# Patch all Windows binaries with resources (icon, manifest, version info)
Patch-Binaries -Platforms $windowsPlatforms
# Save credentials
Save-Credentials
# Run healthcheck
Invoke-Healthcheck
# Sync certificates
Sync-Certificates
# Sign binaries based on configuration
Write-Host ""
Write-Host "Processing Windows binaries for signing..."
Write-Host ""
$signedCount = 0
$unsignedCount = 0
foreach ($platform in $windowsPlatforms) {
$binaryPath = Join-Path $BinDirectory $platform.binary
if (-not (Test-Path $binaryPath)) {
Write-Error "Binary not found: $binaryPath"
exit 1
}
if ($platform.signed -eq $true) {
Write-Host "Signing $($platform.binary) ($($platform.arch))..."
Sign-Binary -BinaryPath $binaryPath
Write-Host "Verifying signature on $($platform.binary)..."
Verify-Signature -BinaryPath $binaryPath
Write-Host "✓ $($platform.binary): signed and verified"
$signedCount++
} else {
Write-Host "○ $($platform.binary) ($($platform.arch)): patched with resources only (not signed per config)"
$unsignedCount++
}
Write-Host ""
}
Write-Host "Windows processing completed successfully:"
Write-Host " - Signed: $signedCount binary(ies)"
Write-Host " - Patched only: $unsignedCount binary(ies)"
Write-Host ""
Write-Host "All decisions based on configuration: $ConfigFile"
}
Main
================================================
FILE: .github/scripts/release/upload-assets.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to upload release assets to GitHub
# Usage: upload-assets.sh <bin-directory>
# Environment variables:
# VERSION: The version/tag to upload to
# GH_TOKEN: GitHub token for authentication
# CLOBBER: Set to 'true' to overwrite existing assets (default: false)
function main {
local -r bin_dir="${1:-bin}"
local -r clobber="${CLOBBER:-false}"
# Validate required environment variables
: "${VERSION:?ERROR: VERSION is a required environment variable}"
: "${GH_TOKEN:?ERROR: GH_TOKEN is a required environment variable}"
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
# Build upload command with optional --clobber flag
local clobber_flag=""
if [[ "$clobber" == "true" ]]; then
clobber_flag="--clobber"
echo "Note: --clobber enabled - will overwrite existing assets"
else
echo "Note: --clobber disabled - will fail if assets already exist"
fi
printf 'Uploading assets to existing release %s...\n' "$VERSION"
# Use pushd/popd to avoid side effects on caller's working directory
pushd "$bin_dir" || return 1
# Upload all files using gh CLI
for file in *; do
echo "Uploading $file..."
if gh release upload "$VERSION" "$file" $clobber_flag; then
echo "Uploaded $file"
else
echo "Upload failed for $file (will retry in verification)" >&2
fi
done
# Return to original directory
popd || return 1
echo "Upload phase completed"
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/verify-assets-uploaded.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to verify all assets were uploaded to the GitHub release
# Usage: verify-assets-uploaded.sh <bin-directory>
# Environment variables:
# VERSION: The version/tag to verify
# GH_TOKEN: GitHub token for authentication
# CLOBBER: Set to 'true' to overwrite existing assets during retry (default: false)
# Source configuration library
# shellcheck source=lib-release-config.sh
source "$(dirname "$0")/lib-release-config.sh"
readonly MAX_RETRIES=10
function main {
local -r bin_dir="${1:-bin}"
local -r clobber="${CLOBBER:-false}"
# Validate required environment variables
: "${VERSION:?ERROR: VERSION is a required environment variable}"
: "${GH_TOKEN:?ERROR: GH_TOKEN is a required environment variable}"
verify_config_file
# Build upload command with optional --clobber flag
local clobber_flag=""
if [[ "$clobber" == "true" ]]; then
clobber_flag="--clobber"
fi
echo "Verifying all assets are accessible..."
# Get list of assets in the release
local assets
assets=$(gh release view "$VERSION" --json 'assets' --jq '.assets[].name')
local asset_count
asset_count=$(wc -l <<< "$assets")
echo "Found $asset_count assets in release"
# Get expected files from centralized configuration
local expected_files
mapfile -t expected_files < <(get_all_expected_files)
# Check each expected file
for expected_file in "${expected_files[@]}"; do
echo "Checking $expected_file..."
# Check if file exists in release
if ! grep -q "^${expected_file}$" <<< "$assets"; then
echo "$expected_file not found in release, uploading..."
# Upload the missing file
if [[ -f "$bin_dir/$expected_file" ]]; then
local i
for ((i=0; i<MAX_RETRIES; i++)); do
if gh release upload "$VERSION" "$bin_dir/$expected_file" $clobber_flag; then
echo "Uploaded $expected_file"
break
fi
echo "Upload attempt $((i+1))/$MAX_RETRIES failed" >&2
sleep 5
done
if (( i == MAX_RETRIES )); then
echo "Failed to upload $expected_file after $MAX_RETRIES retries" >&2
exit 1
fi
else
echo "File $bin_dir/$expected_file not found locally" >&2
exit 1
fi
else
echo "$expected_file present"
fi
done
# Verify we can download assets (spot check)
echo ""
echo "Verifying asset downloads (spot check)..."
local download_url
download_url=$(gh release view "$VERSION" --json 'assets' --jq '.assets[0].url')
if curl -sILf "$download_url" > /dev/null; then
echo "Assets are downloadable"
else
echo "Warning: Could not verify asset download URL" >&2
fi
local expected_count
expected_count=$(get_total_file_count)
local binary_count
binary_count=$(get_binary_count)
echo ""
echo "All required assets verified!"
echo "Expected files: $expected_count ($binary_count binaries + archives + checksums)"
echo "Actual files: $asset_count"
if [[ "$asset_count" -lt "$expected_count" ]]; then
echo "Warning: Expected $expected_count files, found $asset_count" >&2
fi
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/verify-binaries-downloaded.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to verify all expected binaries were downloaded
# Usage: verify-binaries-downloaded.sh <bin-directory> [expected-count]
# Source configuration library
# shellcheck source=lib-release-config.sh
source "$(dirname "$0")/lib-release-config.sh"
function resolve_expected_count {
local -r count_override="$1"
# If override provided, use it; otherwise get from config
if [[ -n "$count_override" ]]; then
echo "$count_override"
return 0
fi
verify_config_file
get_binary_count
return 0
}
function main {
local -r bin_dir="${1:-bin}"
local -r count_override="${2:-}"
local expected_count
expected_count=$(resolve_expected_count "$count_override")
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
# Count binaries first
local binary_count
binary_count=$(find "$bin_dir/" -type f | wc -l)
# List binaries if any exist (resilient to empty directory)
if [[ "$binary_count" -gt 0 ]]; then
echo "Downloaded binaries:"
ls -lahrt "$bin_dir"/*
else
echo "No binaries found in $bin_dir"
fi
echo "Total binaries: $binary_count"
# Verify expected count
echo "Expected: at least $expected_count binaries"
if [[ "$binary_count" -lt "$expected_count" ]]; then
echo "ERROR: Expected at least $expected_count binaries, found $binary_count" >&2
exit 1
fi
echo "All binaries present ($binary_count files)"
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/verify-files.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to verify all required files are present before upload
# Usage: verify-files.sh <bin-directory>
# Source configuration library
# shellcheck source=lib-release-config.sh
source "$(dirname "$0")/lib-release-config.sh"
function main {
local -r bin_dir="${1:-bin}"
if [[ ! -d "$bin_dir" ]]; then
echo "ERROR: Directory $bin_dir does not exist" >&2
exit 1
fi
verify_config_file
echo "Verifying required files..."
# Get all binaries from configuration
local binaries
mapfile -t binaries < <(get_all_binaries)
# Check each binary
for file in "${binaries[@]}"; do
if [[ -f "$bin_dir/$file" ]]; then
echo "$file present"
else
echo "$file missing" >&2
exit 1
fi
done
# Check additional files from configuration
local additional_files
mapfile -t additional_files < <(get_additional_files)
for file in "${additional_files[@]}"; do
if [[ -f "$bin_dir/$file" ]]; then
echo "$file present"
else
echo "$file missing" >&2
exit 1
fi
done
echo "All required files verified"
return 0
}
main "$@"
================================================
FILE: .github/scripts/release/verify-smctl.ps1
================================================
# Script to verify smctl installation
# Usage: verify-smctl.ps1
$ErrorActionPreference = 'Stop'
Write-Host "Checking smctl installation..."
# Check if smctl is in PATH
$smctlPath = Get-Command smctl.exe -ErrorAction SilentlyContinue
if (-not $smctlPath) {
Write-Error "smctl.exe not found in PATH"
exit 1
}
Write-Host "smctl found at: $($smctlPath.Source)"
Write-Host "Checking smctl version..."
# Capture stderr and stdout
$output = & smctl.exe --version 2>&1
# Check exit code
if ($LASTEXITCODE -ne 0) {
Write-Error "smctl --version failed with exit code $LASTEXITCODE. Output: $output"
exit $LASTEXITCODE
}
# Display output if successful
Write-Host $output
Write-Host ""
Write-Host "smctl is ready"
================================================
FILE: .github/scripts/release/verify-static-binary.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Script to verify that binaries are statically linked
# Usage: verify-static-binary.sh <binary-path> <os> <arch>
die() {
echo "ERROR: $*" >&2
exit 1
}
require_arg() {
local -r value="$1"
local -r name="$2"
[[ -n "$value" ]] || die "$name is required"
return 0
}
expect_empty() {
local -r value="$1"
local -r message="$2"
[[ -z "$value" ]] || {
echo "$message" >&2
echo "$value" >&2
exit 1
}
return 0
}
verify_linux_binary() {
local -r binary="$1"
local -r file_info="$2"
echo "Verifying Linux binary is statically linked..."
echo "$file_info"
grep -q "statically linked" <<<"$file_info"
echo "Linux binary is statically linked"
# Verify with ldd - it should either say "not a dynamic executable" or "statically linked"
local ldd_output
ldd_output=$(ldd "$binary" 2>&1 || true)
grep -qE "not a dynamic executable|statically linked" <<<"$ldd_output"
echo "Linux binary has no dynamic dependencies"
return 0
}
verify_darwin_binary() {
local -r binary="$1"
local -r file_info="$2"
echo "Verifying macOS binary..."
echo "$file_info"
grep -q "Mach-O.*executable" <<<"$file_info"
echo "macOS binary is Mach-O executable"
return 0
}
verify_windows_binary() {
local -r binary="$1"
local -r file_info="$2"
echo "Verifying Windows binary..."
echo "$file_info"
grep -q "PE32.*executable.*Windows" <<<"$file_info"
echo "Windows binary is PE32 executable"
local unexpected_dlls
unexpected_dlls=$(
objdump -p "$binary" 2>/dev/null |
grep -i "DLL Name" |
grep -vi "KERNEL32.dll\|msvcrt.dll\|WS2_32.dll\|ADVAPI32.dll\|SHELL32.dll\|ole32.dll" || true
)
expect_empty "$unexpected_dlls" "Windows binary links to unexpected DLLs:"
echo "Windows binary has standard system DLL dependencies only"
return 0
}
main() {
local -r binary="${1:-}"
local -r os="${2:-}"
local -r arch="${3:-}"
require_arg "$binary" "binary path"
require_arg "$os" "os"
require_arg "$arch" "arch"
[[ -f "$binary" ]] || die "Binary $binary does not exist"
echo "Verifying static linking for $binary ($os/$arch)..."
local file_info
file_info=$(file "$binary")
case "$os" in
linux)
verify_linux_binary "$binary" "$file_info"
;;
darwin)
verify_darwin_binary "$binary" "$file_info"
;;
windows)
verify_windows_binary "$binary" "$file_info"
;;
*)
die "Unsupported OS: $os"
;;
esac
echo "Static linking verification passed for $os/$arch!"
return 0
}
main "$@"
================================================
FILE: .github/scripts/setup/cas.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
: "${ENV_FILE:?ENV_FILE is not set}"
touch "$ENV_FILE"
printf "export TG_EXPERIMENT='%s'\n" "cas" >> "$ENV_FILE"
================================================
FILE: .github/scripts/setup/engine.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
export TOFU_ENGINE_VERSION="v0.0.20"
export REPO="gruntwork-io/terragrunt-engine-opentofu"
export ASSET_NAME="terragrunt-iac-engine-opentofu_rpc_${TOFU_ENGINE_VERSION}_linux_amd64.zip"
pushd .
# Download the engine binary
mkdir -p /tmp/engine
cd /tmp/engine
wget -O "engine.zip" "https://github.com/${REPO}/releases/download/${TOFU_ENGINE_VERSION}/${ASSET_NAME}"
unzip -o "engine.zip"
popd
================================================
FILE: .github/scripts/setup/experiment-mode.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
: "${ENV_FILE:?ENV_FILE is not set}"
touch "$ENV_FILE"
printf "export TG_EXPERIMENT_MODE=%s\n" "true" >> "$ENV_FILE"
================================================
FILE: .github/scripts/setup/gcp.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
: "${ENV_FILE:?ENV_FILE is not set}"
touch "$ENV_FILE"
echo "$GCLOUD_SERVICE_KEY" > "${HOME}/gcloud-service-key.json"
export GOOGLE_APPLICATION_CREDENTIALS="${HOME}/gcloud-service-key.json"
printf "export GOOGLE_APPLICATION_CREDENTIALS='%s'\n" "${HOME}/gcloud-service-key.json" >> "$ENV_FILE"
# Save gcloud commands to ENV_FILE
printf "gcloud auth activate-service-account --key-file=\"%s\" --quiet\n" "${HOME}/gcloud-service-key.json" >> "$ENV_FILE"
printf "gcloud config set project '%s'\n" "${GOOGLE_PROJECT_ID}" >> "$ENV_FILE"
printf "export GOOGLE_CLOUD_PROJECT='%s'\n" "${GOOGLE_PROJECT_ID}" >> "$ENV_FILE"
================================================
FILE: .github/scripts/setup/generate-mocks.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
make generate-mocks
================================================
FILE: .github/scripts/setup/generate-secrets.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Required environment variables
: "${NAME:?NAME is not set}"
: "${ENV_FILE:?ENV_FILE is not set}"
: "${GITHUB_WORKSPACE:?GITHUB_WORKSPACE is not set}"
: "${GHA_DEPLOY_KEY:?GHA_DEPLOY_KEY is not set}"
: "${AWS_ACCESS_KEY_ID:?AWS_ACCESS_KEY_ID is not set}"
: "${AWS_SECRET_ACCESS_KEY:?AWS_SECRET_ACCESS_KEY is not set}"
: "${AWS_TEST_S3_ASSUME_ROLE:?AWS_TEST_S3_ASSUME_ROLE is not set}"
: "${AWS_TEST_OIDC_ROLE_ARN:?AWS_TEST_OIDC_ROLE_ARN is not set}"
: "${GCLOUD_SERVICE_KEY:?GCLOUD_SERVICE_KEY is not set}"
: "${GOOGLE_CLOUD_PROJECT:?GOOGLE_CLOUD_PROJECT is not set}"
: "${GOOGLE_COMPUTE_ZONE:?GOOGLE_COMPUTE_ZONE is not set}"
: "${GOOGLE_IDENTITY_EMAIL:?GOOGLE_IDENTITY_EMAIL is not set}"
: "${GOOGLE_PROJECT_ID:?GOOGLE_PROJECT_ID is not set}"
: "${GCLOUD_SERVICE_KEY_IMPERSONATOR:?GCLOUD_SERVICE_KEY_IMPERSONATOR is not set}"
# Optional environment variables
SECRETS="${SECRETS:-}"
touch "$ENV_FILE"
# Manually export each secret listed in matrix.integration.secrets
for SECRET in $SECRETS; do
if [[ "$SECRET" == "GHA_DEPLOY_KEY" && -n "${GHA_DEPLOY_KEY}" ]]; then
printf "export GHA_DEPLOY_KEY='%s'\n" "${GHA_DEPLOY_KEY}" >> "$ENV_FILE"
elif [[ "$SECRET" == "AWS_ACCESS_KEY_ID" && -n "${AWS_ACCESS_KEY_ID}" ]]; then
printf "export AWS_ACCESS_KEY_ID='%s'\n" "${AWS_ACCESS_KEY_ID}" >> "$ENV_FILE"
elif [[ "$SECRET" == "AWS_SECRET_ACCESS_KEY" && -n "${AWS_SECRET_ACCESS_KEY}" ]]; then
printf "export AWS_SECRET_ACCESS_KEY='%s'\n" "${AWS_SECRET_ACCESS_KEY}" >> "$ENV_FILE"
elif [[ "$SECRET" == "GCLOUD_SERVICE_KEY" && -n "${GCLOUD_SERVICE_KEY}" ]]; then
printf "export GCLOUD_SERVICE_KEY='%s'\n" "${GCLOUD_SERVICE_KEY}" >> "$ENV_FILE"
printf "export GOOGLE_SERVICE_ACCOUNT_JSON='%s'\n" "${GCLOUD_SERVICE_KEY}" >> "$ENV_FILE"
elif [[ "$SECRET" == "GOOGLE_CLOUD_PROJECT" && -n "${GOOGLE_CLOUD_PROJECT}" ]]; then
printf "export GOOGLE_CLOUD_PROJECT='%s'\n" "${GOOGLE_CLOUD_PROJECT}" >> "$ENV_FILE"
elif [[ "$SECRET" == "GOOGLE_COMPUTE_ZONE" && -n "${GOOGLE_COMPUTE_ZONE}" ]]; then
printf "export GOOGLE_COMPUTE_ZONE='%s'\n" "${GOOGLE_COMPUTE_ZONE}" >> "$ENV_FILE"
elif [[ "$SECRET" == "GOOGLE_IDENTITY_EMAIL" && -n "${GOOGLE_IDENTITY_EMAIL}" ]]; then
printf "export GOOGLE_IDENTITY_EMAIL='%s'\n" "${GOOGLE_IDENTITY_EMAIL}" >> "$ENV_FILE"
elif [[ "$SECRET" == "GOOGLE_PROJECT_ID" && -n "${GOOGLE_PROJECT_ID}" ]]; then
printf "export GOOGLE_PROJECT_ID='%s'\n" "${GOOGLE_PROJECT_ID}" >> "$ENV_FILE"
elif [[ "$SECRET" == "GCLOUD_SERVICE_KEY_IMPERSONATOR" && -n "${GCLOUD_SERVICE_KEY_IMPERSONATOR}" ]]; then
printf "export GCLOUD_SERVICE_KEY_IMPERSONATOR='%s'\n" "${GCLOUD_SERVICE_KEY_IMPERSONATOR}" >> "$ENV_FILE"
elif [[ "$SECRET" == "AWS_ACCESS_KEY_ID" && -n "${AWS_ACCESS_KEY_ID}" ]]; then
printf "export AWS_ACCESS_KEY_ID='%s'\n" "${AWS_ACCESS_KEY_ID}" >> "$ENV_FILE"
elif [[ "$SECRET" == "AWS_SECRET_ACCESS_KEY" && -n "${AWS_SECRET_ACCESS_KEY}" ]]; then
printf "export AWS_SECRET_ACCESS_KEY='%s'\n" "${AWS_SECRET_ACCESS_KEY}" >> "$ENV_FILE"
elif [[ "$SECRET" == "AWS_TEST_S3_ASSUME_ROLE" && -n "${AWS_TEST_S3_ASSUME_ROLE}" ]]; then
printf "export AWS_TEST_S3_ASSUME_ROLE='%s'\n" "${AWS_TEST_S3_ASSUME_ROLE}" >> "$ENV_FILE"
elif [[ "$SECRET" == "AWS_TEST_OIDC_ROLE_ARN" && -n "${AWS_TEST_OIDC_ROLE_ARN}" ]]; then
printf "export AWS_TEST_OIDC_ROLE_ARN='%s'\n" "${AWS_TEST_OIDC_ROLE_ARN}" >> "$ENV_FILE"
fi
done
echo "Created environment file with secrets for $NAME"
================================================
FILE: .github/scripts/setup/mac-sign.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Apple certificate used to validate developer certificates https://www.apple.com/certificateauthority/
readonly APPLE_ROOT_CERTIFICATE="http://certs.apple.com/devidg2.der"
function print_usage {
echo
echo "Usage: $0 [OPTIONS] <Path to files used to sign...>"
echo
printf ' MACOS_CERTIFICATE\t\tMac developer certificate in P12 format, encoded in base64.\n'
printf ' MACOS_CERTIFICATE_PASSWORD\tMac certificate password\n'
echo
echo "Optional Arguments:"
printf ' --macos-skip-root-certificate\t\tSkip importing Apple Root certificate. Useful when running in already configured environment.\n'
printf ' --help\t\t\t\tShow this help text and exit.\n'
echo
echo "Examples:"
echo " $0 sign.hcl"
return 0
}
function main {
local mac_skip_root_certificate=""
local assets=()
while [[ $# -gt 0 ]]; do
local key="$1"
case "$key" in
--macos-skip-root-certificate)
mac_skip_root_certificate=true
shift
;;
--help)
print_usage
exit
;;
-* )
echo "ERROR: Unrecognized argument: $key" >&2
print_usage
exit 1
;;
* )
assets=("$@")
break
esac
done
ensure_macos
import_certificate_mac "${mac_skip_root_certificate}"
sign_mac "${assets[@]}"
return 0
}
function ensure_macos {
if [[ $OSTYPE != 'darwin'* ]]; then
echo "Signing of Mac binaries is supported only on MacOS" >&2
exit 1
fi
return 0
}
function sign_mac {
local -r assets=("$@")
local gon_cmd="gon"
for filepath in "${assets[@]}"; do
echo "Signing ${filepath}"
"${gon_cmd}" -log-level=info "${filepath}"
done
return 0
}
function import_certificate_mac {
local -r mac_skip_root_certificate="$1"
assert_env_var_not_empty "MACOS_CERTIFICATE"
assert_env_var_not_empty "MACOS_CERTIFICATE_PASSWORD"
trap "rm -rf /tmp/*-keychain" EXIT
local mac_certificate_pwd="${MACOS_CERTIFICATE_PASSWORD}"
local keystore_pw="${RANDOM}"
# create separated keychain file to store certificate and do quick cleanup of sensitive data
local db_file
db_file=$(mktemp "/tmp/XXXXXX-keychain")
rm -rf "${db_file}"
echo "Creating separated keychain for certificate"
security create-keychain -p "${keystore_pw}" "${db_file}"
security default-keychain -s "${db_file}"
security unlock-keychain -p "${keystore_pw}" "${db_file}"
echo "${MACOS_CERTIFICATE}" | base64 -d | security import /dev/stdin -f pkcs12 -k "${db_file}" -P "${mac_certificate_pwd}" -T /usr/bin/codesign
if [[ "${mac_skip_root_certificate}" == "" ]]; then
# download apple root certificate used as root for developer certificate
curl -v "${APPLE_ROOT_CERTIFICATE}" --output certificate.der
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain certificate.der
fi
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${keystore_pw}" "${db_file}"
return 0
}
function assert_env_var_not_empty {
local -r var_name="$1"
local -r var_value="${!var_name}"
if [[ -z "$var_value" ]]; then
echo "ERROR: Required environment $var_name not set." >&2
exit 1
fi
return 0
}
main "$@"
================================================
FILE: .github/scripts/setup/provider-cache-server.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
: "${ENV_FILE:?ENV_FILE is not set}"
touch "$ENV_FILE"
printf "export TG_PROVIDER_CACHE='%s'\n" "1" >> "$ENV_FILE"
================================================
FILE: .github/scripts/setup/run-setup-scripts.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Required environment variables
: "${ENV_FILE:?ENV_FILE is not set}"
# Optional environment variables
SETUP_SCRIPTS="${SETUP_SCRIPTS:-}"
# Source the environment file
# shellcheck source=/dev/null
source "${ENV_FILE}"
# Loop through setup scripts and execute them
for SCRIPT in $SETUP_SCRIPTS; do
echo "Running setup script: $SCRIPT"
"$SCRIPT"
echo "Setup script $SCRIPT completed"
done
================================================
FILE: .github/scripts/setup/sops.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
gpg --import --no-tty --batch --yes ./test/fixtures/sops/test_pgp_key.asc
================================================
FILE: .github/scripts/setup/ssh.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
SSH_KEY="${GHA_DEPLOY_KEY:?Required environment variable GHA_DEPLOY_KEY}"
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
================================================
FILE: .github/scripts/setup/terraform-switch-latest.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
# Install Terraform 1.14.4
.github/scripts/setup/terraform-switch.sh 1.14.4
================================================
FILE: .github/scripts/setup/terraform-switch.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
: "${ENV_FILE:?ENV_FILE is not set}"
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <terraform-version>" >&2
exit 1
fi
TF_VERSION="$1"
touch "$ENV_FILE"
mise uninstall opentofu
mise use "terraform@${TF_VERSION}"
terraform --version
printf "export TG_TF_PATH='%s'\n" "terraform" >> "$ENV_FILE"
================================================
FILE: .github/scripts/setup/tofu-switch.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
: "${ENV_FILE:?ENV_FILE is not set}"
touch "$ENV_FILE"
mise uninstall --all terraform
tofu --version
printf "export TG_TF_PATH='%s'\n" "tofu" >> "$ENV_FILE"
================================================
FILE: .github/scripts/setup/windows-setup.ps1
================================================
git config --global core.compression 9
git config --system core.longpaths true
git config --global core.longpaths true
git config --local core.longpaths true
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
mkdir C:\bin
cmd /c mklink C:\bin\sh.exe "C:\Program Files\Git\usr\bin\bash.exe"
cmd /c mklink C:\bin\bash.exe "C:\Program Files\Git\usr\bin\bash.exe"
echo "C:\bin" | Out-File -Append -FilePath $env:GITHUB_PATH
================================================
FILE: .github/workflows/announce-release.yml
================================================
name: Announce Release
on:
release:
# This is intentionally not `published` to avoid announcing pre-releases
types: [released]
workflow_dispatch:
inputs:
tag_name:
description: 'The tag name of the release'
required: true
jobs:
release:
runs-on: ubuntu-slim
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Announce Release
run: ./.github/scripts/announce-release.sh
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
TAG_NAME: ${{ github.event.release.tag_name || inputs.tag_name }}
URL: ${{ secrets.RELEASE_ANNOUNCEMENT_URL }}
ROLE_ID: ${{ secrets.RELEASE_ANNOUNCEMENT_ROLE_ID }}
USERNAME: ${{ secrets.RELEASE_ANNOUNCEMENT_USERNAME }}
AVATAR_URL: ${{ secrets.RELEASE_ANNOUNCEMENT_AVATAR_URL }}
================================================
FILE: .github/workflows/base-test.yml
================================================
name: Base Tests
on:
workflow_call:
jobs:
test:
name: Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos]
env:
MISE_PROFILE: cicd
# Reduce GC frequency (default 100) to speed up builds/tests at cost of higher memory
GOGC: "400"
steps:
- name: "Mount tmpfs"
shell: bash
if: runner.os == 'Linux'
run: |
sudo mount -t tmpfs -o size=12G tmpfs /tmp
mkdir -p /home/runner/go
sudo mount -t tmpfs -o size=12G tmpfs /home/runner/go
mkdir -p /home/runner/.cache/go-build
sudo mount -t tmpfs -o size=4G tmpfs /home/runner/.cache/go-build
mkdir -p /home/runner/.cache/terragrunt
sudo mount -t tmpfs -o size=4G tmpfs /home/runner/.cache/terragrunt
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 1
# RAM disk for go-build cache — persists through post-steps so cache save works.
# If ramdisk is unmounted before job cleanup, cache save will fail silently.
- name: "Mount RAM disk"
shell: bash
if: runner.os == 'macOS'
run: |
RAMDISK=$(hdiutil attach -nomount ram://8388608 | tr -d '[:space:]') || { echo "Failed to create RAM disk"; exit 1; }
# Wait for disk device to be registered in kernel (hdiutil may return before kernel is ready)
for i in $(seq 1 10); do
diskutil info "$RAMDISK" > /dev/null 2>&1 && break
sleep 1
done
diskutil erasevolume HFS+ RAMDisk "$RAMDISK"
mkdir -p /Volumes/RAMDisk/go-build
rm -rf ~/Library/Caches/go-build
ln -sf /Volumes/RAMDisk/go-build ~/Library/Caches/go-build
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-amd64
restore-keys: |
${{ runner.os }}-go-build-
- name: Go Mod Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-amd64
restore-keys: |
${{ runner.os }}-go-mod-
- name: Terragrunt Provider Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ runner.os == 'Linux' && '~/.cache/terragrunt' || '~/Library/Caches/terragrunt' }}
key: ${{ runner.os }}-terragrunt-provider-cache-${{ hashFiles('**/.terraform.lock.hcl') }}
restore-keys: |
${{ runner.os }}-terragrunt-provider-cache-
- name: Run Tests
id: run-tests
run: |
set -o pipefail
go test -v ./... -timeout 45m | tee >(go-junit-report -set-exit-code > result.xml)
shell: bash
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Use shorter temp path on macOS to avoid path length issues with Git worktrees.
# Default /var/folders/.../T/ paths are too long for Git's path resolution.
TMPDIR: ${{ matrix.os == 'macos' && '/tmp' || '' }}
- name: Upload Report (${{ matrix.os }})
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: test-report-${{ matrix.os }}
path: result.xml
- name: Display Test Results (${{ matrix.os }})
uses: mikepenz/action-junit-report@49b2ca06f62aa7ef83ae6769a2179271e160d8e4 # v6
if: always()
with:
report_paths: result.xml
detailed_summary: 'true'
include_time_in_summary: 'true'
group_suite: 'true'
================================================
FILE: .github/workflows/build-no-proxy.yml
================================================
name: Build Without Go Proxy
on:
workflow_call:
workflow_dispatch:
jobs:
build-no-proxy:
name: Build (${{ matrix.os }}/${{ matrix.arch }})
runs-on: ubuntu-latest
strategy:
matrix:
include:
- os: darwin
arch: amd64
- os: darwin
arch: arm64
- os: linux
arch: "386"
- os: linux
arch: amd64
- os: linux
arch: arm64
- os: windows
arch: "386"
- os: windows
arch: amd64
steps:
- name: "Mount tmpfs"
shell: bash
if: runner.os == 'Linux'
run: |
sudo mount -t tmpfs -o size=12G tmpfs /tmp
mkdir -p /home/runner/go
sudo mount -t tmpfs -o size=12G tmpfs /home/runner/go
mkdir -p /home/runner/.cache/go-build
sudo mount -t tmpfs -o size=4G tmpfs /home/runner/.cache/go-build
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ matrix.arch }}
restore-keys: |
${{ runner.os }}-go-build-
- name: Go Mod Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-mod-
- name: Build Terragrunt without Go proxy
env:
GOPROXY: direct
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
run: |
OUTPUT="bin/terragrunt-${GOOS}-${GOARCH}"
if [ "${GOOS}" = "windows" ]; then
OUTPUT="${OUTPUT}.exe"
fi
go build -o "${OUTPUT}" \
-ldflags "-X github.com/gruntwork-io/go-commons/version.Version=${GITHUB_REF_NAME} -extldflags '-static'" \
.
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
workflow_call:
jobs:
detect_release:
name: Detect if this is a release build
runs-on: ubuntu-latest
outputs:
is_release: ${{ steps.check.outputs.is_release }}
steps:
- name: Check if release tag
id: check
run: |
REF="${GITHUB_REF}"
echo "Git ref: $REF"
# Check if this is a release tag (v*, alpha*, beta*)
if [[ "$REF" =~ ^refs/tags/v.* ]] || \
[[ "$REF" =~ ^refs/tags/alpha.* ]] || \
[[ "$REF" =~ ^refs/tags/beta.* ]]; then
echo "is_release=true" >> "$GITHUB_OUTPUT"
echo "This is a RELEASE build - signing will be enabled"
else
echo "is_release=false" >> "$GITHUB_OUTPUT"
echo "This is NOT a release build - signing will be skipped"
fi
build:
name: Build (${{ matrix.os }}/${{ matrix.arch }})
needs: detect_release
runs-on: ubuntu-latest
strategy:
matrix:
include:
- os: darwin
arch: amd64
- os: darwin
arch: arm64
- os: linux
arch: "386"
- os: linux
arch: amd64
- os: linux
arch: arm64
- os: windows
arch: "386"
- os: windows
arch: amd64
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ matrix.arch }}
restore-keys: |
${{ runner.os }}-go-build-
- name: Go Mod Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-mod-
- name: Build Terragrunt
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
CGO_ENABLED: 0
run: |
OUTPUT="bin/terragrunt_${GOOS}_${GOARCH}"
if [[ "${GOOS}" == "windows" ]]; then
OUTPUT="${OUTPUT}.exe"
fi
go build -o "${OUTPUT}" \
-ldflags "-s -w -X github.com/gruntwork-io/go-commons/version.Version=${GITHUB_REF_NAME}" \
.
- name: Verify Static Linking
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
run: |
OUTPUT="bin/terragrunt_${GOOS}_${GOARCH}"
if [[ "${GOOS}" == "windows" ]]; then
OUTPUT="${OUTPUT}.exe"
fi
.github/scripts/release/verify-static-binary.sh "${OUTPUT}" "${GOOS}" "${GOARCH}"
- name: Upload Build Artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: terragrunt_${{ matrix.os }}_${{ matrix.arch }}
path: bin/terragrunt_${{ matrix.os }}_${{ matrix.arch }}*
sign_macos:
name: Sign MacOS Binaries
if: ${{ needs.detect_release.outputs.is_release == 'true' }}
needs: [detect_release, build]
uses: ./.github/workflows/sign-macos.yml
secrets: inherit
sign_windows:
name: Sign Windows Binaries
if: ${{ needs.detect_release.outputs.is_release == 'true' }}
needs: [detect_release, build]
uses: ./.github/workflows/sign-windows.yml
secrets: inherit
merge_signed_binaries:
name: Merge All Signed Binaries
if: ${{ needs.detect_release.outputs.is_release == 'true' }}
needs: [detect_release, sign_macos, sign_windows]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Download macOS signed binaries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: macos-signed-files
path: bin/
- name: Verify macOS binaries after download
run: |
# Get list of expected macOS binaries from config
macos_binaries=$(jq -r '.platforms[] | select(.os == "darwin") | .binary' .github/assets/release-assets-config.json)
echo "Expected macOS binaries from config:"
echo "$macos_binaries"
echo ""
echo "Listing expected files in bin/:"
for binary in $macos_binaries; do
if [[ -f "bin/$binary" ]]; then
ls -lh "bin/$binary"
fi
if [[ -f "bin/$binary.zip" ]]; then
ls -lh "bin/$binary.zip"
fi
done
echo ""
echo "Verifying macOS binaries:"
for binary in $macos_binaries; do
echo "Checking bin/$binary:"
[[ -f "bin/$binary" ]] || {
echo " ERROR: Binary bin/$binary is missing from downloaded artifact"
exit 1
}
echo " OK: bin/$binary"
file "bin/$binary"
# Check for ZIP file
if [[ -f "bin/$binary.zip" ]]; then
echo " OK: bin/$binary.zip"
ls -lh "bin/$binary.zip"
else
echo " NOTICE: bin/$binary.zip (not present, will be created in merge)"
fi
echo ""
done
- name: Download Windows signed binaries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: windows-signed-files
path: bin/
- name: Download Linux binaries (unsigned)
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: terragrunt_linux_*
path: bin/
merge-multiple: true
- name: List all binaries
run: |
echo "All binaries ready for release:"
ls -lahrt bin/*
- name: Upload All Signed Binaries
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: all-signed-binaries
path: bin/*
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
lint:
uses: ./.github/workflows/lint.yml
permissions:
contents: read
secrets: inherit
precommit:
uses: ./.github/workflows/precommit.yml
permissions:
contents: read
secrets: inherit
codespell:
uses: ./.github/workflows/codespell.yml
permissions:
contents: read
secrets: inherit
go_mod_tidy_check:
uses: ./.github/workflows/go-mod-tidy-check.yml
permissions:
contents: read
secrets: inherit
markdownlint:
uses: ./.github/workflows/markdownlint.yml
permissions:
contents: read
secrets: inherit
install_script_test:
uses: ./.github/workflows/install-script-test.yml
permissions:
contents: read
secrets: inherit
license_check:
uses: ./.github/workflows/license-check.yml
permissions:
contents: read
secrets: inherit
fuzz:
uses: ./.github/workflows/fuzz.yml
permissions:
contents: read
secrets: inherit
# Fast feedback: only gate on lint/precommit/go_mod_tidy. Other checks (codespell,
# markdownlint, license_check, install_script_test) run in parallel and are enforced
# by branch protection rules, not by job dependencies.
base_tests:
needs: [lint, precommit, go_mod_tidy_check]
uses: ./.github/workflows/base-test.yml
permissions:
contents: read
checks: write
secrets: inherit
build:
needs: [lint, precommit, go_mod_tidy_check]
uses: ./.github/workflows/build.yml
permissions:
contents: read
secrets: inherit
build_no_proxy:
# Only run no_proxy builds on main branch to save CI time
if: github.ref == 'refs/heads/main'
needs: [lint, precommit, go_mod_tidy_check]
uses: ./.github/workflows/build-no-proxy.yml
permissions:
contents: read
secrets: inherit
integration_tests:
needs: [base_tests, build]
uses: ./.github/workflows/integration-test.yml
permissions:
contents: read
checks: write
secrets: inherit
oidc_integration_tests:
needs: [base_tests, build]
uses: ./.github/workflows/oidc-integration-test.yml
permissions:
id-token: write
contents: read
checks: write
secrets: inherit
================================================
FILE: .github/workflows/cloud-nuke.yml
================================================
name: Hourly Cloud Nuke
on:
schedule:
- cron: "0 * * * *" # Runs every hour
workflow_dispatch:
jobs:
run_cloud_nuke:
permissions:
id-token: write
contents: read
name: Nuke
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Install cloud-nuke
run: |
wget -O /usr/local/bin/cloud-nuke \
--header="Authorization: Bearer ${GITHUB_TOKEN}" \
"https://github.com/gruntwork-io/cloud-nuke/releases/download/v${VERSION}/cloud-nuke_linux_amd64"
chmod +x /usr/local/bin/cloud-nuke
env:
# Authenticate to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: 0.40.0
- name: Authenticate to AWS
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6
with:
role-to-assume: ${{ secrets.CLOUD_NUKE_ROLE }}
aws-region: us-east-1
- name: Run cloud-nuke
run: |
cloud-nuke aws \
--force \
--log-level debug \
--resource-type s3 \
--resource-type vpc \
--resource-type ec2 \
--resource-type dynamodb \
--region us-east-1 \
--region us-west-2 \
--older-than 1h \
--config .github/cloud-nuke/config.yml
================================================
FILE: .github/workflows/codespell.yml
================================================
name: Codespell
on:
workflow_call:
jobs:
codespell:
name: Check Spelling
runs-on: ubuntu-slim
env:
MISE_PROFILE: cicd
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run codespell
run: codespell
================================================
FILE: .github/workflows/flake.yml
================================================
name: Flake
on:
release:
types: [prereleased]
workflow_dispatch:
jobs:
test:
name: Flake Test (${{ matrix.flake.name }})
runs-on: ${{ matrix.flake.os }}-latest
strategy:
fail-fast: false
matrix:
flake:
- name: Ubuntu Base tests
os: ubuntu
count: 3
timeout: 45m
- name: macOS Base tests
os: macos
count: 3
timeout: 45m
env:
MISE_PROFILE: cicd
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: |
${{ steps.go-cache-paths.outputs.go-build }}
${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.flake.os }}-amd64
- name: Run Tests
id: run-tests
run: |
set -o pipefail
go test -v ./... -count=${COUNT} -timeout ${TIMEOUT} | tee >(go-junit-report -set-exit-code > result.xml)
shell: bash
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COUNT: ${{ matrix.flake.count }}
TIMEOUT: ${{ matrix.flake.timeout }}
- name: Upload Report (${{ matrix.flake.name }})
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: test-report-${{ matrix.flake.name }}
path: result.xml
- name: Display Test Results (${{ matrix.flake.name }})
uses: mikepenz/action-junit-report@49b2ca06f62aa7ef83ae6769a2179271e160d8e4 # v6
if: always()
with:
report_paths: result.xml
detailed_summary: 'true'
include_time_in_summary: 'true'
group_suite: 'true'
================================================
FILE: .github/workflows/fuzz.yml
================================================
name: Fuzz
on:
workflow_call:
jobs:
fuzz:
name: Fuzz Tests
runs-on: ubuntu-latest
env:
MISE_PROFILE: cicd
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 1
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-linux-amd64
restore-keys: |
${{ runner.os }}-go-build-
- name: Go Mod Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-linux-amd64
restore-keys: |
${{ runner.os }}-go-mod-
- name: Fuzz Corpus Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ~/.cache/go-build/fuzz
key: ${{ runner.os }}-fuzz-corpus-${{ github.sha }}
restore-keys: |
${{ runner.os }}-fuzz-corpus-
- name: Run Fuzz Tests
run: make fuzz
- name: Archive Fuzz Failures
if: failure()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: fuzz-failures
path: |
**/testdata/fuzz/**
================================================
FILE: .github/workflows/go-mod-tidy-check.yml
================================================
name: Go Mod Tidy Check
on:
workflow_call:
jobs:
go-mod-tidy-check:
name: Check go.mod and go.sum are tidy
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run go mod tidy
run: go mod tidy
- name: Check for changes
run: |
if ! git diff --exit-code go.mod go.sum; then
echo "::error::go.mod or go.sum are not tidy. Please run 'go mod tidy' locally and commit the changes."
exit 1
fi
echo "go.mod and go.sum are tidy"
================================================
FILE: .github/workflows/gopls.yml
================================================
name: Gopls Quickfix Check
on:
schedule:
- cron: '0 2 1 * *'
workflow_dispatch:
jobs:
gopls-quickfix:
name: Gopls Quickfix
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: main
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MISE_PROFILE: cicd
- name: Find Go files
id: gofiles
run: |
find . -type f -name '*.go' -not -path './vendor/*' > gofiles.txt
- name: Install parallel
run: sudo apt-get update && sudo apt-get install -y parallel
- name: Run gopls quickfixes
id: gopls_run
run: ./.github/scripts/gopls/run.sh
- name: Check for changes
id: check-changes
run: ./.github/scripts/gopls/check-for-changes.sh
env:
HAS_FIXES: ${{ steps.gopls_run.outputs.has_fixes }}
- name: Create issue for problems found
id: create_issue_for_problems
if: steps.gopls_run.outputs.has_fixes == 'true'
uses: actions/github-script@v8
env:
FIXED_FILES_PATH: ${{ steps.gopls_run.outputs.fixed_files_path }}
OUTPUT_FILE_PATH: ${{ steps.gopls_run.outputs.output_file_path }}
with:
script: |
const createIssue = require('./.github/scripts/gopls/create-issue.js');
const fixedFilesPath = process.env.FIXED_FILES_PATH;
const outputFilePath = process.env.OUTPUT_FILE_PATH;
await createIssue({ github, context, core, fixedFilesPath, outputFilePath });
- name: Create pull request for fixes
if: steps.check-changes.outputs.has_changes == 'true'
uses: actions/github-script@v8
env:
ISSUE_NUMBER: ${{ steps.create_issue_for_problems.outputs.issue_number }}
FIXED_FILES_PATH: ${{ steps.gopls_run.outputs.fixed_files_path }}
with:
script: |
const createPR = require('./.github/scripts/gopls/create-pr.js');
const issueNumber = process.env.ISSUE_NUMBER;
const fixedFilesPath = process.env.FIXED_FILES_PATH;
await createPR({ github, context, core, exec, issueNumber, fixedFilesPath });
- name: Success message
if: steps.gopls_run.outputs.has_fixes == 'false'
run: |
echo "✅ No gopls quickfix issues found!"
echo "All Go files are up to date with gopls recommendations."
================================================
FILE: .github/workflows/install-script-test.yml
================================================
name: Install Script Test
on:
workflow_call:
jobs:
install-script-test:
name: Install Script Tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Install GPG (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get update && sudo apt-get install -y gnupg
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4
- name: Run install script tests
run: ./docs/tests/install_test.sh
================================================
FILE: .github/workflows/integration-test.yml
================================================
name: Integration Tests
on:
workflow_call:
jobs:
test:
name: Test (${{ matrix.integration.name }})
runs-on: ${{ matrix.integration.os }}-latest
env:
MISE_PROFILE: cicd
strategy:
fail-fast: false
matrix:
integration:
- name: Fixtures with OpenTofu
os: ubuntu
target: ./test
tags: tofu
setup_scripts:
- .github/scripts/setup/tofu-switch.sh
- name: Fixtures with Latest Terraform
os: ubuntu
target: ./test
setup_scripts:
- .github/scripts/setup/terraform-switch-latest.sh
- name: SSH
os: ubuntu
target: ./...
setup_scripts:
- .github/scripts/setup/ssh.sh
tags: ssh
run: '^TestSSH'
secrets: [GHA_DEPLOY_KEY]
- name: SOPS
os: ubuntu
target: ./...
setup_scripts:
- .github/scripts/setup/sops.sh
tags: sops
run: '^TestSOPS'
- name: Tflint
os: ubuntu
target: ./...
tags: tflint
run: '^TestTflint'
secrets: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY]
- name: GCP
os: ubuntu
target: ./...
setup_scripts:
- .github/scripts/setup/gcp.sh
tags: gcp
run: '^TestGcp'
secrets: [GCLOUD_SERVICE_KEY, GOOGLE_CLOUD_PROJECT, GOOGLE_COMPUTE_ZONE, GOOGLE_IDENTITY_EMAIL, GOOGLE_PROJECT_ID, GCLOUD_SERVICE_KEY_IMPERSONATOR]
- name: AWS Tofu
os: ubuntu
target: ./...
tags: 'aws,tofu'
run: '^TestAws'
secrets: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_TEST_S3_ASSUME_ROLE]
setup_scripts:
- .github/scripts/setup/tofu-switch.sh
- name: AWS with Latest Terraform
os: ubuntu
target: ./...
tags: aws
run: '^TestAws'
secrets: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_TEST_S3_ASSUME_ROLE]
setup_scripts:
- .github/scripts/setup/terraform-switch-latest.sh
- name: AWSGCP
os: ubuntu
target: ./...
setup_scripts:
- .github/scripts/setup/gcp.sh
tags: awsgcp
run: '^TestAwsGcp'
secrets: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GCLOUD_SERVICE_KEY, GOOGLE_CLOUD_PROJECT, GOOGLE_COMPUTE_ZONE, GOOGLE_IDENTITY_EMAIL, GOOGLE_PROJECT_ID]
- name: Engine
os: ubuntu
target: ./...
setup_scripts:
- .github/scripts/setup/engine.sh
tags: engine
run: '^TestEngine'
- name: Windows
os: windows
target: ./...
setup_scripts:
- .github/scripts/setup/windows-setup.ps1
tags: windows
run: '^TestWindows'
- name: Provider Cache Server with Latest Terraform
os: ubuntu
target: ./test
setup_scripts:
- .github/scripts/setup/provider-cache-server.sh
- .github/scripts/setup/terraform-switch-latest.sh
- name: Provider Cache Server with Tofu
os: ubuntu
target: ./test
tags: tofu
setup_scripts:
- .github/scripts/setup/provider-cache-server.sh
- .github/scripts/setup/tofu-switch.sh
- name: Deprecated
os: ubuntu
target: ./...
tags: deprecated
run: '^TestDeprecated'
- name: Mock
os: ubuntu
target: ./...
tags: mocks
run: '^TestMock'
setup_scripts:
- .github/scripts/setup/generate-mocks.sh
- name: Race
os: ubuntu
target: ./...
run: '.*WithRacing'
test_args: "-race"
- name: Parse
os: ubuntu
target: ./...
tags: parse
run: '^TestParse'
- name: CAS
os: ubuntu
target: ./...
setup_scripts:
- .github/scripts/setup/cas.sh
- name: Experiment mode
os: ubuntu
target: ./...
setup_scripts:
- .github/scripts/setup/experiment-mode.sh
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 1
- name: "Setup Docker"
if: runner.os == 'Linux'
id: set-up-docker
uses: docker/setup-docker-action@1a6edb0ba9ac496f6850236981f15d8f9a82254d # v5
- name: "Save space on node"
if: runner.os != 'Windows'
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force
sudo docker builder prune -a
df -h
- name: "Mount tmpfs"
shell: bash
if: runner.os == 'Linux'
run: |
mkdir -p /home/runner/.cache/go-build
sudo mount -t tmpfs -o size=4G tmpfs /home/runner/.cache/go-build
# install dependencies for the integration tests
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate Secrets Environment
run: ./.github/scripts/setup/generate-secrets.sh
env:
NAME: ${{ matrix.integration.name }}
ENV_FILE: ${{ github.workspace }}/.env.secrets
SECRETS: ${{ join(matrix.integration.secrets, ' ') }}
GHA_DEPLOY_KEY: ${{ secrets.GHA_DEPLOY_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_TEST_OIDC_ROLE_ARN: ${{ secrets.AWS_TEST_OIDC_ROLE_ARN }}
GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}
GOOGLE_CLOUD_PROJECT: ${{ secrets.GOOGLE_CLOUD_PROJECT }}
GOOGLE_COMPUTE_ZONE: ${{ secrets.GOOGLE_COMPUTE_ZONE }}
GOOGLE_IDENTITY_EMAIL: ${{ secrets.GOOGLE_IDENTITY_EMAIL }}
GOOGLE_PROJECT_ID: ${{ secrets.GOOGLE_PROJECT_ID }}
GCLOUD_SERVICE_KEY_IMPERSONATOR: ${{ secrets.GCLOUD_SERVICE_KEY_IMPERSONATOR }}
AWS_TEST_S3_ASSUME_ROLE: ${{ secrets.AWS_TEST_S3_ASSUME_ROLE }}
shell: bash
- name: Setup
if: runner.os != 'Windows'
run: ./.github/scripts/setup/run-setup-scripts.sh
shell: bash
env:
ENV_FILE: ${{ github.workspace }}/.env.secrets
SETUP_SCRIPTS: ${{ join(matrix.integration.setup_scripts, ' ') }}
- name: Windows Setup
if: runner.os == 'Windows'
run: pwsh -File ./.github/scripts/setup/windows-setup.ps1
shell: pwsh
env:
ENV_FILE: ${{ github.workspace }}/.env.secrets
SETUP_SCRIPTS: ${{ join(matrix.integration.setup_scripts, ' ') }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: |
${{ steps.go-cache-paths.outputs.go-build }}
${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.integration.os }}-amd64
restore-keys: |
${{ runner.os }}-go-build-
- name: Terragrunt Provider Cache
if: runner.os == 'Linux'
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ~/.cache/terragrunt
key: ${{ runner.os }}-terragrunt-provider-cache-${{ hashFiles('**/.terraform.lock.hcl') }}
restore-keys: |
${{ runner.os }}-terragrunt-provider-cache-
- name: Run Tests
run: |
if [ "$SKIP" != "true" ]; then
source "${GITHUB_WORKSPACE}/.env.secrets"
# print command arguments
set -x
if [[ "$HAS_DOCKER" == "true" ]]; then
TAGS="${TAGS:+$TAGS,docker}"
TAGS="${TAGS:=docker}"
fi
go test -v -timeout 45m ${TAGS:+-tags "$TAGS"} ${RUN:+-run "$RUN"} ${TEST_ARGS} "${TARGET}" | tee test_output.log
# Generate XML report from test output
go-junit-report < test_output.log > result.xml
else
echo "Skipping tests for $NAME as the skip flag is true."
fi
shell: bash
env:
GITHUB_OAUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET: ${{ matrix.integration.target }}
TAGS: ${{ matrix.integration.tags }}
RUN: ${{ matrix.integration.run }}
SKIP: ${{ matrix.integration.skip }}
NAME: ${{ matrix.integration.name }}
TEST_ARGS: ${{ matrix.integration.test_args }}
HAS_DOCKER: ${{ runner.os == 'Linux' }}
- name: Upload Test Results (${{ matrix.integration.name }})
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: test-results-${{ matrix.integration.name }}
path: |
test_output.log
result.xml
- name: Display Test Results (${{ matrix.integration.name }})
uses: mikepenz/action-junit-report@49b2ca06f62aa7ef83ae6769a2179271e160d8e4 # v6
if: always()
with:
report_paths: result.xml
detailed_summary: 'true'
include_time_in_summary: 'true'
group_suite: 'true'
- name: Print Failed Tests (${{ matrix.integration.name }})
run: |
echo "Failed Tests in ${{ matrix.integration.name }}"
if [[ -f test_output.log ]]; then
# Count only test failure lines in a way that is safe with -e -o pipefail
failed_count=$(grep -E -c '^--- FAIL:' test_output.log || echo 0)
echo "Failed tests count: $failed_count"
if [[ "${failed_count}" -gt 0 ]]; then
echo "Failed test names:"
grep -E '^--- FAIL:' test_output.log | sed 's/.*FAIL:[[:space:]]*//'
else
echo "No failed tests found"
fi
else
echo "No test output found"
fi
echo ""
shell: bash
================================================
FILE: .github/workflows/license-check.yml
================================================
name: License Check
on:
workflow_call:
jobs:
license-check:
name: License Check
runs-on: ubuntu-slim
env:
MISE_PROFILE: cicd
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-linux-amd64
restore-keys: |
${{ runner.os }}-go-build-
- name: Go Mod Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-linux-amd64
restore-keys: |
${{ runner.os }}-go-mod-
- name: Run License Check
id: run-license-check
run: |
set -o pipefail
make license-check | tee license-check.log
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload License Check Report
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: license-check-report-ubuntu
path: license-check.log
================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint
on:
workflow_call:
jobs:
lint:
name: Lint (${{ matrix.os }})
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos]
env:
# Reduce GC frequency (default 100) to speed up builds/tests at cost of higher memory
GOGC: "400"
steps:
- name: "Mount tmpfs"
shell: bash
if: runner.os == 'Linux'
run: |
sudo mount -t tmpfs -o size=12G tmpfs /tmp
mkdir -p /home/runner/go
sudo mount -t tmpfs -o size=12G tmpfs /home/runner/go
mkdir -p /home/runner/.cache/go-build
sudo mount -t tmpfs -o size=4G tmpfs /home/runner/.cache/go-build
mkdir -p /home/runner/.cache/golangci-lint
sudo mount -t tmpfs -o size=2G tmpfs /home/runner/.cache/golangci-lint
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Set up mise
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
shell: bash
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
if [ "$RUNNER_OS" == "macOS" ]; then
echo "golangci-lint-cache=$HOME/Library/Caches/golangci-lint" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "golangci-lint-cache=$HOME/.cache/golangci-lint" >> "$GITHUB_OUTPUT"
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-amd64
restore-keys: |
${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-
- name: Go Mod Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-amd64
restore-keys: |
${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-
${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-
${{ runner.os }}-go-mod-
- name: golangci-lint Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ${{ steps.go-cache-paths.outputs.golangci-lint-cache }}
key: ${{ runner.os }}-golangci-lint-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-amd64
restore-keys: |
${{ runner.os }}-golangci-lint-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-
${{ runner.os }}-golangci-lint-
# fetch-depth: 0 fetches current branch history; origin/main ref must be fetched separately.
# Use refspec main:main to create a local branch (required for git merge-base main HEAD).
- name: Fetch main branch
if: startsWith(github.ref, 'refs/heads/') && github.ref != 'refs/heads/main'
run: git fetch origin main:main
# Ensure Go build cache directory exists on macOS.
# Prevents "mkdir go-build: file exists" or "No such file or directory"
# errors in golangci-lint.
- name: Ensure Go build cache dir (macOS)
if: runner.os == 'macOS'
run: |
cache_dir="$(go env GOCACHE)"
if [ -f "$cache_dir" ]; then rm -f "$cache_dir"; fi
mkdir -p "$cache_dir"
# macOS runners have ~14GB RAM. GOGC=400 lets the Go heap grow to ~31GB (measured), causing
# heavy swap and lint timeout. Cap heap to keep golangci-lint within available physical memory.
- name: Set memory limits (macOS)
if: runner.os == 'macOS'
run: |
echo "GOGC=100" >> "$GITHUB_ENV"
echo "GOMEMLIMIT=10GiB" >> "$GITHUB_ENV"
# Linux runners have ~28GB RAM but GOGC=400 still causes the heap to grow beyond available
# physical memory when linting with many build tags, triggering runner shutdown signals.
# Cap the heap to keep golangci-lint stable on Linux.
- name: Set memory limits (Linux)
if: runner.os == 'Linux'
run: |
echo "GOGC=100" >> "$GITHUB_ENV"
echo "GOMEMLIMIT=20GiB" >> "$GITHUB_ENV"
- name: Check for lint config changes
id: lint-config
if: startsWith(github.ref, 'refs/heads/') && github.ref != 'refs/heads/main'
run: |
if git diff --name-only origin/main...HEAD | grep -q '^\.golangci\.yml$'; then
echo "changed=true" >> "$GITHUB_OUTPUT"
else
echo "changed=false" >> "$GITHUB_OUTPUT"
fi
- name: Lint
run: |
# Full lint on main, tags, or when lint config changed
if [[ "${{ github.ref }}" != refs/heads/* ]] || \
[[ "${{ github.ref }}" == "refs/heads/main" ]] || \
[[ "${{ steps.lint-config.outputs.changed }}" == "true" ]]; then
make run-lint
else
make run-lint-incremental
fi
================================================
FILE: .github/workflows/markdownlint.yml
================================================
name: Markdown Lint
on:
workflow_call:
jobs:
markdownlint:
name: Run Lint
runs-on: ubuntu-slim
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Run markdownlint
uses: DavidAnson/markdownlint-cli2-action@07035fd053f7be764496c0f8d8f9f41f98305101 # v22
with:
globs: |
docs/**/*.md
================================================
FILE: .github/workflows/oidc-integration-test.yml
================================================
# These tests require different top-level permissions
# than the other integration tests, so we're keeping them
# in a separate workflow.
name: OIDC Integration Tests
on:
workflow_call:
jobs:
test:
permissions:
id-token: write
contents: read
checks: write
name: Test OIDC (${{ matrix.integration.name }})
runs-on: ${{ matrix.integration.os }}-latest
env:
MISE_PROFILE: cicd
strategy:
fail-fast: false
matrix:
integration:
- name: GHA AWS
os: ubuntu
target: ./...
tags: awsoidc
run: '^TestAws'
# We leave the key and secret on so that cleanup steps can use them.
secrets: [AWS_TEST_OIDC_ROLE_ARN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY]
setup_scripts:
- .github/scripts/setup/tofu-switch.sh
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: "Save space on node"
if: runner.os != 'Windows'
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force
sudo docker builder prune -a
df -h
# install dependencies for the integration tests
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate Secrets Environment
run: ./.github/scripts/setup/generate-secrets.sh
env:
NAME: ${{ matrix.integration.name }}
ENV_FILE: ${{ github.workspace }}/.env.secrets
SECRETS: ${{ join(matrix.integration.secrets, ' ') }}
GHA_DEPLOY_KEY: ${{ secrets.GHA_DEPLOY_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_TEST_OIDC_ROLE_ARN: ${{ secrets.AWS_TEST_OIDC_ROLE_ARN }}
GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}
GOOGLE_CLOUD_PROJECT: ${{ secrets.GOOGLE_CLOUD_PROJECT }}
GOOGLE_COMPUTE_ZONE: ${{ secrets.GOOGLE_COMPUTE_ZONE }}
GOOGLE_IDENTITY_EMAIL: ${{ secrets.GOOGLE_IDENTITY_EMAIL }}
GOOGLE_PROJECT_ID: ${{ secrets.GOOGLE_PROJECT_ID }}
GCLOUD_SERVICE_KEY_IMPERSONATOR: ${{ secrets.GCLOUD_SERVICE_KEY_IMPERSONATOR }}
AWS_TEST_S3_ASSUME_ROLE: ${{ secrets.AWS_TEST_S3_ASSUME_ROLE }}
shell: bash
- name: Setup
if: runner.os != 'Windows'
run: ./.github/scripts/setup/run-setup-scripts.sh
shell: bash
env:
ENV_FILE: ${{ github.workspace }}/.env.secrets
SETUP_SCRIPTS: ${{ join(matrix.integration.setup_scripts, ' ') }}
- name: Windows Setup
if: runner.os == 'Windows'
run: pwsh -File ./.github/scripts/setup/windows-setup.ps1
shell: pwsh
env:
ENV_FILE: ${{ github.workspace }}/.env.secrets
SETUP_SCRIPTS: ${{ join(matrix.integration.setup_scripts, ' ') }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: |
${{ steps.go-cache-paths.outputs.go-build }}
${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.integration.os }}-amd64
- name: Terragrunt Provider Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: ~/.cache/terragrunt
key: ${{ runner.os }}-terragrunt-provider-cache-${{ hashFiles('**/.terraform.lock.hcl') }}
restore-keys: |
${{ runner.os }}-terragrunt-provider-cache-
- name: Run Tests
run: |
if [ "$SKIP" != "true" ]; then
source "${GITHUB_WORKSPACE}/.env.secrets"
# print command arguments
set -x
go test -v -timeout 45m ${TAGS:+-tags "$TAGS"} ${RUN:+-run "$RUN"} ${TEST_ARGS} "${TARGET}" | tee >(go-junit-report -set-exit-code > result.xml)
else
echo "Skipping tests for $NAME as the skip flag is true."
fi
shell: bash
env:
GITHUB_OAUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET: ${{ matrix.integration.target }}
TAGS: ${{ matrix.integration.tags }}
RUN: ${{ matrix.integration.run }}
SKIP: ${{ matrix.integration.skip }}
NAME: ${{ matrix.integration.name }}
TEST_ARGS: ${{ matrix.integration.test_args }}
- name: Upload Report (${{ matrix.integration.name }})
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: test-report-${{ matrix.integration.name }}
path: result.xml
- name: Display Test Results (${{ matrix.integration.name }})
uses: mikepenz/action-junit-report@49b2ca06f62aa7ef83ae6769a2179271e160d8e4 # v6
if: always()
with:
report_paths: result.xml
detailed_summary: 'true'
include_time_in_summary: 'true'
group_suite: 'true'
================================================
FILE: .github/workflows/precommit.yml
================================================
name: Pre-commit
on:
workflow_call:
jobs:
precommit:
name: Run pre-commit hooks
runs-on: ubuntu-latest
env:
MISE_PROFILE: cicd
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
# Adding token here to reduce the likelihood of hitting rate limit issues.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Go Build Cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: |
${{ steps.go-cache-paths.outputs.go-build }}
${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-linux-amd64
restore-keys: |
${{ runner.os }}-go-build-
- name: Run pre-commit hooks
env:
GOPROXY: direct
GOOS: linux
GOARCH: amd64
run: |
pre-commit install
pre-commit run --all-files
================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
push:
tags:
- 'v*'
- 'alpha*'
- 'beta*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to release (e.g., v0.58.8)'
required: true
type: string
clobber:
description: 'Overwrite existing release assets (--clobber)'
required: false
type: boolean
default: false
jobs:
# Build and sign all binaries (reuses build.yml workflow)
build-and-sign:
name: Build and Sign All Binaries
uses: ./.github/workflows/build.yml
permissions:
contents: write
id-token: write
actions: read
secrets: inherit
# Upload binaries to existing GitHub release
upload-assets:
name: Upload Release Assets
needs: build-and-sign
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
actions: read
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Get version
id: version
env:
INPUT_TAG: ${{ inputs.tag }}
EVENT_NAME: ${{ github.event_name }}
run: .github/scripts/release/get-version.sh
- name: Check if release exists
id: check_release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
run: .github/scripts/release/check-release-exists.sh
- name: Download pre-built signed binaries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: all-signed-binaries
path: bin/
- name: Verify binaries downloaded
run: .github/scripts/release/verify-binaries-downloaded.sh bin 7
- name: Set execution permissions on binaries
run: .github/scripts/release/set-permissions.sh bin
- name: Create ZIP and TAR.GZ archives
run: .github/scripts/release/create-archives.sh bin
- name: Generate SHA256SUMS
run: .github/scripts/release/generate-checksums.sh bin
- name: Import GPG key and export public key
env:
SIGNING_GPG_PRIVATE_KEY: ${{ secrets.SIGNING_GPG_PRIVATE_KEY }}
run: |
echo "${SIGNING_GPG_PRIVATE_KEY}" | base64 --decode | gpg --batch --import
GPG_FINGERPRINT=$(gpg --list-secret-keys --keyid-format LONG | awk '/^sec/{sub(/.*\//, "", $2); print $2; exit}')
echo "GPG_FINGERPRINT=${GPG_FINGERPRINT}" >> "${GITHUB_ENV}"
gpg --armor --export "${GPG_FINGERPRINT}" > bin/terragrunt-signing-key.asc
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4
- name: Sign SHA256SUMS
env:
SIGNING_GPG_PASSPHRASE: ${{ secrets.SIGNING_GPG_PASSPHRASE }}
run: .github/scripts/release/sign-checksums.sh bin
- name: Verify signatures before upload
run: .github/scripts/release/verify-files.sh bin
- name: Upload assets to release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
CLOBBER: ${{ github.event_name == 'workflow_dispatch' && inputs.clobber || 'false' }}
run: .github/scripts/release/upload-assets.sh bin
- name: Verify all assets uploaded
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
CLOBBER: ${{ github.event_name == 'workflow_dispatch' && inputs.clobber || 'false' }}
run: .github/scripts/release/verify-assets-uploaded.sh bin
- name: Upload summary
if: always()
env:
VERSION: ${{ steps.version.outputs.version }}
RELEASE_ID: ${{ steps.check_release.outputs.release_id }}
IS_DRAFT: ${{ steps.check_release.outputs.is_draft }}
run: .github/scripts/release/generate-upload-summary.sh
================================================
FILE: .github/workflows/sign-macos.yml
================================================
name: Sign MacOS Binaries
on:
workflow_dispatch:
inputs:
artifact-pattern:
description: 'Pattern for artifacts to download (default: terragrunt_darwin_*)'
required: false
type: string
default: 'terragrunt_darwin_*'
upload-artifact-name:
description: 'Name for the uploaded signed artifacts'
required: false
type: string
default: 'macos-signed-files'
workflow_call:
inputs:
artifact-pattern:
description: 'Pattern for artifacts to download (default: terragrunt_darwin_*)'
required: false
type: string
default: 'terragrunt_darwin_*'
upload-artifact-name:
description: 'Name for the uploaded signed artifacts'
required: false
type: string
default: 'macos-signed-files'
jobs:
sign-macos:
name: Sign MacOS Binaries
runs-on: macos-latest
env:
MISE_PROFILE: cicd
GON_VERSION: v0.0.37
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Download macOS build artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: ${{ inputs.artifact-pattern }}
path: artifacts/
- name: Prepare build artifacts
run: .github/scripts/release/prepare-macos-artifacts.sh artifacts bin
- name: Use mise to install dependencies
uses: jdx/mise-action@c1ecc8f748cd28cdeabf76dab3cccde4ce692fe4 # v4.0.0
with:
version: 2026.1.9
experimental: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Cache gon binary
id: cache-gon
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: gon
key: gon-${{ env.GON_VERSION }}
- name: Download and install gon
if: steps.cache-gon.outputs.cache-hit != 'true'
run: .github/scripts/release/install-gon.sh ${{ env.GON_VERSION }}
- name: Verify gon installation
run: gon --version
- name: Sign MacOS Binaries
env:
AC_PASSWORD: ${{ secrets.MACOS_AC_PASSWORD }}
AC_PROVIDER: ${{ secrets.MACOS_AC_PROVIDER }}
AC_USERNAME: ${{ secrets.MACOS_AC_LOGIN }}
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
run: .github/scripts/release/sign-macos-binaries.sh bin
- name: Verify codesign signatures
run: |
# Get list of expected macOS binaries from config
macos_binaries=$(jq -r '.platforms[] | select(.os == "darwin") | .binary' .github/assets/release-assets-config.json)
for binary in $macos_binaries; do
codesign -dv --verbose=4 "bin/$binary" 2>&1 || {
echo "ERROR: No valid signature found for bin/$binary"
exit 1
}
done
- name: Upload Signed MacOS Binaries
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ inputs.upload-artifact-name }}
path: bin/terragrunt_darwin_*
if-no-files-found: error
================================================
FILE: .github/workflows/sign-windows.yml
================================================
name: Sign Windows Binaries
on:
workflow_call:
inputs:
artifact_pattern:
description: 'Pattern for artifacts to download (default: terragrunt_windows_*)'
required: false
type: string
default: 'terragrunt_windows_*'
upload_artifact_name:
description: 'Name for the uploaded signed artifacts'
required: false
type: string
default: 'windows-signed-files'
jobs:
sign-windows:
name: Sign Windows Binaries
runs-on: windows-latest
env:
SM_HOST: https://clientauth.one.digicert.com
SM_API_KEY: ${{ secrets.WINDOWS_SIGNING_API_KEY }}
SM_CLIENT_CERT_PASSWORD: ${{ secrets.WINDOWS_SIGNING_P12_PASSWORD }}
SM_KEYPAIR_ALIAS: ${{ secrets.WINDOWS_SIGNING_KEYPAIR_ALIAS }}
WINDOWS_SIGNING_P12_BASE64: ${{ secrets.WINDOWS_SIGNING_P12_BASE64 }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Download Windows build artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: ${{ inputs.artifact_pattern }}
path: artifacts/
merge-multiple: true
- name: Prepare build artifacts
shell: pwsh
run: .github/scripts/release/prepare-windows-artifacts.ps1 -ArtifactsDirectory artifacts -BinDirectory bin
- name: Setup Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: go.mod
- name: Install go-winres
shell: pwsh
run: .github/scripts/release/install-go-winres.ps1
# Install DigiCert smtools (smctl)
- name: Install DigiCert smtools
uses: digicert/ssm-code-signing@1d820463733701cf1484c7eb5d7d24a15ca2c454 # v1.2.1
with:
force-download-tools: 'true'
# Verify smctl is available
- name: Verify smctl installation
shell: pwsh
run: .github/scripts/release/verify-smctl.ps1
# Restore P12 client certificate and set SM_CLIENT_CERT_FILE
- name: Restore P12 client certificate
shell: pwsh
run: .github/scripts/release/restore-p12-certificate.ps1
# Sign Windows binaries using external script
- name: Sign and patch Windows binaries
shell: pwsh
run: .github/scripts/release/sign-windows.ps1 -BinDirectory bin
# Upload Windows binaries (signed amd64 + unsigned 386)
- name: Upload Windows Binaries
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ inputs.upload_artifact_name }}
path: |
bin/terragrunt_windows_amd64.exe
bin/terragrunt_windows_386.exe
if-no-files-found: error
================================================
FILE: .github/workflows/stale.yml
================================================
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
permissions:
contents: read
issues: write
pull-requests: write
runs-on: ubuntu-slim
steps:
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10
with:
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for raising this issue.'
stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for submitting this pull request.'
days-before-stale: 90
days-before-close: 7
stale-issue-label: 'stale'
stale-pr-label: 'stale'
exempt-issue-labels: 'rfc,preserved'
exempt-draft-pr: true
================================================
FILE: .github/workflows/update-codified-remote-deps.yml
================================================
name: Update Codified Remote Dependencies
on:
schedule:
- cron: '0 9 * * 1' # Every Monday at 9:00 UTC
workflow_dispatch:
jobs:
live-stacks-example:
permissions:
contents: write
pull-requests: write
name: Live Stacks Example Commit
runs-on: ubuntu-slim
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Check for update
id: check
run: |
LATEST_COMMIT=$(git ls-remote https://github.com/gruntwork-io/terragrunt-infrastructure-live-stacks-example.git HEAD | awk '{print $1}')
CURRENT_COMMIT=$(grep -oP 'git", "checkout", "\K[0-9a-f]{40}' test/integration_example_live_stacks_test.go)
echo "latest=$LATEST_COMMIT" >> "$GITHUB_OUTPUT"
echo "current=$CURRENT_COMMIT" >> "$GITHUB_OUTPUT"
if [[ "$LATEST_COMMIT" == "$CURRENT_COMMIT" ]]; then
echo "needs_update=false" >> "$GITHUB_OUTPUT"
else
echo "needs_update=true" >> "$GITHUB_OUTPUT"
fi
- name: Update commit hash
if: steps.check.outputs.needs_update == 'true'
env:
CURRENT_COMMIT: ${{ steps.check.outputs.current }}
LATEST_COMMIT: ${{ steps.check.outputs.latest }}
run: |
sed -i "s/$CURRENT_COMMIT/$LATEST_COMMIT/" test/integration_example_live_stacks_test.go
- name: Create pull request
if: steps.check.outputs.needs_update == 'true'
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7
with:
branch: chore/update-live-stacks-example-commit
commit-message: 'chore: Update live stacks example commit to ${{ steps.check.outputs.latest }}'
title: 'chore: Update live stacks example commit'
body: |
Updates the pinned commit in `TestExampleLiveStacks` from:
- `${{ steps.check.outputs.current }}`
to:
- `${{ steps.check.outputs.latest }}`
[Compare changes](https://github.com/gruntwork-io/terragrunt-infrastructure-live-stacks-example/compare/${{ steps.check.outputs.current }}...${{ steps.check.outputs.latest }})
labels: automated
================================================
FILE: .gitignore
================================================
.*.sw?
.idea
terragrunt.iml
vendor
.terraform
.vscode
*.tfstate
*.tfstate.backup
*.out
.terragrunt-cache
.bundle
.ruby-version
terragrunt
.DS_Store
.go-version
.terragrunt-stack
.devcontainer.json
.cursor/
.env
.licensei.cache
bin
# Windows code signing resources
rsrc.syso
resource.syso
*.syso
================================================
FILE: .golangci.yml
================================================
version: "2"
run:
go: "1.26"
issues-exit-code: 1
tests: true
output:
formats:
text:
path: stdout
print-linter-name: true
print-issued-lines: true
linters:
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- contextcheck
- dupl
- durationcheck
- errchkjson
- errorlint
- exhaustive
- fatcontext
- gocheckcompilerdirectives
- gochecksumtype
- goconst
- gocritic
- gosmopolitan
- lll
- loggercheck
- makezero
- misspell
- mnd
- musttag
- nilerr
- nilnesserr
- noctx
- paralleltest
- perfsprint
- prealloc
- protogetter
- reassign
- rowserrcheck
- spancheck
- sqlclosecheck
- staticcheck
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unconvert
- unparam
- usetesting
- wastedassign
- wsl_v5
- zerologlint
settings:
dupl:
threshold: 120
errcheck:
check-type-assertions: false
check-blank: false
exclude-functions:
- (*os.File).Close
errorlint:
errorf: true
asserts: true
comparison: true
goconst:
min-len: 3
min-occurrences: 5
gocritic:
enabled-tags:
- performance
disabled-tags:
- experimental
govet:
enable:
- fieldalignment
- printf
- unusedwrite
nakedret:
max-func-lines: 20
staticcheck:
checks:
- all
- -SA9005
- -QF1008
- -ST1001
unparam:
check-exported: false
wsl_v5:
allow-whole-block: false
branch-max-lines: 2
exclusions:
generated: lax
rules:
- linters:
- dupl
- errcheck
- gocyclo
- mnd
- unparam
- wsl
path: _test\.go
# We end up with duplicated content in this package to save us from duplicating code in other packages.
- linters:
- dupl
path: cli/flags/shared
# Incrementally linting lines that are too long to ensure that
# we don't have conflicts on every file in the codebase while
# trying to get this merged in.
- linters:
- lll
path-except: '^(internal/awshelper/|internal/cas/)'
paths:
- docs
- _ci
- .github
- .circleci
- third_party$
- builtin$
- examples$
issues:
max-issues-per-linter: 0
max-same-issues: 0
formatters:
enable:
- goimports
settings:
gofmt:
simplify: true
exclusions:
generated: lax
paths:
- docs
- _ci
- .github
- .circleci
- third_party$
- builtin$
- examples$
================================================
FILE: .gon_amd64.hcl
================================================
# See https://github.com/gruntwork-io/terraform-aws-ci/blob/main/modules/sign-binary-helpers/
# for further instructions on how to sign the binary + submitting for notarization.
source = ["./bin/terragrunt_darwin_amd64"]
bundle_id = "io.gruntwork.app.terragrunt"
apple_id {
username = "machine.apple@gruntwork.io"
}
sign {
application_identity = "Developer ID Application: Gruntwork, Inc."
}
zip {
output_path = "terragrunt_darwin_amd64.zip"
}
================================================
FILE: .gon_arm64.hcl
================================================
# See https://github.com/gruntwork-io/terraform-aws-ci/blob/main/modules/sign-binary-helpers/
# for further instructions on how to sign the binary + submitting for notarization.
source = ["./bin/terragrunt_darwin_arm64"]
bundle_id = "io.gruntwork.app.terragrunt"
apple_id {
username = "machine.apple@gruntwork.io"
}
sign {
application_identity = "Developer ID Application: Gruntwork, Inc."
}
zip {
output_path = "terragrunt_darwin_arm64.zip"
}
================================================
FILE: .licensei.toml
================================================
approved = [
"apache-2.0",
"bsd-2-clause",
"bsd-3-clause",
"isc",
"mpl-2.0",
"mit",
]
ignored = [
"github.com/terraform-linters/tflint-plugin-sdk",
"github.com/owenrumney/go-sarif",
"github.com/davecgh/go-spew"
]
[header]
ignorePaths = ["vendor", ".gen"]
ignoreFiles = ["mock_*.go", "*_gen.go"]
================================================
FILE: .markdownlint-cli2.yaml
================================================
config:
# Disable line length limit
MD013: false
# Disable multiple headers with the same content
MD024: false
# Disable requirement for descriptive links (e.g. allow click [here]())
MD059: false
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/gruntwork-io/pre-commit
rev: v0.1.29
hooks:
- id: tofu-fmt
exclude: test/fixtures/hclvalidate/valid/.*
- id: goimports
================================================
FILE: .sonarcloud.properties
================================================
# Source File Exclusions: Patterns used to exclude some source files from analysis.
sonar.exclusions=**/*_test.go
# Test File Inclusions: Patterns used to include some test files and only these ones in analysis.
sonar.test.inclusions=**/*_test.go
================================================
FILE: CODEOWNERS
================================================
* @denis256 @thisguycodes @yhakbar
================================================
FILE: KEYS
================================================
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEaWUgtBYJKwYBBAHaRw8BAQdA9b1hTzoHHbAYEqd4F+8hBnuw89vQ35F5gaWE
9Tpns760NEdydW50d29yayAoQ29kZSBTaWduaW5nIEtleSkgPHNlY3VyaXR5QGdy
dW50d29yay5pbz6IkwQTFgoAOxYhBGjID4bfmOcQwPIuLld3dKyoR8xJBQJpZSC0
AhsDBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEFd3dKyoR8xJN9ABAKHD
87thKPV4afl81OA+R+Fqr9x2eFI7EygeWec3b2pUAPwNV6sfkzzPARTKzsZeqcxW
vDJAtK5LYaokTLdsXb8bBA==
=6QIi
-----END PGP PUBLIC KEY BLOCK-----
================================================
FILE: LICENSE.txt
================================================
The MIT License (MIT)
Copyright (c) 2016 Gruntwork, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: Makefile
================================================
GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)
help:
@echo "Various utilities for managing the terragrunt repository"
fmt:
@echo "Running source files through gofmt..."
gofmt -w $(GOFMT_FILES)
fmtcheck:
pre-commit run goimports --all-files
install-pre-commit-hook:
pre-commit install
# This build target just for convenience for those building directly from
# source. See also: .github/workflows/build.yml
build: terragrunt
terragrunt: $(shell find . \( -type d -name 'vendor' -prune \) \
-o \( -type f -name '*.go' -print \) )
set -xe ;\
vtag_maybe_extra=$$(git describe --tags --abbrev=12 --dirty --broken) ;\
CGO_ENABLED=0 go build -o $@ -ldflags "-s -w -X github.com/gruntwork-io/go-commons/version.Version=$${vtag_maybe_extra}" .
clean:
rm -f terragrunt
IGNORE_TAGS := windows|linux|darwin|freebsd|openbsd|netbsd|dragonfly|solaris|plan9|js|wasip1|aix|android|illumos|ios|386|amd64|arm|arm64|mips|mips64|mips64le|mipsle|ppc64|ppc64le|riscv64|s390x|wasm
LINT_TAGS := $(shell grep -rh --include='*.go' 'go:build' . | \
sed 's/.*go:build\s*//' | \
tr -cs '[:alnum:]_' '\n' | \
grep -vE '^($(IGNORE_TAGS))$$' | \
sed '/^$$/d' | \
sort -u | \
paste -sd, -)
run-lint:
@echo "Linting with feature flags: [$(LINT_TAGS)]"
GOFLAGS="-tags=$(LINT_TAGS)" golangci-lint run -v --timeout=30m ./...
run-lint-incremental:
@echo "Incremental lint (new issues only) with feature flags: [$(LINT_TAGS)]"
GOFLAGS="-tags=$(LINT_TAGS)" golangci-lint run -v --timeout=30m --new-from-merge-base=main ./...
run-lint-fix:
@echo "Linting with feature flags: [$(LINT_TAGS)]"
GOFLAGS="-tags=$(LINT_TAGS)" golangci-lint run -v --timeout=30m --fix ./...
generate-mocks:
go generate ./...
license-check:
go mod vendor
licensei cache --debug
licensei check --debug
licensei header --debug
fuzz:
@for package in $$(go list ./...); do \
for fuzz_test in $$(go test -list 'Fuzz' "$$package" 2>/dev/null | grep '^Fuzz' || true); do \
echo "Fuzzing $$fuzz_test in $$package"; \
go test -run '^$$' -fuzztime="30s" -v -fuzz "^$$fuzz_test$$" "$$package"; \
done; \
done
.PHONY: help fmt fmtcheck install-pre-commit-hook clean run-lint run-lint-fix fuzz
================================================
FILE: README.md
================================================
# Terragrunt
[](https://gruntwork.io/?ref=repo_terragrunt)
[](https://goreportcard.com/report/github.com/gruntwork-io/terragrunt)
[](https://godoc.org/github.com/gruntwork-io/terragrunt)


Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in [OpenTofu](https://opentofu.org)/[Terraform](https://www.terraform.io) to scale.
Please see the following for more info, including install instructions and complete documentation:
* [Terragrunt Website](https://terragrunt.com)
* [Getting started with Terragrunt](https://docs.terragrunt.com/getting-started/quick-start/)
* [Terragrunt Documentation](https://docs.terragrunt.com/)
* [Contributing to Terragrunt](https://docs.terragrunt.com/community/contributing)
* [Commercial Support](https://gruntwork.io/support/)
## Join the Discord!
Join [our community](https://discord.com/invite/YENaT9h8jh) for discussions, support, and contributions:
[](https://discord.com/invite/YENaT9h8jh)
## License
This code is released under the MIT License. See [LICENSE.txt](LICENSE.txt).
================================================
FILE: SECURITY.md
================================================
# Reporting Security Issues
Gruntwork takes security seriously, and we value the input of independent security researchers. If you're reading this because you're looking to engage in responsible disclosure of a security vulnerability, we want to start with thanking you for your efforts. We appreciate your work and will make every effort to acknowledge your contributions.
To report a security issue, please use the GitHub Security Advisory ["Report a vulnerability"](https://github.com/gruntwork-io/terragrunt/security/advisories/new) button in the ["Security"](https://github.com/gruntwork-io/terragrunt/security) tab.
After receiving the report, we will investigate the issue and inform you of next steps. After the initial reply, we may ask for additional information, and will endeavor to keep you informed of our progress.
If you are reporting a bug related to an associated tool that Terragrunt integrates with, we ask that you report the issue directly to the maintainers of that tool.
Please do not disclose the issue publicly until we have had a chance to address it.
## Expectations on timelines
You can expect that Gruntwork will take any report of a security vulnerability seriously, but we ask that you also respect that it can take time to investigate and address issues given the size of the team maintaining Terragrunt. We will do our best to keep you informed of our progress, and provide insight into the timeline for addressing the issue.
## Thank you
We appreciate your help in making Terragrunt more secure. Thank you for your efforts in responsibly disclosing security issues, and for your patience as we work to address them.
## Verifying Release Signatures
All Terragrunt releases are signed with both GPG and Cosign. You can verify the authenticity of downloaded binaries using either method.
### Download Verification Files
```bash
VERSION="v0.XX.X" # Replace with actual version
curl -LO "https://github.com/gruntwork-io/terragrunt/releases/download/${VERSION}/SHA256SUMS"
curl -LO "https://github.com/gruntwork-io/terragrunt/releases/download/${VERSION}/SHA256SUMS.gpgsig"
curl -LO "https://github.com/gruntwork-io/terragrunt/releases/download/${VERSION}/SHA256SUMS.sig"
curl -LO "https://github.com/gruntwork-io/terragrunt/releases/download/${VERSION}/SHA256SUMS.pem"
```
### GPG Verification
```bash
# Import the public key (first time only)
curl -s https://gruntwork.io/.well-known/pgp-key.txt | gpg --import
# Verify the signature
gpg --verify SHA256SUMS.gpgsig SHA256SUMS
# Verify binary checksum
sha256sum -c SHA256SUMS --ignore-missing
```
### Cosign Verification
```bash
# Install cosign: https://docs.sigstore.dev/cosign/system_config/installation/
cosign verify-blob SHA256SUMS \
--signature SHA256SUMS.sig \
--certificate SHA256SUMS.pem \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp "github.com/gruntwork-io/terragrunt"
# Verify binary checksum
sha256sum -c SHA256SUMS --ignore-missing
```
================================================
FILE: docs/.gitignore
================================================
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# Vercel files
.vercel
================================================
FILE: docs/.vercelignore
================================================
node_modules
.env
.env.local
.env.production
================================================
FILE: docs/README.md
================================================
# Terragrunt Documentation
This is the documentation for Terragrunt (hosted at <https://docs.terragrunt.com>), built using [Starlight](https://github.com/withastro/starlight), a documentation framework for Astro.
## Development
To get started, install the requisite dependencies to run the project locally using [mise](https://mise.jdx.dev/):
```bash
mise install
```
Afterwards, you'll want to install the NPM dependencies for the project:
```bash
bun i
```
You'll also need to install [d2](https://github.com/terrastruct/d2/blob/master/docs/INSTALL.md) to build any diagrams referenced in the documentation:
You can now start the development server:
```bash
bun dev
```
This will start a development server on <http://127.0.0.1:4321> that will be automatically reloaded when you make changes to documentation.
## Building
When the project is ready to deployed, it will be built using the following command:
```bash
bun run build
```
This will generate a `dist` directory with the built documentation.
Running this locally can be useful if you see that the build fails in CI, as additional checks are performed in the build process, like ensuring that all links are valid.
## Hosting
The website is hosted on [Vercel](https://vercel.com/), and is automatically deployed when a new commit is pushed to the `main` branch.
Every pull request will result in a preview deployment of the documentation site. This preview site is only accessible by maintainers of the project to prevent running untrusted code in Vercel builds.
================================================
FILE: docs/astro.config.mjs
================================================
// @ts-check
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";
import sitemap from "@astrojs/sitemap";
import vercel from "@astrojs/vercel";
import partytown from "@astrojs/partytown";
import tailwindcss from "@tailwindcss/vite";
import react from "@astrojs/react";
import starlightLinksValidator from "starlight-links-validator";
import starlightLlmsTxt from "starlight-llms-txt";
import d2 from "astro-d2";
// Check if we're in Vercel environment
const isVercel = globalThis.process?.env?.VERCEL;
export const sidebar = [
{
label: "Getting Started",
autogenerate: { directory: "01-getting-started" },
},
{
label: "Guides",
items: [
{
label: "Terralith to Terragrunt",
autogenerate: { directory: "02-guides/01-terralith-to-terragrunt", collapsed: true },
},
],
collapsed: true,
},
{
label: "Features",
collapsed: true,
items: [
{
label: "Units",
collapsed: true,
autogenerate: { directory: "03-features/01-units", collapsed: true },
},
{
label: "Stacks",
collapsed: true,
autogenerate: { directory: "03-features/02-stacks", collapsed: true },
},
{
label: "Catalog",
collapsed: true,
autogenerate: { directory: "03-features/06-catalog", collapsed: true },
},
{
label: "Caching",
collapsed: true,
autogenerate: { directory: "03-features/07-caching", collapsed: true },
},
{
label: "Filters",
collapsed: true,
autogenerate: { directory: "03-features/08-filter", collapsed: true },
},
],
},
{
label: "Reference",
collapsed: true,
items: [
{
label: "HCL",
autogenerate: { directory: "04-reference/01-hcl", collapsed: true },
},
{
label: "CLI",
collapsed: true,
items: [
{ label: "Overview", slug: "reference/cli" },
{
label: "Commands",
autogenerate: {
directory: "04-reference/02-cli/02-commands",
collapsed: true,
},
},
{ label: "Global Flags", slug: "reference/cli/global-flags" },
],
},
{ label: "Strict Controls", slug: "reference/strict-controls" },
{ label: "Experiments", slug: "reference/experiments" },
{
label: "Supported Versions",
slug: "reference/supported-versions",
},
{ label: "Lock Files", slug: "reference/lock-files" },
{
label: "Logging",
autogenerate: { directory: "04-reference/07-logging", collapsed: true },
},
{ label: "Terragrunt Cache", slug: "reference/terragrunt-cache" },
],
},
{
label: "Community",
autogenerate: { directory: "05-community", collapsed: true },
collapsed: true,
},
{
label: "Troubleshooting",
autogenerate: { directory: "06-troubleshooting", collapsed: true },
collapsed: true,
},
{
label: "Process",
autogenerate: { directory: "07-process", collapsed: true },
collapsed: true,
},
{
label: "Migrate",
autogenerate: { directory: "08-migrate", collapsed: true },
collapsed: true,
},
];
// https://astro.build/config
export default defineConfig({
site: "https://docs.terragrunt.com",
base: "/",
output: isVercel ? "server" : "static",
adapter: isVercel
? vercel({
imageService: true,
isr: {
expiration: 60 * 60 * 24, // 24 hours
},
})
: undefined,
integrations: [
// We use React for the shadcn/ui components.
react(),
starlight({
title: "Terragrunt",
description: "Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.",
editLink: {
// TODO: update this once the docs live in `docs`.
baseUrl:
"https://github.com/gruntwork-io/terragrunt/edit/main/docs",
},
customCss: ["./src/styles/global.css"],
head: [
{
tag: 'meta',
attrs: {
name: 'description',
content: 'Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.',
},
},
{
tag: 'meta',
attrs: {
property: 'og:title',
content: 'Terragrunt',
},
},
{
tag: 'meta',
attrs: {
property: 'og:description',
content: 'Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.',
},
},
{
tag: 'meta',
attrs: {
property: 'og:type',
content: 'website',
},
},
{
tag: 'meta',
attrs: {
property: 'og:url',
content: 'https://docs.terragrunt.com',
},
},
{
tag: 'meta',
attrs: {
name: 'twitter:card',
content: 'summary_large_image',
},
},
{
tag: 'meta',
attrs: {
name: 'twitter:title',
content: 'Terragrunt',
},
},
{
tag: 'meta',
attrs: {
name: 'twitter:description',
content: 'Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.',
},
},
],
components: {
Header: "./src/components/Header.astro",
PageSidebar: "./src/components/PageSidebar.astro",
SiteTitle: "./src/components/SiteTitle.astro",
SkipLink: "./src/components/SkipLink.astro",
},
logo: {
dark: "/src/assets/horizontal-logo-light.svg",
light: "/src/assets/horizontal-logo-dark.svg",
},
social: [
{
href: "/community/invite",
icon: "discord",
label: "Discord",
},
],
sidebar: sidebar,
plugins: [
starlightLinksValidator({
exclude: [
// Used in the docs for OpenTelemetry
"http://localhost:16686/",
"http://localhost:9090/",
// Unfortunately, these have to be ignored, as they're referencing content
// that is generated outside the contents of the markdown file.
"/reference/cli/commands/run#*",
"/reference/cli/commands/run/#*",
"/reference/cli/commands/list#*",
"/reference/cli/commands
Showing preview only (212K chars total). Download the full file or copy to clipboard to get everything.
gitextract_0weulqda/
├── .coderabbit.yaml
├── .codespellrc
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── 01-bug_report.md
│ │ ├── 02-bad_error_message.md
│ │ ├── 03-rfc.yml
│ │ └── 04-feature-request.md
│ ├── assets/
│ │ └── release-assets-config.json
│ ├── cloud-nuke/
│ │ └── config.yml
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ ├── scripts/
│ │ ├── announce-release.sh
│ │ ├── gopls/
│ │ │ ├── check-for-changes.sh
│ │ │ ├── create-issue.js
│ │ │ ├── create-pr.js
│ │ │ └── run.sh
│ │ ├── release/
│ │ │ ├── README.md
│ │ │ ├── check-release-exists.sh
│ │ │ ├── create-archives.sh
│ │ │ ├── generate-checksums.sh
│ │ │ ├── generate-upload-summary.sh
│ │ │ ├── get-version.sh
│ │ │ ├── install-go-winres.ps1
│ │ │ ├── install-gon.sh
│ │ │ ├── lib-release-config.sh
│ │ │ ├── prepare-macos-artifacts.sh
│ │ │ ├── prepare-windows-artifacts.ps1
│ │ │ ├── restore-p12-certificate.ps1
│ │ │ ├── set-permissions.sh
│ │ │ ├── sign-checksums.sh
│ │ │ ├── sign-macos-binaries.sh
│ │ │ ├── sign-windows.ps1
│ │ │ ├── upload-assets.sh
│ │ │ ├── verify-assets-uploaded.sh
│ │ │ ├── verify-binaries-downloaded.sh
│ │ │ ├── verify-files.sh
│ │ │ ├── verify-smctl.ps1
│ │ │ └── verify-static-binary.sh
│ │ └── setup/
│ │ ├── cas.sh
│ │ ├── engine.sh
│ │ ├── experiment-mode.sh
│ │ ├── gcp.sh
│ │ ├── generate-mocks.sh
│ │ ├── generate-secrets.sh
│ │ ├── mac-sign.sh
│ │ ├── provider-cache-server.sh
│ │ ├── run-setup-scripts.sh
│ │ ├── sops.sh
│ │ ├── ssh.sh
│ │ ├── terraform-switch-latest.sh
│ │ ├── terraform-switch.sh
│ │ ├── tofu-switch.sh
│ │ └── windows-setup.ps1
│ └── workflows/
│ ├── announce-release.yml
│ ├── base-test.yml
│ ├── build-no-proxy.yml
│ ├── build.yml
│ ├── ci.yml
│ ├── cloud-nuke.yml
│ ├── codespell.yml
│ ├── flake.yml
│ ├── fuzz.yml
│ ├── go-mod-tidy-check.yml
│ ├── gopls.yml
│ ├── install-script-test.yml
│ ├── integration-test.yml
│ ├── license-check.yml
│ ├── lint.yml
│ ├── markdownlint.yml
│ ├── oidc-integration-test.yml
│ ├── precommit.yml
│ ├── release.yml
│ ├── sign-macos.yml
│ ├── sign-windows.yml
│ ├── stale.yml
│ └── update-codified-remote-deps.yml
├── .gitignore
├── .golangci.yml
├── .gon_amd64.hcl
├── .gon_arm64.hcl
├── .licensei.toml
├── .markdownlint-cli2.yaml
├── .pre-commit-config.yaml
├── .sonarcloud.properties
├── CODEOWNERS
├── KEYS
├── LICENSE.txt
├── Makefile
├── README.md
├── SECURITY.md
├── docs/
│ ├── .gitignore
│ ├── .vercelignore
│ ├── README.md
│ ├── astro.config.mjs
│ ├── components.json
│ ├── mise.toml
│ ├── package.json
│ ├── public/
│ │ ├── install
│ │ ├── robots.txt
│ │ └── schemas/
│ │ ├── auth-provider-cmd/
│ │ │ ├── v1/
│ │ │ │ └── schema.json
│ │ │ └── v2/
│ │ │ └── schema.json
│ │ └── run/
│ │ └── report/
│ │ ├── v1/
│ │ │ └── schema.json
│ │ ├── v2/
│ │ │ └── schema.json
│ │ ├── v3/
│ │ │ └── schema.json
│ │ └── v4/
│ │ └── schema.json
│ ├── src/
│ │ ├── assets/
│ │ │ └── icons/
│ │ │ └── terragrunt-icon-accent.astro
│ │ ├── components/
│ │ │ ├── Command.astro
│ │ │ ├── CompactFooter.astro
│ │ │ ├── CompatibilityTable.astro
│ │ │ ├── Flag.astro
│ │ │ ├── Header.astro
│ │ │ ├── InstallTab.astro
│ │ │ ├── InstallTabs.astro
│ │ │ ├── PageSidebar.astro
│ │ │ ├── SectionSpacer.astro
│ │ │ ├── SiteTitle.astro
│ │ │ ├── SkipLink.astro
│ │ │ ├── ThemeToggle.astro
│ │ │ ├── dv-IconButton.astro
│ │ │ ├── ui/
│ │ │ │ ├── Button.tsx
│ │ │ │ └── ButtonLink.tsx
│ │ │ └── vendored/
│ │ │ └── starlight/
│ │ │ ├── Card.astro
│ │ │ ├── FileTree.astro
│ │ │ ├── Icon.astro
│ │ │ ├── Icons.ts
│ │ │ ├── README.md
│ │ │ ├── file-tree-icons.ts
│ │ │ └── rehype-file-tree.ts
│ │ ├── content/
│ │ │ └── docs/
│ │ │ ├── 01-getting-started/
│ │ │ │ ├── 01-quick-start.mdx
│ │ │ │ ├── 02-overview.mdx
│ │ │ │ ├── 03-install.mdx
│ │ │ │ └── 04-terminology.md
│ │ │ ├── 02-guides/
│ │ │ │ └── 01-terralith-to-terragrunt/
│ │ │ │ ├── 01-introduction.md
│ │ │ │ ├── 02-overview.md
│ │ │ │ ├── 03-setup.mdx
│ │ │ │ ├── 04-step-1-starting-the-terralith.mdx
│ │ │ │ ├── 05-step-2-refactoring.mdx
│ │ │ │ ├── 06-step-3-adding-dev.mdx
│ │ │ │ ├── 07-step-4-breaking-the-terralith.mdx
│ │ │ │ ├── 08-step-5-adding-terragrunt.mdx
│ │ │ │ ├── 09-step-6-breaking-the-terralith-further.mdx
│ │ │ │ ├── 10-step-7-taking-advantage-of-terragrunt-stacks.mdx
│ │ │ │ ├── 11-step-8-refactoring-state-with-terragrunt-stacks.mdx
│ │ │ │ └── 12-wrap-up.mdx
│ │ │ ├── 03-features/
│ │ │ │ ├── 01-units/
│ │ │ │ │ ├── 02-includes.mdx
│ │ │ │ │ ├── 03-state-backend.mdx
│ │ │ │ │ ├── 04-extra-arguments.mdx
│ │ │ │ │ ├── 05-authentication.mdx
│ │ │ │ │ ├── 06-hooks.mdx
│ │ │ │ │ ├── 07-auto-init.mdx
│ │ │ │ │ ├── 08-runtime-control.mdx
│ │ │ │ │ ├── 09-engine.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ ├── 02-stacks/
│ │ │ │ │ ├── 02-implicit.mdx
│ │ │ │ │ ├── 03-explicit.mdx
│ │ │ │ │ ├── 04-stack-operations.mdx
│ │ │ │ │ ├── 06-run-queue.mdx
│ │ │ │ │ ├── 07-run-report.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ ├── 06-catalog/
│ │ │ │ │ ├── 02-tui.mdx
│ │ │ │ │ ├── 03-scaffold.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ ├── 07-caching/
│ │ │ │ │ ├── 02-provider-cache-server.mdx
│ │ │ │ │ ├── 03-auto-provider-cache-dir.mdx
│ │ │ │ │ ├── 04-cas.mdx
│ │ │ │ │ └── index.mdx
│ │ │ │ └── 08-filter/
│ │ │ │ ├── 02-name.mdx
│ │ │ │ ├── 03-path.mdx
│ │ │ │ ├── 04-attributes.mdx
│ │ │ │ ├── 05-graph.mdx
│ │ │ │ ├── 06-git.mdx
│ │ │ │ ├── 07-combining.mdx
│ │ │ │ ├── 08-filters-file.mdx
│ │ │ │ └── index.mdx
│ │ │ ├── 04-reference/
│ │ │ │ ├── 01-hcl/
│ │ │ │ │ ├── 01-overview.mdx
│ │ │ │ │ ├── 02-blocks.mdx
│ │ │ │ │ ├── 03-attributes.mdx
│ │ │ │ │ └── 04-functions.mdx
│ │ │ │ ├── 02-cli/
│ │ │ │ │ ├── 01-overview.mdx
│ │ │ │ │ ├── 02-commands/
│ │ │ │ │ │ ├── 0-opentofu-shortcuts.md
│ │ │ │ │ │ ├── 0100-run.md
│ │ │ │ │ │ ├── 0200-exec.md
│ │ │ │ │ │ ├── 0500-catalog.md
│ │ │ │ │ │ ├── 0600-scaffold.md
│ │ │ │ │ │ ├── 0700-find.md
│ │ │ │ │ │ ├── 0800-list.md
│ │ │ │ │ │ ├── 1100-render.md
│ │ │ │ │ │ ├── backend/
│ │ │ │ │ │ │ ├── 0300-bootstrap.md
│ │ │ │ │ │ │ ├── 0301-migrate.md
│ │ │ │ │ │ │ └── 0302-delete.md
│ │ │ │ │ │ ├── dag/
│ │ │ │ │ │ │ └── 1000-graph.md
│ │ │ │ │ │ ├── hcl/
│ │ │ │ │ │ │ ├── 0900-fmt.md
│ │ │ │ │ │ │ └── 0901-validate.md
│ │ │ │ │ │ ├── info/
│ │ │ │ │ │ │ └── 1200-print.md
│ │ │ │ │ │ └── stack/
│ │ │ │ │ │ ├── 0400-generate.md
│ │ │ │ │ │ ├── 0401-run.md
│ │ │ │ │ │ ├── 0402-output.md
│ │ │ │ │ │ └── 0403-clean.md
│ │ │ │ │ └── 98-global-flags.mdx
│ │ │ │ ├── 03-strict-controls.mdx
│ │ │ │ ├── 04-experiments.md
│ │ │ │ ├── 05-supported-versions.mdx
│ │ │ │ ├── 06-lock-files.mdx
│ │ │ │ ├── 07-logging/
│ │ │ │ │ ├── 01-overview.md
│ │ │ │ │ └── 02-formatting.md
│ │ │ │ └── 08-terragrunt-cache.md
│ │ │ ├── 05-community/
│ │ │ │ ├── 01-contributing.mdx
│ │ │ │ ├── 02-support.md
│ │ │ │ └── 03-license.md
│ │ │ ├── 06-troubleshooting/
│ │ │ │ ├── 01-debugging.mdx
│ │ │ │ ├── 02-open-telemetry.md
│ │ │ │ └── 03-performance.mdx
│ │ │ ├── 07-process/
│ │ │ │ ├── 01-1-0-guarantees.mdx
│ │ │ │ ├── 02-cli-rules.mdx
│ │ │ │ └── 03-releases.mdx
│ │ │ └── 08-migrate/
│ │ │ ├── 01-migrating-from-root-terragrunt-hcl.md
│ │ │ ├── 02-upgrading-to-terragrunt-0-19-x.md
│ │ │ ├── 03-cli-redesign.md
│ │ │ ├── 04-terragrunt-stacks.mdx
│ │ │ ├── 05-bare-include.md
│ │ │ └── 06-deprecated-attributes.mdx
│ │ ├── content.config.ts
│ │ ├── data/
│ │ │ ├── commands/
│ │ │ │ ├── backend/
│ │ │ │ │ ├── bootstrap.mdx
│ │ │ │ │ ├── delete.mdx
│ │ │ │ │ └── migrate.mdx
│ │ │ │ ├── catalog.mdx
│ │ │ │ ├── dag/
│ │ │ │ │ └── graph.mdx
│ │ │ │ ├── exec.mdx
│ │ │ │ ├── find.mdx
│ │ │ │ ├── hcl/
│ │ │ │ │ ├── fmt.mdx
│ │ │ │ │ └── validate.mdx
│ │ │ │ ├── info/
│ │ │ │ │ └── print.mdx
│ │ │ │ ├── list.mdx
│ │ │ │ ├── opentofu-shortcuts.mdx
│ │ │ │ ├── render.mdx
│ │ │ │ ├── run.mdx
│ │ │ │ ├── scaffold.mdx
│ │ │ │ └── stack/
│ │ │ │ ├── clean.mdx
│ │ │ │ ├── generate.mdx
│ │ │ │ ├── output.mdx
│ │ │ │ └── run.mdx
│ │ │ ├── compatibility/
│ │ │ │ └── compatibility.json
│ │ │ └── flags/
│ │ │ ├── all.mdx
│ │ │ ├── auth-provider-cmd.mdx
│ │ │ ├── backend-bootstrap-all.mdx
│ │ │ ├── backend-bootstrap-config.mdx
│ │ │ ├── backend-bootstrap-download-dir.mdx
│ │ │ ├── backend-delete-all.mdx
│ │ │ ├── backend-delete-config.mdx
│ │ │ ├── backend-delete-download-dir.mdx
│ │ │ ├── backend-delete-force.mdx
│ │ │ ├── backend-migrate-config.mdx
│ │ │ ├── backend-migrate-download-dir.mdx
│ │ │ ├── backend-migrate-force.mdx
│ │ │ ├── catalog-no-hooks.mdx
│ │ │ ├── catalog-no-include-root.mdx
│ │ │ ├── catalog-no-shell.mdx
│ │ │ ├── catalog-root-file-name.mdx
│ │ │ ├── config.mdx
│ │ │ ├── dependency-fetch-output-from-state.mdx
│ │ │ ├── destroy-dependencies-check.mdx
│ │ │ ├── disable-bucket-update.mdx
│ │ │ ├── disable-command-validation.mdx
│ │ │ ├── download-dir.mdx
│ │ │ ├── engine-cache-path.mdx
│ │ │ ├── engine-log-level.mdx
│ │ │ ├── engine-skip-check.mdx
│ │ │ ├── experiment-mode.mdx
│ │ │ ├── experiment.mdx
│ │ │ ├── experimental-engine.mdx
│ │ │ ├── fail-fast.mdx
│ │ │ ├── feature.mdx
│ │ │ ├── filter-affected.mdx
│ │ │ ├── filter.mdx
│ │ │ ├── filters-file.mdx
│ │ │ ├── find-dag.mdx
│ │ │ ├── find-dependencies.mdx
│ │ │ ├── find-exclude.mdx
│ │ │ ├── find-external.mdx
│ │ │ ├── find-format.mdx
│ │ │ ├── find-hidden.mdx
│ │ │ ├── find-include.mdx
│ │ │ ├── find-json.mdx
│ │ │ ├── find-no-hidden.mdx
│ │ │ ├── find-reading.mdx
│ │ │ ├── graph.mdx
│ │ │ ├── hcl-fmt-check.mdx
│ │ │ ├── hcl-fmt-diff.mdx
│ │ │ ├── hcl-fmt-exclude-dir.mdx
│ │ │ ├── hcl-fmt-file.mdx
│ │ │ ├── hcl-fmt-filter.mdx
│ │ │ ├── hcl-fmt-stdin.mdx
│ │ │ ├── hcl-validate-inputs.mdx
│ │ │ ├── hcl-validate-json.mdx
│ │ │ ├── hcl-validate-show-config-path.mdx
│ │ │ ├── hcl-validate-strict.mdx
│ │ │ ├── help.mdx
│ │ │ ├── iam-assume-role-duration.mdx
│ │ │ ├── iam-assume-role-session-name.mdx
│ │ │ ├── iam-assume-role-web-identity-token.mdx
│ │ │ ├── iam-assume-role.mdx
│ │ │ ├── in-download-dir.mdx
│ │ │ ├── inputs-debug.mdx
│ │ │ ├── json-out-dir.mdx
│ │ │ ├── list-dag.mdx
│ │ │ ├── list-dependencies.mdx
│ │ │ ├── list-external.mdx
│ │ │ ├── list-format.mdx
│ │ │ ├── list-hidden.mdx
│ │ │ ├── list-long.mdx
│ │ │ ├── list-no-hidden.mdx
│ │ │ ├── list-tree.mdx
│ │ │ ├── log-custom-format.mdx
│ │ │ ├── log-disable.mdx
│ │ │ ├── log-format.mdx
│ │ │ ├── log-level.mdx
│ │ │ ├── log-show-abs-paths.mdx
│ │ │ ├── no-auto-approve.mdx
│ │ │ ├── no-auto-init.mdx
│ │ │ ├── no-auto-provider-cache-dir.mdx
│ │ │ ├── no-auto-retry.mdx
│ │ │ ├── no-color.mdx
│ │ │ ├── no-dependency-fetch-output-from-state.mdx
│ │ │ ├── no-destroy-dependencies-check.mdx
│ │ │ ├── no-engine.mdx
│ │ │ ├── no-filters-file.mdx
│ │ │ ├── no-stack-generate.mdx
│ │ │ ├── no-tip.mdx
│ │ │ ├── no-tips.mdx
│ │ │ ├── non-interactive.mdx
│ │ │ ├── out-dir.mdx
│ │ │ ├── parallelism.mdx
│ │ │ ├── provider-cache-dir.mdx
│ │ │ ├── provider-cache-hostname.mdx
│ │ │ ├── provider-cache-port.mdx
│ │ │ ├── provider-cache-registry-names.mdx
│ │ │ ├── provider-cache-token.mdx
│ │ │ ├── provider-cache.mdx
│ │ │ ├── queue-construct-as.mdx
│ │ │ ├── queue-exclude-dir.mdx
│ │ │ ├── queue-exclude-external.mdx
│ │ │ ├── queue-excludes-file.mdx
│ │ │ ├── queue-ignore-dag-order.mdx
│ │ │ ├── queue-ignore-errors.mdx
│ │ │ ├── queue-include-dir.mdx
│ │ │ ├── queue-include-external.mdx
│ │ │ ├── queue-include-units-reading.mdx
│ │ │ ├── queue-strict-include.mdx
│ │ │ ├── render-all.mdx
│ │ │ ├── render-format.mdx
│ │ │ ├── render-write.mdx
│ │ │ ├── report-file.mdx
│ │ │ ├── report-format.mdx
│ │ │ ├── report-schema-file.mdx
│ │ │ ├── scaffold-no-hooks.mdx
│ │ │ ├── scaffold-no-include-root.mdx
│ │ │ ├── scaffold-no-shell.mdx
│ │ │ ├── scaffold-root-file-name.mdx
│ │ │ ├── scaffold-var-file.mdx
│ │ │ ├── scaffold-var.mdx
│ │ │ ├── source-map.mdx
│ │ │ ├── source-update.mdx
│ │ │ ├── source.mdx
│ │ │ ├── stack-generate-filter.mdx
│ │ │ ├── stack-output-format.mdx
│ │ │ ├── stack-output-json.mdx
│ │ │ ├── stack-output-raw.mdx
│ │ │ ├── strict-control.mdx
│ │ │ ├── strict-mode.mdx
│ │ │ ├── summary-disable.mdx
│ │ │ ├── summary-per-unit.mdx
│ │ │ ├── tf-forward-stdout.mdx
│ │ │ ├── tf-path.mdx
│ │ │ ├── units-that-include.mdx
│ │ │ ├── use-partial-parse-config-cache.mdx
│ │ │ ├── version-manager-file-name.mdx
│ │ │ ├── version.mdx
│ │ │ └── working-dir.mdx
│ │ ├── fixtures/
│ │ │ └── terralith-to-terragrunt/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ └── best-cat/
│ │ │ │ ├── index.js
│ │ │ │ ├── package.json
│ │ │ │ ├── script.js
│ │ │ │ ├── styles.css
│ │ │ │ └── template.html
│ │ │ ├── mise.toml
│ │ │ └── walkthrough/
│ │ │ ├── step-1-starting-the-terralith/
│ │ │ │ └── live/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── data.tf
│ │ │ │ ├── ddb.tf
│ │ │ │ ├── iam.tf
│ │ │ │ ├── lambda.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── s3.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-2-refactoring/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── main.tf
│ │ │ │ ├── moved.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-3-adding-dev/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── main.tf
│ │ │ │ ├── moved.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-4-breaking-the-terralith/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── .auto.tfvars.example
│ │ │ │ │ ├── backend.tf
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── providers.tf
│ │ │ │ │ ├── removed.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── prod/
│ │ │ │ ├── .auto.tfvars.example
│ │ │ │ ├── backend.tf
│ │ │ │ ├── main.tf
│ │ │ │ ├── moved.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── providers.tf
│ │ │ │ ├── removed.tf
│ │ │ │ ├── vars-optional.tf
│ │ │ │ ├── vars-required.tf
│ │ │ │ └── versions.tf
│ │ │ ├── step-5-adding-terragrunt/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── prod/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ ├── step-6-breaking-the-terralith-further/
│ │ │ │ ├── catalog/
│ │ │ │ │ └── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ ├── removed.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── prod/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── moved.tf
│ │ │ │ │ │ ├── removed.tf
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── moved.tf
│ │ │ │ │ ├── removed.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ ├── step-7-taking-advantage-of-terragrunt-stacks/
│ │ │ │ ├── catalog/
│ │ │ │ │ ├── modules/
│ │ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ │ ├── ddb/
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ │ └── versions.tf
│ │ │ │ │ │ ├── iam/
│ │ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ │ └── versions.tf
│ │ │ │ │ │ ├── lambda/
│ │ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ │ └── versions.tf
│ │ │ │ │ │ └── s3/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── units/
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── s3/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── prod/
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── root.hcl
│ │ │ └── step-8-refactoring-state-with-terragrunt-stacks/
│ │ │ ├── catalog/
│ │ │ │ ├── modules/
│ │ │ │ │ ├── best_cat/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ └── vars-required.tf
│ │ │ │ │ ├── ddb/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── iam/
│ │ │ │ │ │ ├── data.tf
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ ├── lambda/
│ │ │ │ │ │ ├── main.tf
│ │ │ │ │ │ ├── outputs.tf
│ │ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ │ └── versions.tf
│ │ │ │ │ └── s3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ ├── outputs.tf
│ │ │ │ │ ├── vars-optional.tf
│ │ │ │ │ ├── vars-required.tf
│ │ │ │ │ └── versions.tf
│ │ │ │ └── units/
│ │ │ │ ├── ddb/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── iam/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── lambda/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── s3/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── live/
│ │ │ ├── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── root.hcl
│ │ ├── layouts/
│ │ │ └── BaseLayout.astro
│ │ ├── lib/
│ │ │ ├── commands/
│ │ │ │ ├── headings/
│ │ │ │ │ └── index.ts
│ │ │ │ └── sidebar/
│ │ │ │ └── index.ts
│ │ │ ├── github.ts
│ │ │ └── utils.ts
│ │ ├── pages/
│ │ │ ├── api/
│ │ │ │ └── v1/
│ │ │ │ └── compatibility/
│ │ │ │ └── [tool].ts
│ │ │ ├── index.astro
│ │ │ └── reference/
│ │ │ └── cli/
│ │ │ └── commands/
│ │ │ └── [...slug].astro
│ │ └── styles/
│ │ ├── global.css
│ │ ├── lists.css
│ │ ├── starlight-right-sidebar.css
│ │ └── starlight-search.css
│ ├── tailwind.config.mjs
│ ├── tests/
│ │ └── install_test.sh
│ ├── tsconfig.json
│ └── vercel.json
├── go.mod
├── go.sum
├── internal/
│ ├── awshelper/
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── policy.go
│ │ └── policy_test.go
│ ├── cache/
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ └── context.go
│ ├── cas/
│ │ ├── .gitignore
│ │ ├── benchmark_test.go
│ │ ├── cas.go
│ │ ├── cas_test.go
│ │ ├── content.go
│ │ ├── content_test.go
│ │ ├── errors.go
│ │ ├── errors_test.go
│ │ ├── getter.go
│ │ ├── getter_ssh_test.go
│ │ ├── getter_test.go
│ │ ├── integration_test.go
│ │ ├── local.go
│ │ ├── race_test.go
│ │ ├── store.go
│ │ ├── store_test.go
│ │ ├── tree.go
│ │ └── tree_test.go
│ ├── cli/
│ │ ├── app.go
│ │ ├── app_test.go
│ │ ├── commands/
│ │ │ ├── aws-provider-patch/
│ │ │ │ ├── aws-provider-patch.go
│ │ │ │ ├── aws-provider-patch_test.go
│ │ │ │ ├── cli.go
│ │ │ │ ├── errors.go
│ │ │ │ └── tofu_extensions_test.go
│ │ │ ├── backend/
│ │ │ │ ├── bootstrap/
│ │ │ │ │ ├── bootstrap.go
│ │ │ │ │ └── cli.go
│ │ │ │ ├── cli.go
│ │ │ │ ├── delete/
│ │ │ │ │ ├── cli.go
│ │ │ │ │ └── delete.go
│ │ │ │ └── migrate/
│ │ │ │ ├── cli.go
│ │ │ │ └── migrate.go
│ │ │ ├── catalog/
│ │ │ │ ├── TESTING.md
│ │ │ │ ├── catalog.go
│ │ │ │ ├── catalog_test.go
│ │ │ │ ├── cli.go
│ │ │ │ └── tui/
│ │ │ │ ├── command/
│ │ │ │ │ └── scaffold.go
│ │ │ │ ├── components/
│ │ │ │ │ └── buttonbar/
│ │ │ │ │ └── buttonbar.go
│ │ │ │ ├── delegate.go
│ │ │ │ ├── keys.go
│ │ │ │ ├── model.go
│ │ │ │ ├── model_test.go
│ │ │ │ ├── testdata/
│ │ │ │ │ └── TestTUIInitialOutput.golden
│ │ │ │ ├── tui.go
│ │ │ │ ├── update.go
│ │ │ │ └── view.go
│ │ │ ├── commands.go
│ │ │ ├── dag/
│ │ │ │ ├── cli.go
│ │ │ │ └── graph/
│ │ │ │ ├── cli.go
│ │ │ │ └── cli_test.go
│ │ │ ├── exec/
│ │ │ │ ├── cli.go
│ │ │ │ ├── exec.go
│ │ │ │ └── options.go
│ │ │ ├── find/
│ │ │ │ ├── cli.go
│ │ │ │ ├── find.go
│ │ │ │ ├── find_test.go
│ │ │ │ └── options.go
│ │ │ ├── hcl/
│ │ │ │ ├── cli.go
│ │ │ │ ├── format/
│ │ │ │ │ ├── cli.go
│ │ │ │ │ ├── errors.go
│ │ │ │ │ ├── format.go
│ │ │ │ │ ├── format_bench_test.go
│ │ │ │ │ ├── format_test.go
│ │ │ │ │ └── testdata/
│ │ │ │ │ └── fixtures/
│ │ │ │ │ ├── a/
│ │ │ │ │ │ ├── b/
│ │ │ │ │ │ │ └── c/
│ │ │ │ │ │ │ ├── d/
│ │ │ │ │ │ │ │ ├── e/
│ │ │ │ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ │ │ │ └── services.hcl
│ │ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── expected.hcl
│ │ │ │ │ ├── ignored/
│ │ │ │ │ │ ├── .gitignore
│ │ │ │ │ │ ├── .history/
│ │ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ │ └── .terragrunt-cache/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── validate/
│ │ │ │ ├── cli.go
│ │ │ │ ├── validate.go
│ │ │ │ └── validate_test.go
│ │ │ ├── help/
│ │ │ │ └── cli.go
│ │ │ ├── info/
│ │ │ │ ├── cli.go
│ │ │ │ ├── print/
│ │ │ │ │ ├── cli.go
│ │ │ │ │ └── print.go
│ │ │ │ └── strict/
│ │ │ │ └── command.go
│ │ │ ├── list/
│ │ │ │ ├── cli.go
│ │ │ │ ├── list.go
│ │ │ │ ├── list_test.go
│ │ │ │ └── options.go
│ │ │ ├── render/
│ │ │ │ ├── cli.go
│ │ │ │ ├── options.go
│ │ │ │ ├── render.go
│ │ │ │ └── render_test.go
│ │ │ ├── run/
│ │ │ │ ├── cli.go
│ │ │ │ ├── flags.go
│ │ │ │ ├── help.go
│ │ │ │ └── run.go
│ │ │ ├── scaffold/
│ │ │ │ ├── cli.go
│ │ │ │ ├── scaffold.go
│ │ │ │ └── scaffold_test.go
│ │ │ ├── shortcuts.go
│ │ │ ├── stack/
│ │ │ │ ├── cli.go
│ │ │ │ ├── output.go
│ │ │ │ ├── output_test.go
│ │ │ │ └── stack.go
│ │ │ └── version/
│ │ │ └── cli.go
│ │ ├── flags/
│ │ │ ├── deprecated_flag.go
│ │ │ ├── error_handler.go
│ │ │ ├── error_handler_test.go
│ │ │ ├── errors.go
│ │ │ ├── flag.go
│ │ │ ├── flag_opts.go
│ │ │ ├── flag_test.go
│ │ │ ├── global/
│ │ │ │ └── flags.go
│ │ │ ├── prefix.go
│ │ │ └── shared/
│ │ │ ├── all.go
│ │ │ ├── auth.go
│ │ │ ├── backend.go
│ │ │ ├── config.go
│ │ │ ├── doc.go
│ │ │ ├── download.go
│ │ │ ├── errors.go
│ │ │ ├── failfast.go
│ │ │ ├── feature.go
│ │ │ ├── filter.go
│ │ │ ├── graph.go
│ │ │ ├── iamassumerole.go
│ │ │ ├── inputsdebug.go
│ │ │ ├── parallelism.go
│ │ │ ├── queue.go
│ │ │ ├── scaffold.go
│ │ │ └── tfpath.go
│ │ ├── help.go
│ │ └── help_test.go
│ ├── clihelper/
│ │ ├── app.go
│ │ ├── args.go
│ │ ├── args_test.go
│ │ ├── autocomplete.go
│ │ ├── bool_flag.go
│ │ ├── bool_flag_test.go
│ │ ├── category.go
│ │ ├── command.go
│ │ ├── command_test.go
│ │ ├── commands.go
│ │ ├── context.go
│ │ ├── errors.go
│ │ ├── exit_code.go
│ │ ├── flag.go
│ │ ├── flag_test.go
│ │ ├── flags.go
│ │ ├── flags_test.go
│ │ ├── funcs.go
│ │ ├── generic_flag.go
│ │ ├── generic_flag_test.go
│ │ ├── help.go
│ │ ├── map_flag.go
│ │ ├── map_flag_test.go
│ │ ├── slice_flag.go
│ │ ├── slice_flag_test.go
│ │ ├── sort.go
│ │ └── sort_test.go
│ ├── cloner/
│ │ ├── clone.go
│ │ └── cloner.go
│ ├── codegen/
│ │ ├── codegen.go
│ │ ├── errors.go
│ │ ├── generate.go
│ │ └── generate_test.go
│ ├── component/
│ │ ├── component.go
│ │ ├── component_test.go
│ │ ├── stack.go
│ │ ├── unit.go
│ │ └── unit_output.go
│ ├── configbridge/
│ │ └── bridge.go
│ ├── ctyhelper/
│ │ ├── helper.go
│ │ └── helper_test.go
│ ├── discovery/
│ │ ├── benchmark_test.go
│ │ ├── constructor.go
│ │ ├── discovery.go
│ │ ├── discovery_integration_test.go
│ │ ├── discovery_test.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── filter_test.go
│ │ ├── graph_option.go
│ │ ├── graph_target_test.go
│ │ ├── helpers.go
│ │ ├── options.go
│ │ ├── phase_filesystem.go
│ │ ├── phase_graph.go
│ │ ├── phase_parse.go
│ │ ├── phase_relationship.go
│ │ ├── phase_test.go
│ │ ├── phase_worktree.go
│ │ ├── phase_worktree_integration_test.go
│ │ ├── phase_worktree_test.go
│ │ └── types.go
│ ├── engine/
│ │ ├── engine.go
│ │ ├── engine_test.go
│ │ ├── public_keys.go
│ │ ├── types.go
│ │ └── verification.go
│ ├── errorconfig/
│ │ ├── types.go
│ │ └── types_test.go
│ ├── errors/
│ │ ├── errors.go
│ │ ├── export.go
│ │ ├── multierror.go
│ │ └── util.go
│ ├── experiment/
│ │ ├── errors.go
│ │ ├── experiment.go
│ │ ├── experiment_test.go
│ │ └── warnings.go
│ ├── filter/
│ │ ├── ast.go
│ │ ├── ast_test.go
│ │ ├── candidacy.go
│ │ ├── candidacy_test.go
│ │ ├── classifier.go
│ │ ├── classifier_test.go
│ │ ├── complex_test.go
│ │ ├── diagnostic.go
│ │ ├── diagnostic_test.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── evaluator.go
│ │ ├── evaluator_test.go
│ │ ├── examples_test.go
│ │ ├── filter.go
│ │ ├── filter_test.go
│ │ ├── filters.go
│ │ ├── filters_test.go
│ │ ├── fuzz_test.go
│ │ ├── hints.go
│ │ ├── hints_test.go
│ │ ├── lexer.go
│ │ ├── lexer_test.go
│ │ ├── matcher.go
│ │ ├── parser.go
│ │ ├── parser_test.go
│ │ ├── telemetry.go
│ │ ├── telemetry_test.go
│ │ ├── token.go
│ │ └── walk.go
│ ├── gcphelper/
│ │ ├── config.go
│ │ └── config_test.go
│ ├── git/
│ │ ├── benchmark_test.go
│ │ ├── diff.go
│ │ ├── errors.go
│ │ ├── git.go
│ │ ├── git_test.go
│ │ ├── gogit.go
│ │ ├── gogit_test.go
│ │ └── tree.go
│ ├── github/
│ │ ├── client.go
│ │ └── client_test.go
│ ├── hclhelper/
│ │ ├── wrap.go
│ │ └── wrap_test.go
│ ├── iacargs/
│ │ ├── boolean_args_test.go
│ │ ├── iacargs.go
│ │ └── iacargs_test.go
│ ├── iam/
│ │ └── iam.go
│ ├── locks/
│ │ └── lock.go
│ ├── os/
│ │ ├── exec/
│ │ │ ├── cmd.go
│ │ │ ├── cmd_unix_test.go
│ │ │ ├── cmd_windows_test.go
│ │ │ ├── console_windows_test.go
│ │ │ ├── opts.go
│ │ │ ├── ptty_unix.go
│ │ │ ├── ptty_windows.go
│ │ │ └── testdata/
│ │ │ ├── infinite_loop.bat
│ │ │ ├── test_exit_code.bat
│ │ │ ├── test_exit_code.sh
│ │ │ ├── test_graceful_shutdown.sh
│ │ │ ├── test_sigint_multiple.sh
│ │ │ └── test_sigint_wait.sh
│ │ ├── signal/
│ │ │ ├── context_canceled.go
│ │ │ ├── signal.go
│ │ │ ├── signal_unix.go
│ │ │ └── signal_windows.go
│ │ └── stdout/
│ │ └── stdout.go
│ ├── prepare/
│ │ └── prepare.go
│ ├── providercache/
│ │ ├── options/
│ │ │ └── options.go
│ │ ├── providercache.go
│ │ ├── providercache_test.go
│ │ └── resolve_modules_url_test.go
│ ├── queue/
│ │ ├── queue.go
│ │ └── queue_test.go
│ ├── remotestate/
│ │ ├── backend/
│ │ │ ├── backend.go
│ │ │ ├── common.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── errors.go
│ │ │ ├── gcs/
│ │ │ │ ├── backend.go
│ │ │ │ ├── backend_test.go
│ │ │ │ ├── client.go
│ │ │ │ ├── config.go
│ │ │ │ ├── config_test.go
│ │ │ │ ├── errors.go
│ │ │ │ └── remote_state_config.go
│ │ │ ├── normalize.go
│ │ │ ├── normalize_test.go
│ │ │ └── s3/
│ │ │ ├── backend.go
│ │ │ ├── backend_test.go
│ │ │ ├── client.go
│ │ │ ├── client_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── counting_semaphore.go
│ │ │ ├── counting_semaphore_test.go
│ │ │ ├── errors.go
│ │ │ ├── remote_state_config.go
│ │ │ ├── remote_state_config_test.go
│ │ │ └── retryer.go
│ │ ├── config.go
│ │ ├── remote_state.go
│ │ ├── remote_state_test.go
│ │ ├── terraform_state_file.go
│ │ └── terraform_state_file_test.go
│ ├── report/
│ │ ├── colors.go
│ │ ├── report.go
│ │ ├── report_test.go
│ │ ├── summary.go
│ │ └── writer.go
│ ├── retry/
│ │ └── defaults.go
│ ├── runner/
│ │ ├── common/
│ │ │ ├── options.go
│ │ │ ├── runner.go
│ │ │ └── unit_runner.go
│ │ ├── graph/
│ │ │ └── graph.go
│ │ ├── run/
│ │ │ ├── context.go
│ │ │ ├── creds/
│ │ │ │ ├── getter.go
│ │ │ │ └── providers/
│ │ │ │ ├── amazonsts/
│ │ │ │ │ └── provider.go
│ │ │ │ ├── externalcmd/
│ │ │ │ │ ├── provider.go
│ │ │ │ │ ├── schema.go
│ │ │ │ │ └── schema_test.go
│ │ │ │ └── provider.go
│ │ │ ├── debug.go
│ │ │ ├── download_source.go
│ │ │ ├── download_source_test.go
│ │ │ ├── errors.go
│ │ │ ├── file_copy_getter.go
│ │ │ ├── hook.go
│ │ │ ├── hook_internal_test.go
│ │ │ ├── options.go
│ │ │ ├── prepare_internal_test.go
│ │ │ ├── run.go
│ │ │ ├── run_test.go
│ │ │ ├── symlink_preserving_git_getter.go
│ │ │ ├── tofu_extensions_test.go
│ │ │ ├── version_check.go
│ │ │ ├── version_check_internal_test.go
│ │ │ └── version_check_test.go
│ │ ├── runall/
│ │ │ ├── errors.go
│ │ │ ├── runall.go
│ │ │ └── runall_test.go
│ │ ├── runcfg/
│ │ │ ├── types.go
│ │ │ ├── util.go
│ │ │ └── util_test.go
│ │ ├── runner.go
│ │ └── runnerpool/
│ │ ├── builder.go
│ │ ├── builder_helpers.go
│ │ ├── controller.go
│ │ ├── controller_test.go
│ │ ├── errors.go
│ │ ├── graph_fallback_test.go
│ │ ├── helpers_test.go
│ │ ├── runner.go
│ │ ├── runner_test.go
│ │ ├── writer.go
│ │ └── writer_test.go
│ ├── services/
│ │ └── catalog/
│ │ ├── catalog.go
│ │ ├── catalog_test.go
│ │ └── module/
│ │ ├── doc.go
│ │ ├── doc_test.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── repo.go
│ │ ├── repo_test.go
│ │ └── testdata/
│ │ └── find_modules/
│ │ ├── gitdir/
│ │ │ ├── HEAD
│ │ │ └── config
│ │ └── modules/
│ │ ├── eks-alb-ingress-controller/
│ │ │ ├── README.md
│ │ │ ├── main.tf
│ │ │ └── variables.tf
│ │ ├── eks-alb-ingress-controller-iam-policy/
│ │ │ ├── README.md
│ │ │ ├── main.tf
│ │ │ └── variables.tf
│ │ └── eks-aws-auth-merger/
│ │ ├── README.adoc
│ │ ├── core-concepts.md
│ │ ├── main.tf
│ │ └── variables.tf
│ ├── shell/
│ │ ├── error_explainer.go
│ │ ├── error_explainer_test.go
│ │ ├── git.go
│ │ ├── prompt.go
│ │ ├── run_cmd.go
│ │ ├── run_cmd_output_test.go
│ │ ├── run_cmd_test.go
│ │ ├── run_cmd_unix_test.go
│ │ ├── run_cmd_windows_test.go
│ │ └── testdata/
│ │ ├── test_outputs.sh
│ │ ├── test_sigint_wait.bat
│ │ └── test_sigint_wait.sh
│ ├── stacks/
│ │ ├── clean/
│ │ │ └── clean.go
│ │ ├── generate/
│ │ │ └── generate.go
│ │ └── output/
│ │ └── output.go
│ ├── strict/
│ │ ├── category.go
│ │ ├── control.go
│ │ ├── control_test.go
│ │ ├── controls/
│ │ │ ├── control.go
│ │ │ ├── controls.go
│ │ │ ├── deprecated_command.go
│ │ │ ├── deprecated_env_var.go
│ │ │ └── deprecated_flag_name.go
│ │ ├── errors.go
│ │ ├── status.go
│ │ ├── strict.go
│ │ └── view/
│ │ ├── plaintext/
│ │ │ ├── plaintext.go
│ │ │ ├── render.go
│ │ │ └── template.go
│ │ ├── render.go
│ │ ├── view.go
│ │ └── writer.go
│ ├── telemetry/
│ │ ├── context.go
│ │ ├── errors.go
│ │ ├── meter.go
│ │ ├── meter_test.go
│ │ ├── opts.go
│ │ ├── telemeter.go
│ │ ├── tracer.go
│ │ ├── tracer_test.go
│ │ └── util.go
│ ├── tf/
│ │ ├── cache/
│ │ │ ├── config.go
│ │ │ ├── controllers/
│ │ │ │ ├── discovery.go
│ │ │ │ ├── downloader.go
│ │ │ │ └── provider.go
│ │ │ ├── handlers/
│ │ │ │ ├── common_provider.go
│ │ │ │ ├── direct_provider.go
│ │ │ │ ├── errors.go
│ │ │ │ ├── filesystem_mirror_provider.go
│ │ │ │ ├── network_mirror_provider.go
│ │ │ │ ├── provider.go
│ │ │ │ ├── provider_test.go
│ │ │ │ ├── proxy_provider.go
│ │ │ │ └── registry_urls.go
│ │ │ ├── helpers/
│ │ │ │ ├── client.go
│ │ │ │ ├── http.go
│ │ │ │ └── reverse_proxy.go
│ │ │ ├── middleware/
│ │ │ │ ├── key_auth.go
│ │ │ │ ├── logger.go
│ │ │ │ ├── package.go
│ │ │ │ └── recover.go
│ │ │ ├── models/
│ │ │ │ ├── helper.go
│ │ │ │ ├── provider.go
│ │ │ │ └── provider_test.go
│ │ │ ├── router/
│ │ │ │ ├── controller.go
│ │ │ │ └── router.go
│ │ │ ├── server.go
│ │ │ └── services/
│ │ │ ├── provider_cache.go
│ │ │ └── service.go
│ │ ├── cliconfig/
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── credentials.go
│ │ │ ├── provider_installation.go
│ │ │ └── user_config.go
│ │ ├── context.go
│ │ ├── detailed_exitcode.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── getproviders/
│ │ │ ├── constraints.go
│ │ │ ├── constraints_test.go
│ │ │ ├── hash.go
│ │ │ ├── hash_test.go
│ │ │ ├── lock.go
│ │ │ ├── lock_test.go
│ │ │ ├── mocks/
│ │ │ │ ├── mock_lock.go
│ │ │ │ └── mock_provider.go
│ │ │ ├── package_authentication.go
│ │ │ ├── package_authentication_test.go
│ │ │ ├── provider.go
│ │ │ ├── public_keys.go
│ │ │ └── testdata/
│ │ │ └── filesystem-mirror/
│ │ │ └── tfe.example.com/
│ │ │ └── AwesomeCorp/
│ │ │ └── happycloud/
│ │ │ └── 0.1.0-alpha.2/
│ │ │ └── darwin_amd64/
│ │ │ ├── extra-data.txt
│ │ │ └── terraform-provider-happycloud
│ │ ├── getter.go
│ │ ├── getter_test.go
│ │ ├── log.go
│ │ ├── run_cmd.go
│ │ ├── run_cmd_test.go
│ │ ├── source.go
│ │ ├── source_test.go
│ │ ├── testdata/
│ │ │ └── test_outputs.sh
│ │ ├── tf.go
│ │ └── tf_test.go
│ ├── tfimpl/
│ │ └── tfimpl.go
│ ├── tflint/
│ │ ├── README.md
│ │ ├── tflint.go
│ │ └── tflint_test.go
│ ├── tips/
│ │ ├── errors.go
│ │ ├── tip.go
│ │ ├── tip_test.go
│ │ └── tips.go
│ ├── util/
│ │ ├── collections.go
│ │ ├── collections_test.go
│ │ ├── datetime.go
│ │ ├── datetime_test.go
│ │ ├── dirs.go
│ │ ├── file.go
│ │ ├── file_test.go
│ │ ├── file_tofu_test.go
│ │ ├── hash.go
│ │ ├── jsons.go
│ │ ├── jsons_test.go
│ │ ├── lockfile.go
│ │ ├── locks.go
│ │ ├── locks_test.go
│ │ ├── random.go
│ │ ├── random_test.go
│ │ ├── reflect.go
│ │ ├── reflect_test.go
│ │ ├── retry.go
│ │ ├── shell.go
│ │ ├── shell_test.go
│ │ ├── sync_writer.go
│ │ ├── testdata/
│ │ │ ├── fixture-glob-canonical/
│ │ │ │ ├── module-a/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── module-b/
│ │ │ │ ├── module-b-child/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── fixture-sanitize-path/
│ │ │ └── env/
│ │ │ └── unit/
│ │ │ └── .terraform-version
│ │ ├── trap_writer.go
│ │ ├── util.go
│ │ └── writer_notifier.go
│ ├── vfs/
│ │ ├── vfs.go
│ │ └── vfs_test.go
│ ├── view/
│ │ ├── diagnostic/
│ │ │ ├── diagnostic.go
│ │ │ ├── expression_value.go
│ │ │ ├── extra.go
│ │ │ ├── function.go
│ │ │ ├── range.go
│ │ │ ├── servity.go
│ │ │ └── snippet.go
│ │ ├── human_render.go
│ │ ├── json_render.go
│ │ ├── view.go
│ │ └── writer.go
│ ├── worker/
│ │ ├── worker.go
│ │ └── worker_test.go
│ ├── worktrees/
│ │ ├── worktrees.go
│ │ └── worktrees_test.go
│ └── writer/
│ └── writer.go
├── main.go
├── mise.cicd.toml
├── mise.toml
├── pkg/
│ ├── config/
│ │ ├── cache_test.go
│ │ ├── catalog.go
│ │ ├── catalog_test.go
│ │ ├── config.go
│ │ ├── config_as_cty.go
│ │ ├── config_as_cty_test.go
│ │ ├── config_helpers.go
│ │ ├── config_helpers_test.go
│ │ ├── config_partial.go
│ │ ├── config_partial_test.go
│ │ ├── config_test.go
│ │ ├── context.go
│ │ ├── cty_helpers.go
│ │ ├── dependency.go
│ │ ├── dependency_inputs_test.go
│ │ ├── dependency_test.go
│ │ ├── engine.go
│ │ ├── errors.go
│ │ ├── errors_block.go
│ │ ├── exclude.go
│ │ ├── external_test.go
│ │ ├── feature_flag.go
│ │ ├── hclparse/
│ │ │ ├── attributes.go
│ │ │ ├── block.go
│ │ │ ├── errors.go
│ │ │ ├── file.go
│ │ │ ├── options.go
│ │ │ └── parser.go
│ │ ├── include.go
│ │ ├── include_test.go
│ │ ├── locals.go
│ │ ├── locals_test.go
│ │ ├── options.go
│ │ ├── parsing_context.go
│ │ ├── sops_race_test.go
│ │ ├── sops_test.go
│ │ ├── stack.go
│ │ ├── stack_test.go
│ │ ├── stack_validation.go
│ │ ├── stack_validation_test.go
│ │ ├── telemetry.go
│ │ ├── translate.go
│ │ ├── util.go
│ │ ├── variable.go
│ │ └── variable_test.go
│ ├── log/
│ │ ├── context.go
│ │ ├── context_test.go
│ │ ├── external_test.go
│ │ ├── fields.go
│ │ ├── force_level_hook.go
│ │ ├── force_level_hook_test.go
│ │ ├── format/
│ │ │ ├── format.go
│ │ │ ├── format_test.go
│ │ │ ├── formatter.go
│ │ │ ├── options/
│ │ │ │ ├── align.go
│ │ │ │ ├── case.go
│ │ │ │ ├── color.go
│ │ │ │ ├── common.go
│ │ │ │ ├── content.go
│ │ │ │ ├── errors.go
│ │ │ │ ├── escape.go
│ │ │ │ ├── level_format.go
│ │ │ │ ├── option.go
│ │ │ │ ├── path_format.go
│ │ │ │ ├── prefix.go
│ │ │ │ ├── suffix.go
│ │ │ │ ├── time_format.go
│ │ │ │ ├── util.go
│ │ │ │ └── width.go
│ │ │ └── placeholders/
│ │ │ ├── common.go
│ │ │ ├── errors.go
│ │ │ ├── field.go
│ │ │ ├── interval.go
│ │ │ ├── level.go
│ │ │ ├── message.go
│ │ │ ├── placeholder.go
│ │ │ ├── placeholder_test.go
│ │ │ ├── plaintext.go
│ │ │ └── time.go
│ │ ├── formatter.go
│ │ ├── level.go
│ │ ├── level_test.go
│ │ ├── log.go
│ │ ├── logger.go
│ │ ├── logger_test.go
│ │ ├── options.go
│ │ ├── util.go
│ │ ├── util_test.go
│ │ └── writer/
│ │ ├── options.go
│ │ ├── writer.go
│ │ └── writer_test.go
│ ├── options/
│ │ ├── auto_retry_options.go
│ │ ├── options.go
│ │ └── options_test.go
│ └── pkg.go
└── test/
├── benchmarks/
│ ├── .gitignore
│ ├── helpers/
│ │ └── helpers.go
│ ├── integration_auto_provider_cache_dir_bench_test.go
│ ├── integration_bench_test.go
│ └── integration_cas_bench_test.go
├── cliconfig.go
├── fixtures/
│ ├── assume-role/
│ │ ├── duration/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── external-id/
│ │ │ └── terragrunt.hcl
│ │ └── external-id-with-comma/
│ │ └── terragrunt.hcl
│ ├── assume-role-web-identity/
│ │ └── file-path/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── auth-provider-cmd/
│ │ ├── creds-for-dependency/
│ │ │ ├── dependency/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dependent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── creds.config
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mock-auth-cmd.sh
│ │ ├── multiple-apps/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── creds.config
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── creds.config
│ │ │ ├── root.hcl
│ │ │ └── test-creds.sh
│ │ ├── oidc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── mock-auth-cmd.sh
│ │ │ └── terragrunt.hcl
│ │ ├── remote-state/
│ │ │ ├── creds.config
│ │ │ └── terragrunt.hcl
│ │ ├── remote-state-w-oidc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── mock-auth-cmd.sh
│ │ │ └── terragrunt.hcl
│ │ └── sops/
│ │ ├── .terraform.lock.hcl
│ │ ├── creds.config
│ │ ├── main.tf
│ │ ├── secrets.json
│ │ └── terragrunt.hcl
│ ├── auth-provider-parallel/
│ │ ├── auth-provider.sh
│ │ ├── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── auto-provider-cache-dir/
│ │ ├── basic/
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── heavy/
│ │ └── unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── aws-provider-patch/
│ │ ├── example-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── broken-dependency/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── broken-locals/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── buffer-module-output/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app3/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── catalog/
│ │ ├── complex/
│ │ │ ├── common.hcl
│ │ │ ├── dev/
│ │ │ │ ├── account.hcl
│ │ │ │ └── us-west-1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── modules/
│ │ │ │ │ └── terraform-aws-eks/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ ├── region.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── prod/
│ │ │ │ ├── account.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── root.hcl
│ │ │ └── stage/
│ │ │ ├── account.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── complex-legacy-root/
│ │ │ ├── common.hcl
│ │ │ ├── dev/
│ │ │ │ ├── account.hcl
│ │ │ │ └── us-west-1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── modules/
│ │ │ │ │ └── terraform-aws-eks/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ ├── region.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── prod/
│ │ │ │ ├── account.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── stage/
│ │ │ │ ├── account.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── config1.hcl
│ │ ├── config2.hcl
│ │ ├── config3.hcl
│ │ ├── config4.hcl
│ │ ├── local-template/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ ├── custom-template.txt
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app/
│ │ │ │ └── .gitkeep
│ │ │ └── root.hcl
│ │ └── terraform-aws-eks/
│ │ └── README.md
│ ├── cli-flag-hints/
│ │ └── terragrunt.hcl
│ ├── codegen/
│ │ ├── generate-attr/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── terragrunt.hcl
│ │ │ └── test.tf
│ │ ├── generate-block/
│ │ │ ├── disable/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── disable-signature/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── enable/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── nested/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── child_inherit/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── backend.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── child_overwrite/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ ├── overwrite/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── overwrite_terragrunt/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── overwrite_terragrunt_error/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── same_name_error/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── same_name_includes_error/
│ │ │ │ ├── app1.hcl
│ │ │ │ ├── app2.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── same_name_pair_error/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── skip/
│ │ │ └── terragrunt.hcl
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── remote-state/
│ │ │ ├── base/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── error/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── overwrite/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── backend.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── s3/
│ │ │ │ ├── .gitignore
│ │ │ │ └── terragrunt.hcl
│ │ │ └── skip/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ └── terragrunt.hcl
│ │ └── remove-file/
│ │ ├── remove/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── remove_terragrunt/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── remove_terragrunt_error/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── skip/
│ │ ├── .terraform.lock.hcl
│ │ ├── backend.tf
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── commands-that-need-input/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── config-files/
│ │ ├── ignore-cached-config/
│ │ │ └── terragrunt.hcl
│ │ ├── ignore-terraform-data-dir/
│ │ │ ├── .tf_data/
│ │ │ │ └── modules/
│ │ │ │ └── mod/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── root.hcl
│ │ │ └── subdir/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── .tf_data/
│ │ │ │ └── modules/
│ │ │ │ └── mod/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-configs/
│ │ │ ├── subdir-1/
│ │ │ │ └── empty.txt
│ │ │ ├── subdir-2/
│ │ │ │ └── subdir/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── subdir-3/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-json-configs/
│ │ │ ├── subdir-1/
│ │ │ │ └── empty.txt
│ │ │ ├── subdir-2/
│ │ │ │ └── subdir/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ ├── subdir-3/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── terragrunt.hcl.json
│ │ ├── multiple-mixed-configs/
│ │ │ ├── subdir-1/
│ │ │ │ └── empty.txt
│ │ │ ├── subdir-2/
│ │ │ │ └── subdir/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── subdir-3/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── terragrunt.hcl.json
│ │ ├── none/
│ │ │ ├── empty.txt
│ │ │ └── subdir/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── one-config/
│ │ │ ├── empty.txt
│ │ │ └── subdir/
│ │ │ └── terragrunt.hcl
│ │ ├── one-json-config/
│ │ │ ├── empty.txt
│ │ │ └── subdir/
│ │ │ └── terragrunt.hcl.json
│ │ ├── single-json-config/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl.json
│ │ └── with-non-default-names/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.hcl
│ │ │ └── main.tf
│ │ ├── common.hcl
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── another-name.hcl
│ │ │ └── main.tf
│ │ └── parent.hcl
│ ├── config-terraform-functions/
│ │ ├── other-file.txt
│ │ └── terragrunt.hcl
│ ├── dag-graph/
│ │ ├── region-1/
│ │ │ └── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── region-2/
│ │ │ └── unit-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl.hcl
│ ├── dependency-optimisation/
│ │ ├── module-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── dependency-output/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── destroy-dependent-module/
│ │ ├── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── destroy-dependent-module-errors/
│ │ ├── dev/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── env.hcl
│ │ └── prod/
│ │ ├── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── sops.yaml
│ │ └── terragrunt.hcl
│ ├── destroy-order/
│ │ ├── app/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module-e/
│ │ │ └── terragrunt.hcl
│ │ └── hello/
│ │ ├── .terraform.lock.hcl
│ │ ├── hello/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── main.tf
│ ├── destroy-warning/
│ │ ├── app-v1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── app-v2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── detailed-exitcode/
│ │ ├── changes/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── changes-with-source/
│ │ │ └── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── error/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── fail-on-first-run/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── fail-on-first-run-with-status/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── runall-retry-after-drift/
│ │ ├── app_drift/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app_flaky/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── dirs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── disabled/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-disabled/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-enabled/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-without-enabled/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── disabled-path/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── docs/
│ │ ├── 01-quick-start/
│ │ │ ├── step-01/
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-01.1/
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-02/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-03/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-04/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-05/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-05.1/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── step-06/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── output.tf
│ │ │ ├── step-07/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── bar/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── foo/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── shared/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── output.tf
│ │ │ └── step-07.1/
│ │ │ ├── .gitignore
│ │ │ ├── bar/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── foo/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── shared/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── output.tf
│ │ ├── 02-overview/
│ │ │ ├── step-01-terragrunt.hcl/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-02-dependencies/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── root.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-03-mock-outputs/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── root.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── step-04-configuration-hierarchy/
│ │ │ │ ├── root.hcl
│ │ │ │ └── us-east-1/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── region.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── step-05-exposed-includes/
│ │ │ ├── root.hcl
│ │ │ ├── us-east-1/
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── region.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── us-west-2/
│ │ │ ├── ec2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── region.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ └── 03-stacks-with-local-state/
│ │ ├── .gitignore
│ │ ├── live/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── root.hcl
│ │ └── units/
│ │ └── basic/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── download/
│ │ ├── custom-lock-file-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── custom-lock-file-terraform/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── custom-lock-file-tofu/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── extra-args/
│ │ │ └── common.tfvars
│ │ ├── hello-world/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── hello/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── main.tf
│ │ ├── hello-world-no-remote/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── hello-world-with-backend/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── init-on-source-change/
│ │ │ └── terragrunt.hcl
│ │ ├── invalid-path/
│ │ │ └── terragrunt.hcl
│ │ ├── local/
│ │ │ └── terragrunt.hcl
│ │ ├── local-disable-copy-terraform-lock-file/
│ │ │ └── terragrunt.hcl
│ │ ├── local-include-disable-copy-lock-file/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── local-include-with-prevent-destroy-dependencies/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── local-no-source/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── local-relative/
│ │ │ └── terragrunt.hcl
│ │ ├── local-relative-extra-args-unix/
│ │ │ └── terragrunt.hcl
│ │ ├── local-windows/
│ │ │ ├── JZwoL6Viko8bzuRvTOQFx3Jh8vs/
│ │ │ │ └── 3mU4huxMLOXOW5ZgJOFXGUFDKc8/
│ │ │ │ ├── hello/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-allowed-hidden/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── modules/
│ │ │ ├── .nonce
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── local-with-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-exclude-dir/
│ │ │ ├── integration-env/
│ │ │ │ ├── aws/
│ │ │ │ │ └── module-aws-a/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── gce/
│ │ │ │ ├── module-gce-b/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── module-gce-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── production-env/
│ │ │ ├── aws/
│ │ │ │ └── module-aws-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── gce/
│ │ │ └── module-gce-e/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-hidden-folder/
│ │ │ ├── .hidden-folder/
│ │ │ │ └── README.md
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-include-dir/
│ │ │ ├── integration-env/
│ │ │ │ ├── aws/
│ │ │ │ │ └── module-aws-a/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── gce/
│ │ │ │ ├── module-gce-b/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── module-gce-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── production-env/
│ │ │ ├── aws/
│ │ │ │ └── module-aws-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── gce/
│ │ │ └── module-gce-e/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-missing-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-prevent-destroy/
│ │ │ └── terragrunt.hcl
│ │ ├── local-with-prevent-destroy-dependencies/
│ │ │ ├── module-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-c/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module-d/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module-e/
│ │ │ └── terragrunt.hcl
│ │ ├── override/
│ │ │ └── terragrunt.hcl
│ │ ├── relative/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── remote/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-invalid/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-invalid-with-retries/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-module-in-root/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-ref/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-relative/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-relative-with-slash/
│ │ │ └── terragrunt.hcl
│ │ ├── remote-with-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── stdout/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── stdout-test/
│ │ ├── .terraform.lock.hcl
│ │ └── terragrunt.hcl
│ ├── download-source/
│ │ ├── download-dir-version-file/
│ │ │ └── version-file.txt
│ │ ├── download-dir-version-file-local-hash/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── download-dir-version-file-no-query/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── download-dir-version-file-tf-code/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── hello-world/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── hello-world-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── version-file.txt
│ │ ├── hello-world-local-hash/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── hello-world-local-hash-failed/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── hello-world-version-remote/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── version-file.txt
│ ├── empty-state/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── endswith/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── engine/
│ │ ├── engine-dependencies/
│ │ │ ├── .gitignore
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── local-engine/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── opentofu-engine/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── opentofu-latest-run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app4/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app5/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── opentofu-run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app4/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app5/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── remote-engine/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── trace-parent/
│ │ ├── .terraform.lock.hcl
│ │ ├── get_traceparent.sh
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── env-vars-block/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── ephemeral-inputs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── error-print/
│ │ ├── .terraform.lock.hcl
│ │ ├── custom-tf-script.sh
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── errors/
│ │ ├── default/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── get-default-errors/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── ignore/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── ignore-negative-pattern/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── ignore-signal/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multi-line/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── script.sh
│ │ │ └── terragrunt.hcl
│ │ ├── no-auto-retry/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── retry/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── script.sh
│ │ │ └── terragrunt.hcl
│ │ ├── retry-fail/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── script.sh
│ │ │ └── terragrunt.hcl
│ │ ├── run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── script.sh
│ │ │ │ └── terragrunt.hcl
│ │ │ └── common.hcl
│ │ └── run-all-ignore/
│ │ ├── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── exclude/
│ │ ├── basic/
│ │ │ ├── unit1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unit2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit3/
│ │ │ └── terragrunt.hcl
│ │ └── comprehensive/
│ │ ├── action-mismatch/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── always-excluded/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── conditional-flag/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── conditional-no-run/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dep-unit/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-all-except-output/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-apply-only/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-plan-only/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── flags.hcl
│ │ ├── never-excluded/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-run-false/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-run-not-set/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-run-true/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── normal-unit/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── with-dep/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── exclude-by-default/
│ │ ├── _stacks/
│ │ │ └── terragrunt.stack.hcl
│ │ └── unit1/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── excludes-file/
│ │ ├── .terragrunt-excludes
│ │ ├── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── d/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── excludes-file-pass-as-flag
│ ├── exec-cmd/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── script.sh
│ ├── exec-cmd-tf-path/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── script.sh
│ │ ├── terraform-output-json.sh
│ │ └── tofu-output-json.sh
│ ├── external-dependencies/
│ │ ├── module-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── module-b/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── external-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── extra-args/
│ │ ├── .terraform.lock.hcl
│ │ ├── dev.tfvars
│ │ ├── extra.tfvars
│ │ ├── main.tf
│ │ ├── terragrunt.hcl
│ │ └── us-west-2.tfvars
│ ├── fail-fast/
│ │ ├── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── fail-fast-early-exit/
│ │ ├── depends-on-failing/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depends-on-succeeding/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── failing-unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── succeeding-unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── failure/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── missingvars/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── submod/
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── submod/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── feature-flags/
│ │ ├── error-empty-flag/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── include-flag/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── run-all/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── common.hcl
│ │ └── simple-flag/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── filter/
│ │ ├── mark-as-read/
│ │ │ ├── unit-duplicate/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unit-empty/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unit-no-mark/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit-normal/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── minimize-parsing/
│ │ │ ├── dependency-unit/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── excluded-unit-1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── excluded-unit-2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── excluded-unit-3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── target-unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── minimize-parsing-destroy/
│ │ ├── landmine-unit-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── landmine-unit-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit-b/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── filter-source/
│ │ ├── github-acme-bar/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── github-acme-foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── gitlab-example-baz/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── local-module/
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── find/
│ │ ├── basic/
│ │ │ ├── stack/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ └── terragrunt.hcl
│ │ ├── dag/
│ │ │ ├── a-dependent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── b-dependency/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── c-mixed-deps/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── d-dependencies-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── hidden/
│ │ │ ├── .hide/
│ │ │ │ └── unit/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── stack/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ └── terragrunt.hcl
│ │ ├── include/
│ │ │ ├── bar/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── cloud.hcl
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── internal-v-external/
│ │ │ ├── external/
│ │ │ │ └── c-dependency/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── internal/
│ │ │ ├── a-dependent/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── b-dependency/
│ │ │ └── terragrunt.hcl
│ │ └── read-terragrunt-config/
│ │ ├── .terraform.lock.hcl
│ │ ├── common_deps.hcl
│ │ ├── main.tf
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── find-parent/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── find-parent-with-deprecated-root/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── gcs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-backend/
│ │ ├── common.hcl
│ │ ├── unit1/
│ │ │ └── terragrunt.hcl
│ │ └── unit2/
│ │ └── terragrunt.hcl
│ ├── gcs-byo-bucket/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-impersonate/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-no-bucket/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-no-prefix/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── gcs-parallel-state-init/
│ │ ├── root.hcl
│ │ └── template/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-aws-account-alias/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-aws-caller-identity/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-output/
│ │ ├── cycle/
│ │ │ ├── aa/
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── aba/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── abca/
│ │ │ │ ├── bar/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── baz/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── foo/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── abcda/
│ │ │ ├── bar/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── baz/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── car/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── download-dir/
│ │ │ ├── in-config/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── not-set/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── integration/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── empty/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── localstate/
│ │ │ ├── live/
│ │ │ │ ├── child/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── parent/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── modules/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── parent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── mock-outputs/
│ │ │ ├── dependent1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependent2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependent3/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── source/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mock-outputs-merge-strategy-with-state/
│ │ │ ├── merge-strategy-with-state-compat-conflict/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-compat-false/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-compat-true/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-deep-map-only/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-default/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-strategy-with-state-no-merge/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── merge-strategy-with-state-shallow/
│ │ │ ├── live/
│ │ │ │ ├── child/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── parent/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── modules/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── parent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── mock-outputs-merge-with-state/
│ │ │ ├── merge-with-state-default/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-with-state-false/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-with-state-no-override/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── merge-with-state-true/
│ │ │ │ ├── live/
│ │ │ │ │ ├── child/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ ├── parent/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── root.hcl
│ │ │ │ └── modules/
│ │ │ │ ├── child/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── parent/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── merge-with-state-true-validate-only/
│ │ │ ├── live/
│ │ │ │ ├── child/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── parent/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── root.hcl
│ │ │ └── modules/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── parent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── nested-mocks/
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── live/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── nested-optimization/
│ │ │ ├── .gitignore
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── live/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── nested-optimization-disable/
│ │ │ ├── .gitignore
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── live/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── nested-optimization-nogen/
│ │ │ ├── .gitignore
│ │ │ ├── deepdep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── live/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── regression-1102/
│ │ │ ├── .gitignore
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── regression-1124/
│ │ │ ├── live/
│ │ │ │ ├── app/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── dependency/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── modules/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── regression-1273/
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── main/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── regression-854/
│ │ │ └── root/
│ │ │ ├── environments/
│ │ │ │ ├── network/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── web/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── sg/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── regression-906/
│ │ │ ├── a/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── b/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── c/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── common-dep/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── d/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── e/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── f/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── g/
│ │ │ └── terragrunt.hcl
│ │ ├── run-all-source/
│ │ │ ├── live/
│ │ │ │ ├── unit1/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── unit2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── modules-default/
│ │ │ │ ├── module1/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── module2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── modules-marked/
│ │ │ ├── module1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── MODULE1_MARKER
│ │ │ │ └── main.tf
│ │ │ └── module2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── MODULE2_MARKER
│ │ │ └── main.tf
│ │ └── type-conversion/
│ │ └── terragrunt.hcl
│ ├── get-path/
│ │ ├── get-path-from-repo-root/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── get-path-to-repo-root/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── path_relative_from_include/
│ │ ├── lives/
│ │ │ ├── dev/
│ │ │ │ ├── base/
│ │ │ │ │ ├── terragrunt.hcl
│ │ │ │ │ └── tier.hcl
│ │ │ │ ├── cluster/
│ │ │ │ │ ├── terragrunt.hcl
│ │ │ │ │ └── tier.hcl
│ │ │ │ └── env.hcl
│ │ │ ├── org.hcl
│ │ │ └── root.hcl
│ │ └── modules/
│ │ ├── base/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── cluster/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── get-platform/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-repo-root/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── get-terragrunt-source-cli/
│ │ ├── terraform_config_cli/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── get-terragrunt-source-hcl/
│ │ ├── terraform_config_hcl/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── get-working-dir/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── modules/
│ │ │ └── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── graph/
│ │ ├── eks/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── lambda/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── services/
│ │ ├── eks-service-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-2-v2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-3-v2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-3-v3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-4/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── eks-service-5/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── lambda-service-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── lambda-service-2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── graph-dependencies/
│ │ ├── root/
│ │ │ ├── backend-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── frontend-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── mysql/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── redis/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── hcl-filter/
│ │ ├── fmt/
│ │ │ ├── already-formatted/
│ │ │ │ ├── app1/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── app2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── needs-formatting/
│ │ │ │ ├── db/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── nested/
│ │ │ │ ├── api/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── deep/
│ │ │ │ └── web/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── stacks/
│ │ │ ├── already-formatted/
│ │ │ │ └── stack2/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── needs-formatting/
│ │ │ └── stack1/
│ │ │ └── terragrunt.stack.hcl
│ │ └── validate/
│ │ ├── semantic-error/
│ │ │ ├── incomplete-block/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── missing-value/
│ │ │ └── terragrunt.hcl
│ │ ├── stacks/
│ │ │ ├── syntax-error/
│ │ │ │ └── stack2/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── valid/
│ │ │ └── stack1/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── syntax-error/
│ │ │ ├── invalid-char/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── invalid-key/
│ │ │ └── terragrunt.hcl
│ │ └── valid/
│ │ ├── db/
│ │ │ └── terragrunt.hcl
│ │ └── nested/
│ │ ├── api/
│ │ │ └── terragrunt.hcl
│ │ └── deep/
│ │ └── web/
│ │ └── terragrunt.hcl
│ ├── hclfmt-check/
│ │ ├── a/
│ │ │ ├── b/
│ │ │ │ └── c/
│ │ │ │ ├── d/
│ │ │ │ │ ├── e/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── services.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclfmt-check-errors/
│ │ ├── a/
│ │ │ ├── b/
│ │ │ │ └── c/
│ │ │ │ ├── d/
│ │ │ │ │ ├── e/
│ │ │ │ │ │ └── terragrunt.hcl
│ │ │ │ │ └── services.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclfmt-diff/
│ │ ├── expected.diff
│ │ └── terragrunt.hcl
│ ├── hclfmt-errors/
│ │ ├── dangling-attribute/
│ │ │ └── terragrunt.hcl
│ │ ├── invalid-character/
│ │ │ └── terragrunt.hcl
│ │ └── invalid-key/
│ │ └── terragrunt.hcl
│ ├── hclfmt-heredoc/
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclfmt-stdin/
│ │ ├── expected.hcl
│ │ └── terragrunt.hcl
│ ├── hclvalidate/
│ │ ├── first/
│ │ │ └── b/
│ │ │ └── terragrunt.hcl
│ │ ├── second/
│ │ │ ├── a/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── c/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── d/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── valid/
│ │ ├── circular-reference/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── invalid-local/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── single-required-input/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── validation-block/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── var-in-source/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── var-in-version/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── hidden-runall/
│ │ └── .cloud/
│ │ └── terraform/
│ │ ├── app1/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── app2/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── hooks/
│ │ ├── after-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── all/
│ │ │ ├── after-only/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── before-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── bad-arg-action/
│ │ │ ├── empty-command-list/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── empty-string-command/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── before-after-and-error-merge/
│ │ │ ├── qa/
│ │ │ │ └── my-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── before-after-and-on-error/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── before-and-after/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── hook.sh
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── before-only/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── error-hooks/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── terragrunt.hcl
│ │ │ └── tf.sh
│ │ ├── error-hooks-source-download-fail/
│ │ │ └── terragrunt.hcl
│ │ ├── exit-code-error/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── if-parameter/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── init-once/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── base-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── no-source-no-backend/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── no-source-with-backend/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── with-source-no-backend/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── with-source-no-backend-suppress-hook-stdout/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── with-source-with-backend/
│ │ │ └── terragrunt.hcl
│ │ ├── interpolations/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── one-arg-action/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── path-preservation/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── skip-on-error/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── working_dir/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── mydir/
│ │ │ └── hello_world
│ │ └── terragrunt.hcl
│ ├── include/
│ │ ├── qa/
│ │ │ └── my-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── stage/
│ │ └── my-app/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── include-deep/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── include-expose/
│ │ ├── mixed-with-bare/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ ├── single/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── single-bare/
│ │ │ └── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── terragrunt_env.hcl
│ │ ├── with-dependency/
│ │ │ ├── child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── with-dependency-reference-input/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── include-multiple/
│ │ ├── deep-merge-nonoverlapping/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── deep-merge-overlapping/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── expose/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── has-bare-include/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── json/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── modules/
│ │ │ ├── empty/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── reflect/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── shallow-deep-merge-overlapping/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── shallow-merge/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── terragrunt_inputs.hcl
│ │ ├── terragrunt_inputs_final.hcl
│ │ ├── terragrunt_inputs_override.hcl
│ │ ├── terragrunt_vpc_dep.hcl
│ │ ├── terragrunt_vpc_dep_for_expose.hcl
│ │ └── terragrunt_vpc_dep_override.hcl
│ ├── include-parent/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── common.hcl
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── parent.hcl
│ ├── include-runall/
│ │ ├── a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── alpha.hcl
│ │ ├── b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── c/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── init-cache/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── init-error/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── init-once/
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── inputs/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── inputs-defaults/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── inputs-interpolation/
│ │ ├── main.tf
│ │ ├── stuff.json
│ │ └── terragrunt.hcl
│ ├── list/
│ │ ├── basic/
│ │ │ ├── a-unit/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── b-unit/
│ │ │ └── terragrunt.hcl
│ │ ├── dag/
│ │ │ ├── stacks/
│ │ │ │ └── live/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── live/
│ │ │ ├── dev/
│ │ │ │ ├── db/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── ec2/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── prod/
│ │ │ ├── db/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── ec2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ └── long/
│ │ ├── unit-0/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-1/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-2/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-3/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-4/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-5/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-6/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-7/
│ │ │ └── terragrunt.hcl
│ │ ├── unit-8/
│ │ │ └── terragrunt.hcl
│ │ └── unit-9/
│ │ └── terragrunt.hcl
│ ├── locals/
│ │ ├── canonical/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── contents.txt
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── local-in-include/
│ │ │ ├── qa/
│ │ │ │ └── my-app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── run-multiple/
│ │ │ └── terragrunt.hcl
│ │ └── run-once/
│ │ └── terragrunt.hcl
│ ├── locals-errors/
│ │ ├── undefined-local/
│ │ │ └── terragrunt.hcl
│ │ └── undefined-local-but-input/
│ │ └── terragrunt.hcl
│ ├── log/
│ │ ├── formatter/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── levels/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── rel-paths/
│ │ └── duplicate-dir-names/
│ │ └── workspace/
│ │ └── one/
│ │ └── two/
│ │ ├── aaa/
│ │ │ └── bbb/
│ │ │ └── ccc/
│ │ │ ├── module-b/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── workspace/
│ │ │ └── terragrunt.hcl
│ │ └── tf/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── manifest/
│ │ ├── version-1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── stale.tf
│ │ ├── version-2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── version-3-subfolder/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── sub/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── version-4-subfolder-empty/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── version-5-not-empty-subfolder/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── sub2/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── manifest-removal/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── missing-dependencies/
│ │ ├── main/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── module-a/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── mixed-config/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── stack/
│ │ │ └── terragrunt.stack.hcl
│ │ └── unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── module-path-in-error/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── d1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── provider.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── modules/
│ │ ├── hcl-module-b/
│ │ │ ├── module-b-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl.json
│ │ ├── hcl-module-c/
│ │ │ └── terragrunt.hcl
│ │ ├── json-module-a/
│ │ │ └── terragrunt.hcl.json
│ │ ├── json-module-b/
│ │ │ ├── module-b-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl.json
│ │ │ └── root.hcl
│ │ ├── json-module-c/
│ │ │ └── terragrunt.hcl.json
│ │ ├── json-module-d/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl.json
│ │ ├── module-a/
│ │ │ └── terragrunt.hcl
│ │ ├── module-abba/
│ │ │ └── terragrunt.hcl
│ │ ├── module-b/
│ │ │ ├── module-b-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── module-c/
│ │ │ └── terragrunt.hcl
│ │ ├── module-d/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-e/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── module-e-child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── module-f/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-g/
│ │ │ └── terragrunt.hcl
│ │ ├── module-h/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-i/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── terragrunt.hcl
│ │ │ └── test.tf
│ │ ├── module-j/
│ │ │ └── terragrunt.hcl
│ │ ├── module-k/
│ │ │ └── terragrunt.hcl
│ │ ├── module-l/
│ │ │ └── terragrunt.hcl
│ │ ├── module-m/
│ │ │ ├── env.hcl
│ │ │ ├── module-m-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── terragrunt.hcl
│ │ │ │ └── tier.hcl
│ │ │ └── root.hcl
│ │ └── module-missing-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── multiinclude-dependency/
│ │ ├── depa/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depa.hcl
│ │ ├── depb/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depb.hcl
│ │ ├── depc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── depc.hcl
│ │ ├── main/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── no-color/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── no-color-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── terragrunt.hcl
│ │ └── y/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── no-submodules/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── null-values/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── out-dir/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── output-all/
│ │ ├── env1/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── output-from-dependency/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── terragrunt.hcl
│ │ └── variables.tf
│ ├── output-from-remote-state/
│ │ ├── env1/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── terragrunt.hcl
│ │ │ │ └── variables.tf
│ │ │ └── app3/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── output-module-groups/
│ │ └── root/
│ │ ├── backend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── frontend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mysql/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── redis/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── parallel-run/
│ │ ├── .tflint.hcl
│ │ ├── common/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── dev/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── parallel-state-init/
│ │ ├── root.hcl
│ │ └── template/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── parallelism/
│ │ ├── template/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── parent-folders/
│ │ ├── in-another-subfolder/
│ │ │ ├── common/
│ │ │ │ └── foo.txt
│ │ │ └── live/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-terragrunt-in-parents/
│ │ │ ├── child/
│ │ │ │ ├── root.hcl
│ │ │ │ └── sub-child/
│ │ │ │ ├── root.hcl
│ │ │ │ └── sub-sub-child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── no-terragrunt-in-root/
│ │ │ └── child/
│ │ │ └── sub-child/
│ │ │ └── terragrunt.hcl
│ │ ├── other-file-names/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── foo.txt
│ │ ├── terragrunt-in-root/
│ │ │ ├── child/
│ │ │ │ └── sub-child/
│ │ │ │ └── sub-sub-child/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── override/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── with-params/
│ │ └── tfwork/
│ │ ├── test-var/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── providers.tf
│ │ └── tg/
│ │ └── terragrunt.hcl
│ ├── parsing/
│ │ └── exposed-include-with-deprecated-inputs/
│ │ ├── child/
│ │ │ └── terragrunt.hcl
│ │ ├── compcommon.hcl
│ │ ├── dep/
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── partial-parse/
│ │ ├── ignore-bad-block-in-parent/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ ├── partial-inheritance/
│ │ │ ├── child/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── terragrunt-version-constraint/
│ │ └── terragrunt.hcl
│ ├── planfile-order-test/
│ │ ├── .gitignore
│ │ ├── .terraform.lock.hcl
│ │ ├── inputs.tf
│ │ ├── resource.tf
│ │ ├── terragrunt.hcl
│ │ └── vars/
│ │ └── variables.tfvars
│ ├── prevent-destroy-not-set/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── prevent-destroy-override/
│ │ ├── child/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── private-registry/
│ │ ├── env.tfrc
│ │ └── terragrunt.hcl
│ ├── provider-cache/
│ │ ├── dependency/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dep/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── direct/
│ │ │ ├── .gitignore
│ │ │ ├── first/
│ │ │ │ ├── app/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app1/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app2/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app3/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app4/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app5/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app6/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app7/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── app8/
│ │ │ │ │ ├── main.tf
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── app9/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── second/
│ │ │ ├── app/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app1/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app3/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app4/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app5/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app6/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app7/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app8/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app9/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── filesystem-mirror/
│ │ │ └── app/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-platforms/
│ │ │ ├── .gitignore
│ │ │ ├── app1/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── app2/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app3/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── network-mirror/
│ │ │ └── apps/
│ │ │ ├── app0/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app1/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── weak-constraint/
│ │ ├── .gitignore
│ │ └── app/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── queue-strict-include/
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependent/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── transitive-dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── queue-strict-include-units-reading/
│ │ ├── live/
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── sources/
│ │ └── source.hcl
│ ├── read-config/
│ │ ├── from_dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── terragrunt.hcl
│ │ │ │ └── vars.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── full/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── source.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── iam_role_in_file/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── iam_roles_multiple_modules/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── component1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── component2/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── with_constraints/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── with_default/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── with_dependency/
│ │ │ ├── dep/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ └── with_original_terragrunt_dir/
│ │ ├── .terraform.lock.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── foo/
│ │ │ └── bar.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── read-tf-vars/
│ │ ├── empty.tfvars
│ │ ├── my.tfvars
│ │ ├── my.tfvars.json
│ │ ├── only-comments.tfvars
│ │ └── terragrunt.hcl
│ ├── regressions/
│ │ ├── 5195-scope-escape/
│ │ │ ├── bastion/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── accesslogging-bucket/
│ │ │ ├── no-target-prefix-input/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── remote_terragrunt.hcl
│ │ │ └── with-target-prefix-input/
│ │ │ ├── .gitignore
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── remote_terragrunt.hcl
│ │ ├── apply-all-envvar/
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── no-require-envvar/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── require-envvar/
│ │ │ └── terragrunt.hcl
│ │ ├── benchmark-parsing/
│ │ │ ├── modules/
│ │ │ │ └── dummy-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── variables.tf
│ │ │ │ └── versions.tf
│ │ │ ├── production/
│ │ │ │ ├── dependency-group-template/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── deployment-group-1/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── environment.hcl
│ │ │ └── root-terragrunt.hcl
│ │ ├── benchmark-parsing-includes/
│ │ │ ├── modules/
│ │ │ │ └── dummy-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── variables.tf
│ │ │ │ └── versions.tf
│ │ │ ├── production/
│ │ │ │ ├── dependency-group-template/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ ├── deployment-group-1/
│ │ │ │ │ ├── app.hcl
│ │ │ │ │ └── webserver/
│ │ │ │ │ └── terragrunt.hcl
│ │ │ │ └── environment.hcl
│ │ │ └── root-terragrunt.hcl
│ │ ├── dependency-empty-config-path/
│ │ │ ├── _source/
│ │ │ │ └── units/
│ │ │ │ └── consumer/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── live/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── dependency-generate/
│ │ │ ├── modules/
│ │ │ │ ├── other-module/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── test-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── other/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── testing/
│ │ │ └── terragrunt.hcl
│ │ ├── dependency-include-error/
│ │ │ ├── dep/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── layer.hcl
│ │ │ ├── root.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── disabled-dependency-empty-config-path/
│ │ │ ├── modules/
│ │ │ │ └── id/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── root.hcl
│ │ │ ├── unit-a/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit-b/
│ │ │ └── terragrunt.hcl
│ │ ├── exclude-dependency/
│ │ │ ├── amazing-app/
│ │ │ │ └── k8s/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── clusters/
│ │ │ │ └── eks/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── modules/
│ │ │ │ ├── eks/
│ │ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ │ └── main.tf
│ │ │ │ └── k8s/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── root.hcl
│ │ │ └── testapp/
│ │ │ └── k8s/
│ │ │ └── terragrunt.hcl
│ │ ├── include-error/
│ │ │ ├── _envcommon.hcl
│ │ │ └── project/
│ │ │ ├── app/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── eng_teams.hcl
│ │ ├── mocks-merge-with-state/
│ │ │ ├── deep-map/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── shallow/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-dependency-load-sync/
│ │ │ ├── dep1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dep2/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── main/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── modules/
│ │ │ │ └── dummy-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ ├── outputs.tf
│ │ │ │ ├── variables.tf
│ │ │ │ └── versions.tf
│ │ │ └── root-terragrunt.hcl
│ │ ├── multiple-stacks/
│ │ │ ├── live/
│ │ │ │ ├── appv2.terragrunt.stack.hcl
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── template/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── not-existing-dependency/
│ │ │ ├── invalid-path/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── parent-find-fail/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── parsing-run-all-with-generate/
│ │ │ ├── root.hcl
│ │ │ ├── services/
│ │ │ │ └── test1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── services-info/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── run-cmd-include-output/
│ │ │ ├── root.hcl
│ │ │ ├── scripts/
│ │ │ │ └── emit_output.sh
│ │ │ ├── unit-a/
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit-b/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── sensitive-values/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── dev.enc.yaml
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── skip-init/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── skip-versioning/
│ │ │ ├── .gitignore
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── local_terragrunt.hcl
│ │ │ ├── main.tf
│ │ │ └── remote_terragrunt.hcl
│ │ └── yamldecode/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── relative-include-cmd/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── app.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt-test.hcl
│ ├── render-json/
│ │ ├── common_vars.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── main/
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── render-json-inputs/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── dependency/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── render-json-metadata/
│ │ ├── attributes/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependencies/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── include.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependency1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dependency2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependency/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── dependency/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── dependency2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── includes/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── generate.hcl
│ │ │ │ ├── inputs.hcl
│ │ │ │ ├── locals.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── common/
│ │ │ └── common.hcl
│ │ └── terraform-remote-state/
│ │ ├── app/
│ │ │ └── terragrunt.hcl
│ │ ├── common/
│ │ │ ├── remote_state.hcl
│ │ │ └── terraform.hcl
│ │ └── terraform/
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── render-json-mock-outputs/
│ │ ├── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── render-json-regression/
│ │ ├── bar/
│ │ │ └── terragrunt.hcl
│ │ ├── baz/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── terragrunt.hcl
│ ├── render-json-with-encryption/
│ │ ├── common_vars.hcl
│ │ ├── dep/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── main/
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── report/
│ │ ├── chain-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── chain-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── chain-c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── error-ignore/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-early-exit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-exclude/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-failure/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── first-success/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── retry-success/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── second-early-exit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── second-exclude/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── second-failure/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── second-success/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── root-terragrunt-hcl-regression/
│ │ ├── bar/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── baz/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── run-cmd-flags/
│ │ ├── module-conflict/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-global-cache-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-global-cache-b/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-no-cache/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── module-quiet/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── scripts/
│ │ ├── .gitignore
│ │ ├── emit_secret.sh
│ │ ├── global_counter.sh
│ │ └── no_cache_counter.sh
│ ├── run-filter/
│ │ ├── cache/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── db/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── service/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── runner-pool-remote-source/
│ │ ├── unit-a/
│ │ │ └── terragrunt.hcl
│ │ └── unit-b/
│ │ └── terragrunt.hcl
│ ├── s3-backend/
│ │ ├── common.hcl
│ │ ├── dual-locking/
│ │ │ └── terragrunt.hcl
│ │ ├── unit1/
│ │ │ └── terragrunt.hcl
│ │ ├── unit2/
│ │ │ └── terragrunt.hcl
│ │ └── use-lockfile/
│ │ └── terragrunt.hcl
│ ├── s3-backend-disable-init/
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── s3-backend-migrate/
│ │ ├── unit1/
│ │ │ └── terragrunt.hcl
│ │ └── unit2/
│ │ └── terragrunt.hcl
│ ├── s3-encryption/
│ │ ├── basic-encryption/
│ │ │ └── terragrunt.hcl
│ │ ├── custom-key/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── sse-aes/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── sse-kms/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── s3-errors/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── scaffold/
│ │ ├── catalog-config-test/
│ │ │ └── terragrunt.hcl
│ │ ├── custom-default-template/
│ │ │ ├── root.hcl
│ │ │ └── unit/
│ │ │ └── .gitkeep
│ │ ├── dependency-prompt-template/
│ │ │ ├── .boilerplate/
│ │ │ │ └── boilerplate.yml
│ │ │ ├── base/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── test.hcl
│ │ │ └── leaf/
│ │ │ ├── boilerplate.yml
│ │ │ └── terragrunt.hcl
│ │ ├── external-template/
│ │ │ ├── dependency/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── dependency.txt
│ │ │ └── template/
│ │ │ ├── boilerplate.yml
│ │ │ ├── external-template.txt
│ │ │ └── terragrunt.hcl
│ │ ├── module-with-template/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ ├── template-file.txt
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── root-hcl/
│ │ │ ├── root.hcl
│ │ │ └── unit/
│ │ │ └── .gitkeep
│ │ ├── scaffold-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── variables.tf
│ │ ├── scaffold-module-tofu/
│ │ │ ├── main.tofu
│ │ │ └── variables.tofu
│ │ ├── with-hooks/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── with-shell-and-hooks/
│ │ │ ├── .boilerplate/
│ │ │ │ ├── boilerplate.yml
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── with-shell-commands/
│ │ ├── .boilerplate/
│ │ │ ├── boilerplate.yml
│ │ │ └── terragrunt.hcl
│ │ ├── .terraform.lock.hcl
│ │ └── main.tf
│ ├── skip/
│ │ ├── base-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── skip-false/
│ │ │ ├── resource1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── resource2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── root.hcl
│ │ └── skip-true/
│ │ ├── resource1/
│ │ │ └── terragrunt.hcl
│ │ ├── resource2/
│ │ │ └── terragrunt.hcl
│ │ └── root.hcl
│ ├── skip-dependencies/
│ │ ├── first/
│ │ │ ├── foo.hcl
│ │ │ └── terragrunt.hcl
│ │ ├── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ └── second/
│ │ └── terragrunt.hcl
│ ├── skip-legacy-root/
│ │ ├── base-module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── skip-false/
│ │ │ ├── resource1/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── resource2/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terragrunt.hcl
│ │ └── skip-true/
│ │ ├── resource1/
│ │ │ └── terragrunt.hcl
│ │ ├── resource2/
│ │ │ └── terragrunt.hcl
│ │ └── terragrunt.hcl
│ ├── sops/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── secrets.env
│ │ ├── secrets.ini
│ │ ├── secrets.json
│ │ ├── secrets.txt
│ │ ├── secrets.yaml
│ │ ├── terragrunt.hcl
│ │ └── test_pgp_key.asc
│ ├── sops-errors/
│ │ ├── .terraform.lock.hcl
│ │ ├── file.yaml
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── sops-kms/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── secrets.env
│ │ ├── secrets.ini
│ │ ├── secrets.json
│ │ ├── secrets.txt
│ │ ├── secrets.yaml
│ │ └── terragrunt.hcl
│ ├── sops-missing/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── source-map/
│ │ ├── modules/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── vpc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── multiple-match/
│ │ │ ├── terragrunt-vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terratest-vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-only-one-match/
│ │ │ ├── terragrunt-vpc/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── terratest-vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-with-dependency/
│ │ │ ├── app/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-with-dependency-same-url/
│ │ │ ├── app/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ └── terragrunt.hcl
│ │ ├── single/
│ │ │ └── terragrunt.hcl
│ │ └── slashes-in-ref/
│ │ └── terragrunt.hcl
│ ├── stack/
│ │ ├── disjoint/
│ │ │ ├── a/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── b/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── c/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── disjoint-symlinks/
│ │ │ ├── a/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── module/
│ │ │ ├── .terraform.lock.hcl
│ │ │ └── main.tf
│ │ ├── mgmt/
│ │ │ ├── bastion-host/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── kms-master-key/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── vpc/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── root.hcl
│ │ └── stage/
│ │ ├── backend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── frontend-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── mysql/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── redis/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── search-app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── example-module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── vpc/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── stacks/
│ │ ├── all-no-stack-dir/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── basic/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── chick/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── chicken/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── father/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── mother/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── coexist-hcl-and-stack/
│ │ │ ├── modules/
│ │ │ │ └── test/
│ │ │ │ └── main.tf
│ │ │ ├── non-prod/
│ │ │ │ └── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ └── test/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── test/
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── dependencies/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app-with-dependency/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── errors/
│ │ │ ├── absolute-path/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── cycles/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── stack/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── unit/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── incorrect-source/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── locals-error/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── not-existing-path/
│ │ │ │ └── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── relative-path-outside-of-stack/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── stack-empty-path/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── unit-empty-path/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── app/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── unknown-value/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── bad-unit/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── validation-stack/
│ │ │ │ ├── live/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── stacks/
│ │ │ │ │ └── v1/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── units/
│ │ │ │ └── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── validation-unit/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── v1/
│ │ │ ├── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── db/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── web/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── find-in-parent-folders/
│ │ │ ├── live/
│ │ │ │ └── stack/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── mock.hcl
│ │ │ └── units/
│ │ │ └── foo/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── get-original-terragrunt-dir/
│ │ │ ├── live/
│ │ │ │ ├── account1/
│ │ │ │ │ ├── no-locals-nested/
│ │ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ ├── read-config/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ └── with-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ ├── non-nested/
│ │ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ ├── read-config/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ └── with-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ ├── read-config-nested/
│ │ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ ├── read-config/
│ │ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ │ └── with-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ └── with-locals-nested/
│ │ │ │ │ ├── no-locals/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ ├── read-config/
│ │ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ │ └── with-locals/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── common/
│ │ │ │ └── stack_config.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── no-locals/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── read-config/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── with-locals/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── terragrunt.hcl
│ │ ├── inputs/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── locals/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── chick/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── chicken/
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── father/
│ │ │ │ └── terragrunt.hcl
│ │ │ └── mother/
│ │ │ └── terragrunt.hcl
│ │ ├── multiple-stacks/
│ │ │ ├── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── nested/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── live-v2/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── db/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── web/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── nested-outputs/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── v1/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ ├── v2/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── v3/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-dot-terragrunt-stack-output/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-stack/
│ │ │ ├── config/
│ │ │ │ └── config.txt
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ └── dev/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── api/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ ├── db/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── web/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-stack-dir/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── no-validation/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ └── stack1/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app1/
│ │ │ └── code/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── outputs/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ ├── app1/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── app2/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── read-stack/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── remote/
│ │ │ └── terragrunt.stack.hcl
│ │ ├── self-include/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── module/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ ├── main.tf
│ │ │ │ └── terragrunt.hcl
│ │ │ └── unit/
│ │ │ └── terragrunt.hcl
│ │ ├── source-map/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── tf/
│ │ │ │ └── modules/
│ │ │ │ ├── .terraform.lock.hcl
│ │ │ │ └── main.tf
│ │ │ └── units/
│ │ │ └── app/
│ │ │ └── terragrunt.hcl
│ │ ├── stack-values/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ ├── stacks/
│ │ │ │ ├── dev/
│ │ │ │ │ └── terragrunt.stack.hcl
│ │ │ │ └── prod/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── terragrunt-dir/
│ │ │ ├── live/
│ │ │ │ ├── root.hcl
│ │ │ │ └── tennant_1/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── unit_a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ ├── unit-values/
│ │ │ ├── live/
│ │ │ │ └── terragrunt.stack.hcl
│ │ │ └── units/
│ │ │ └── app/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── version-constraints/
│ │ ├── live/
│ │ │ └── terragrunt.stack.hcl
│ │ └── unit/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── startswith/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── strcontains/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── streaming/
│ │ ├── unit1/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── unit2/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
│ ├── strict-bare-include/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ ├── parent.hcl
│ │ └── terragrunt.hcl
│ ├── terragrunt-info-error/
│ │ ├── module-a/
│ │ │ ├── .terraform.lock.hcl
│ │ │ ├── main.tf
│ │ │ └── terragrunt.hcl
│ │ └── module-b/
│ │ ├── .terraform.lock.hcl
│ │ ├── main.tf
│ │ └── terragrunt.hcl
Showing preview only (702K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (7085 symbols across 671 files)
FILE: docs/astro.config.mjs
method configureServer (line 364) | configureServer(server) {
FILE: docs/src/components/ui/Button.tsx
type ButtonProps (line 7) | interface ButtonProps {
function isSizeIcon (line 19) | function isSizeIcon(size?: string): boolean {
function Button (line 23) | function Button({
FILE: docs/src/components/ui/ButtonLink.tsx
type ButtonProps (line 7) | type ButtonProps = React.ComponentProps<typeof Button>;
type ButtonLinkProps (line 9) | interface ButtonLinkProps extends ButtonProps {
function ButtonLink (line 16) | function ButtonLink({
FILE: docs/src/components/vendored/starlight/Icons.ts
type StarlightIcon (line 203) | type StarlightIcon = keyof typeof Icons;
FILE: docs/src/components/vendored/starlight/rehype-file-tree.ts
type DataMap (line 13) | interface DataMap {
function processFileTree (line 28) | function processFileTree(html: string, directoryLabel: string) {
function makeText (line 139) | function makeText(value = ''): Text {
function makeSVGIcon (line 144) | function makeSVGIcon(svgString: string) {
function getFileIcon (line 159) | function getFileIcon(fileName: string) {
function getFileIconName (line 170) | function getFileIconName(fileName: string) {
function getFileIconTypeFromExtension (line 187) | function getFileIconTypeFromExtension(fileName: string) {
function validateFileTree (line 202) | function validateFileTree(tree: Element) {
function isElementNode (line 235) | function isElementNode(node: ElementContent): node is Element {
function throwFileTreeValidationError (line 240) | function throwFileTreeValidationError(message: string): never {
type Definitions (line 247) | interface Definitions {
FILE: docs/src/fixtures/terralith-to-terragrunt/app/best-cat/index.js
constant CACHE_CLEANUP_INTERVAL (line 47) | const CACHE_CLEANUP_INTERVAL = 5 * 60 * 1000;
function cleanupExpiredCache (line 53) | function cleanupExpiredCache() {
function getCachedPresignedUrl (line 71) | async function getCachedPresignedUrl(bucketName, imageKey) {
function getCachedS3List (line 99) | async function getCachedS3List(bucketName) {
function handler (line 126) | async function handler(event) {
FILE: docs/src/fixtures/terralith-to-terragrunt/app/best-cat/script.js
function vote (line 23) | async function vote(imageKey, voteType) {
function showNotification (line 112) | function showNotification(message, type = 'info') {
FILE: docs/src/lib/commands/headings/index.ts
function getHeadings (line 3) | async function getHeadings(
FILE: docs/src/lib/commands/sidebar/index.ts
function createCommandSidebarItem (line 8) | function createCommandSidebarItem(command: CollectionEntry<'commands'>):...
function organizeCommandsIntoGroups (line 26) | function organizeCommandsIntoGroups(flatCommandItems: (SidebarItem & { o...
function insertCommandsIntoSidebar (line 57) | function insertCommandsIntoSidebar(
function populateAutogeneratedSections (line 93) | function populateAutogeneratedSections(items: SidebarItem[]) {
function getSidebar (line 121) | async function getSidebar(commands: CollectionEntry<'commands'>[]): Prom...
FILE: docs/src/lib/github.ts
constant CACHE_TTL_MS (line 1) | const CACHE_TTL_MS = 60 * 60 * 1000;
constant FETCH_TIMEOUT_MS (line 2) | const FETCH_TIMEOUT_MS = 10 * 1000;
type CacheEntry (line 4) | interface CacheEntry<T> {
function memoizedFetch (line 15) | async function memoizedFetch<T>(
type GitHubRepoResponse (line 34) | interface GitHubRepoResponse {
type GitHubReleaseResponse (line 39) | interface GitHubReleaseResponse {
function getGitHubRepo (line 51) | async function getGitHubRepo(
function getLatestRelease (line 97) | async function getLatestRelease(
function formatStarCount (line 142) | function formatStarCount(stars: number): string {
FILE: docs/src/lib/utils.ts
function cn (line 6) | function cn(...inputs: ClassValue[]) {
FILE: internal/awshelper/config.go
constant minARNParts (line 26) | minARNParts = 2
type AwsSessionConfig (line 30) | type AwsSessionConfig struct
type tokenFetcher (line 44) | type tokenFetcher
method FetchToken (line 48) | func (f tokenFetcher) FetchToken(_ context.Context) ([]byte, error) {
type AWSConfigBuilder (line 65) | type AWSConfigBuilder struct
method WithSessionConfig (line 79) | func (b *AWSConfigBuilder) WithSessionConfig(cfg *AwsSessionConfig) *A...
method WithEnv (line 85) | func (b *AWSConfigBuilder) WithEnv(env map[string]string) *AWSConfigBu...
method WithIAMRoleOptions (line 91) | func (b *AWSConfigBuilder) WithIAMRoleOptions(opts iam.RoleOptions) *A...
method Build (line 97) | func (b *AWSConfigBuilder) Build(ctx context.Context, l log.Logger) (a...
method BuildS3Client (line 158) | func (b *AWSConfigBuilder) BuildS3Client(ctx context.Context, l log.Lo...
function NewAWSConfigBuilder (line 72) | func NewAWSConfigBuilder() *AWSConfigBuilder {
function getRegionFromEnv (line 186) | func getRegionFromEnv(env map[string]string) string {
function getMergedIAMRoleOptions (line 199) | func getMergedIAMRoleOptions(awsCfg *AwsSessionConfig, iamRoleOpts iam.R...
function getExternalID (line 215) | func getExternalID(awsCfg *AwsSessionConfig) string {
function AssumeIamRole (line 224) | func AssumeIamRole(
function GetAWSCallerIdentity (line 307) | func GetAWSCallerIdentity(ctx context.Context, cfg *aws.Config) (*sts.Ge...
function ValidateAwsConfig (line 313) | func ValidateAwsConfig(ctx context.Context, cfg *aws.Config) error {
function GetAWSPartition (line 319) | func GetAWSPartition(ctx context.Context, cfg *aws.Config) (string, erro...
function GetAWSAccountAlias (line 341) | func GetAWSAccountAlias(ctx context.Context, cfg *aws.Config) (string, e...
function GetAWSAccountID (line 357) | func GetAWSAccountID(ctx context.Context, cfg *aws.Config) (string, erro...
function GetAWSIdentityArn (line 367) | func GetAWSIdentityArn(ctx context.Context, cfg *aws.Config) (string, er...
function GetAWSUserID (line 377) | func GetAWSUserID(ctx context.Context, cfg *aws.Config) (string, error) {
function ValidatePublicAccessBlock (line 387) | func ValidatePublicAccessBlock(output *s3.GetPublicAccessBlockOutput) (b...
function getWebIdentityCredentialsFromIAMRoleOptions (line 401) | func getWebIdentityCredentialsFromIAMRoleOptions(
function getSTSCredentialsFromIAMRoleOptions (line 447) | func getSTSCredentialsFromIAMRoleOptions(
function createCredentialsFromEnv (line 491) | func createCredentialsFromEnv(env map[string]string) aws.CredentialsProv...
FILE: internal/awshelper/config_test.go
function TestAwsSessionValidationFail (line 18) | func TestAwsSessionValidationFail(t *testing.T) {
function TestAwsNegativePublicAccessResponse (line 35) | func TestAwsNegativePublicAccessResponse(t *testing.T) {
function TestCreateAwsConfigWithAuthProviderEnv (line 82) | func TestCreateAwsConfigWithAuthProviderEnv(t *testing.T) {
function TestCreateAwsConfigWithAuthProviderEnvDefaultRegion (line 104) | func TestCreateAwsConfigWithAuthProviderEnvDefaultRegion(t *testing.T) {
function TestAwsConfigRegionTakesPrecedenceOverEnvVars (line 124) | func TestAwsConfigRegionTakesPrecedenceOverEnvVars(t *testing.T) {
FILE: internal/awshelper/policy.go
type Policy (line 6) | type Policy struct
type Statement (line 15) | type Statement struct
function UnmarshalPolicy (line 25) | func UnmarshalPolicy(policy string) (Policy, error) {
function MarshalPolicy (line 36) | func MarshalPolicy(policy Policy) ([]byte, error) {
FILE: internal/awshelper/policy_test.go
constant simplePolicy (line 13) | simplePolicy = `
constant arraysPolicy (line 27) | arraysPolicy = `
function TestAwsUnmarshalStringActionResource (line 56) | func TestAwsUnmarshalStringActionResource(t *testing.T) {
function TestAwsUnmarshalActionResourceList (line 85) | func TestAwsUnmarshalActionResourceList(t *testing.T) {
FILE: internal/cache/cache.go
type Cache (line 17) | type Cache struct
function NewCache (line 24) | func NewCache[V any](name string) *Cache[V] {
method Get (line 33) | func (c *Cache[V]) Get(ctx context.Context, key string) (V, bool) {
method Put (line 53) | func (c *Cache[V]) Put(ctx context.Context, key string, value V) {
type ExpiringItem (line 65) | type ExpiringItem struct
type ExpiringCache (line 71) | type ExpiringCache struct
function NewExpiringCache (line 78) | func NewExpiringCache[V any](name string) *ExpiringCache[V] {
method Get (line 87) | func (c *ExpiringCache[V]) Get(ctx context.Context, key string) (V, bool) {
method Put (line 112) | func (c *ExpiringCache[V]) Put(ctx context.Context, key string, value V,...
function ContextCache (line 121) | func ContextCache[T any](ctx context.Context, key any) *Cache[T] {
FILE: internal/cache/cache_test.go
function TestCacheCreation (line 11) | func TestCacheCreation(t *testing.T) {
function TestStringCacheOperation (line 22) | func TestStringCacheOperation(t *testing.T) {
function TestExpiringCacheCreation (line 41) | func TestExpiringCacheCreation(t *testing.T) {
function TestExpiringCacheOperation (line 52) | func TestExpiringCacheOperation(t *testing.T) {
function TestExpiringCacheExpiration (line 71) | func TestExpiringCacheExpiration(t *testing.T) {
FILE: internal/cache/context.go
constant RunCmdCacheContextKey (line 9) | RunCmdCacheContextKey ctxKey = iota
constant runCmdCacheName (line 12) | runCmdCacheName = "runCmdCache"
type ctxKey (line 16) | type ctxKey
function ContextWithCache (line 18) | func ContextWithCache(ctx context.Context) context.Context {
FILE: internal/cas/benchmark_test.go
function BenchmarkClone (line 17) | func BenchmarkClone(b *testing.B) {
function BenchmarkContent (line 94) | func BenchmarkContent(b *testing.B) {
function BenchmarkGitOperations (line 150) | func BenchmarkGitOperations(b *testing.B) {
FILE: internal/cas/cas.go
type Options (line 26) | type Options struct
type CloneOptions (line 33) | type CloneOptions struct
type CAS (line 48) | type CAS struct
method Clone (line 88) | func (c *CAS) Clone(ctx context.Context, l log.Logger, opts *CloneOpti...
method prepareTargetDirectory (line 152) | func (c *CAS) prepareTargetDirectory(dir, url string) string {
method resolveReference (line 161) | func (c *CAS) resolveReference(ctx context.Context, url, branch string...
method cloneAndStoreContent (line 178) | func (c *CAS) cloneAndStoreContent(
method storeRootTree (line 192) | func (c *CAS) storeRootTree(ctx context.Context, l log.Logger, hash st...
method storeTreeRecursive (line 246) | func (c *CAS) storeTreeRecursive(ctx context.Context, l log.Logger, ha...
method storeBlobs (line 265) | func (c *CAS) storeBlobs(ctx context.Context, entries []git.TreeEntry)...
method ensureBlob (line 283) | func (c *CAS) ensureBlob(ctx context.Context, hash string) error {
function New (line 57) | func New(opts Options) (*CAS, error) {
function hashFile (line 345) | func hashFile(path string) (string, error) {
FILE: internal/cas/cas_test.go
function TestCAS_Clone (line 14) | func TestCAS_Clone(t *testing.T) {
FILE: internal/cas/content.go
type Content (line 16) | type Content struct
method Link (line 39) | func (c *Content) Link(ctx context.Context, hash, targetPath string) e...
method Store (line 90) | func (c *Content) Store(l log.Logger, hash string, data []byte) error {
method Ensure (line 116) | func (c *Content) Ensure(l log.Logger, hash string, data []byte) error {
method EnsureWithWait (line 127) | func (c *Content) EnsureWithWait(l log.Logger, hash string, data []byt...
method writeContentToFile (line 160) | func (c *Content) writeContentToFile(l log.Logger, hash string, data [...
method EnsureCopy (line 240) | func (c *Content) EnsureCopy(l log.Logger, hash, src string) error {
method GetTmpHandle (line 285) | func (c *Content) GetTmpHandle(hash string) (*os.File, error) {
method Read (line 303) | func (c *Content) Read(hash string) ([]byte, error) {
method getPartition (line 309) | func (c *Content) getPartition(hash string) string {
method getPath (line 314) | func (c *Content) getPath(hash string) string {
constant DefaultDirPerms (line 22) | DefaultDirPerms = os.FileMode(0755)
constant StoredFilePerms (line 24) | StoredFilePerms = os.FileMode(0444)
constant RegularFilePerms (line 26) | RegularFilePerms = os.FileMode(0644)
constant WindowsOS (line 28) | WindowsOS = "windows"
function NewContent (line 32) | func NewContent(store *Store) *Content {
FILE: internal/cas/content_test.go
constant testHashValue (line 15) | testHashValue = "abcdef123456"
function TestContent_Store (line 17) | func TestContent_Store(t *testing.T) {
function TestContent_Link (line 90) | func TestContent_Link(t *testing.T) {
function TestContent_EnsureWithWait (line 158) | func TestContent_EnsureWithWait(t *testing.T) {
FILE: internal/cas/errors.go
type Error (line 10) | type Error
method Error (line 12) | func (e Error) Error() string {
constant ErrTempDir (line 18) | ErrTempDir Error = "failed to create or manage temporary directory"
constant ErrCreateDir (line 20) | ErrCreateDir Error = "failed to create directory"
constant ErrReadFile (line 22) | ErrReadFile Error = "failed to read file"
constant ErrGitClone (line 24) | ErrGitClone Error = "failed to complete git clone"
type WrappedError (line 28) | type WrappedError struct
method Error (line 35) | func (e *WrappedError) Error() string {
method Unwrap (line 43) | func (e *WrappedError) Unwrap() error {
function wrapError (line 55) | func wrapError(op, path string, err error) error {
FILE: internal/cas/errors_test.go
function TestErrorString (line 11) | func TestErrorString(t *testing.T) {
function TestWrappedError (line 39) | func TestWrappedError(t *testing.T) {
FILE: internal/cas/getter.go
type CASGetter (line 19) | type CASGetter struct
method Get (line 41) | func (g *CASGetter) Get(ctx context.Context, req *getter.Request) error {
method GetFile (line 81) | func (g *CASGetter) GetFile(_ context.Context, req *getter.Request) er...
method Mode (line 85) | func (g *CASGetter) Mode(_ context.Context, url *url.URL) (getter.Mode...
method Detect (line 89) | func (g *CASGetter) Detect(req *getter.Request) (bool, error) {
function NewCASGetter (line 26) | func NewCASGetter(l log.Logger, cas *CAS, opts *CloneOptions) *CASGetter {
FILE: internal/cas/getter_ssh_test.go
function TestSSHCASGetterGet (line 24) | func TestSSHCASGetterGet(t *testing.T) {
FILE: internal/cas/getter_test.go
function TestCASGetterMode (line 17) | func TestCASGetterMode(t *testing.T) {
function TestCASGetterGetFile (line 29) | func TestCASGetterGetFile(t *testing.T) {
function TestCASGetterDetect (line 38) | func TestCASGetterDetect(t *testing.T) {
function TestCASGetterGet (line 97) | func TestCASGetterGet(t *testing.T) {
function TestCASGetterLocalDir (line 152) | func TestCASGetterLocalDir(t *testing.T) {
FILE: internal/cas/integration_test.go
function TestIntegration_CloneAndReuse (line 16) | func TestIntegration_CloneAndReuse(t *testing.T) {
function TestIntegration_TreeStorage (line 104) | func TestIntegration_TreeStorage(t *testing.T) {
FILE: internal/cas/local.go
method StoreLocalDirectory (line 18) | func (c *CAS) StoreLocalDirectory(ctx context.Context, l log.Logger, sou...
method hashDirectory (line 40) | func (c *CAS) hashDirectory(sourceDir string) (string, []byte, error) {
method storeLocalContent (line 90) | func (c *CAS) storeLocalContent(l log.Logger, sourceDir, dirHash string,...
function hashString (line 122) | func hashString(s string) string {
FILE: internal/cas/race_test.go
function TestCASGetterGetWithRacing (line 17) | func TestCASGetterGetWithRacing(t *testing.T) {
FILE: internal/cas/store.go
type Store (line 11) | type Store struct
method Path (line 23) | func (s *Store) Path() string {
method NeedsWrite (line 28) | func (s *Store) NeedsWrite(hash string) bool {
method hasContent (line 36) | func (s *Store) hasContent(path string) bool {
method AcquireLock (line 44) | func (s *Store) AcquireLock(hash string) (*flock.Flock, error) {
method TryAcquireLock (line 63) | func (s *Store) TryAcquireLock(hash string) (*flock.Flock, bool, error) {
method EnsureWithWait (line 94) | func (s *Store) EnsureWithWait(hash string) (needsWrite bool, lock *fl...
function NewStore (line 16) | func NewStore(path string) *Store {
FILE: internal/cas/store_test.go
function TestStore (line 15) | func TestStore(t *testing.T) {
function TestStore_NeedsWrite (line 28) | func TestStore_NeedsWrite(t *testing.T) {
function TestStore_AcquireLock (line 69) | func TestStore_AcquireLock(t *testing.T) {
function TestStore_TryAcquireLock (line 89) | func TestStore_TryAcquireLock(t *testing.T) {
function TestStore_LockConcurrency (line 122) | func TestStore_LockConcurrency(t *testing.T) {
function TestStore_EnsureWithWait (line 170) | func TestStore_EnsureWithWait(t *testing.T) {
FILE: internal/cas/tree.go
function LinkTree (line 14) | func LinkTree(ctx context.Context, store *Store, t *git.Tree, targetDir ...
FILE: internal/cas/tree_test.go
function TestParseTreeEntry (line 15) | func TestParseTreeEntry(t *testing.T) {
function TestParseTree (line 87) | func TestParseTree(t *testing.T) {
function TestLinkTree (line 140) | func TestLinkTree(t *testing.T) {
FILE: internal/cli/app.go
constant AppName (line 32) | AppName = "terragrunt"
function init (line 35) | func init() {
type App (line 41) | type App struct
method Run (line 69) | func (app *App) Run(args []string) error {
method registerGracefullyShutdown (line 73) | func (app *App) registerGracefullyShutdown(ctx context.Context) contex...
method RunContext (line 87) | func (app *App) RunContext(ctx context.Context, args []string) error {
function NewApp (line 48) | func NewApp(l log.Logger, opts *options.TerragruntOptions) *App {
function removeNoColorFlagDuplicates (line 133) | func removeNoColorFlagDuplicates(args []string) []string {
function beforeAction (line 154) | func beforeAction(_ *options.TerragruntOptions) clihelper.ActionFunc {
function OSExiter (line 185) | func OSExiter(exitCode int) {
function ExitErrHandler (line 191) | func ExitErrHandler(_ *clihelper.Context, err error) error {
FILE: internal/cli/app_test.go
function TestParseTerragruntOptionsFromArgs (line 38) | func TestParseTerragruntOptionsFromArgs(t *testing.T) {
function assertOptionsEqual (line 463) | func assertOptionsEqual(t *testing.T, expected *options.TerragruntOption...
function mockOptions (line 478) | func mockOptions(t *testing.T, terragruntConfigPath string, workingDir s...
function mockOptionsWithIamRole (line 496) | func mockOptionsWithIamRole(t *testing.T, terragruntConfigPath string, w...
function mockOptionsWithIamAssumeRoleDuration (line 506) | func mockOptionsWithIamAssumeRoleDuration(t *testing.T, terragruntConfig...
function mockOptionsWithIamAssumeRoleSessionName (line 516) | func mockOptionsWithIamAssumeRoleSessionName(t *testing.T, terragruntCon...
function mockOptionsWithIamWebIdentityToken (line 526) | func mockOptionsWithIamWebIdentityToken(t *testing.T, terragruntConfigPa...
function mockOptionsWithSourceMap (line 536) | func mockOptionsWithSourceMap(t *testing.T, terragruntConfigPath string,...
function TestFilterTerragruntArgs (line 545) | func TestFilterTerragruntArgs(t *testing.T) {
function TestParseMultiStringArg (line 612) | func TestParseMultiStringArg(t *testing.T) {
function TestParseMutliStringKeyValueArg (line 667) | func TestParseMutliStringKeyValueArg(t *testing.T) {
function TestTerragruntVersion (line 727) | func TestTerragruntVersion(t *testing.T) {
function TestTerragruntHelp (line 753) | func TestTerragruntHelp(t *testing.T) {
function TestTerraformHelp (line 811) | func TestTerraformHelp(t *testing.T) {
function TestTerraformHelp_wrongHelpFlag (line 834) | func TestTerraformHelp_wrongHelpFlag(t *testing.T) {
function setCommandAction (line 846) | func setCommandAction(action clihelper.ActionFunc, cmds ...*clihelper.Co...
function runAppTest (line 853) | func runAppTest(l log.Logger, args []string, opts *options.TerragruntOpt...
function doubleDashed (line 887) | func doubleDashed(name string) string {
type argMissingValueError (line 891) | type argMissingValueError
method Error (line 893) | func (err argMissingValueError) Error() string {
function TestAutocomplete (line 897) | func TestAutocomplete(t *testing.T) { //nolint:paralleltest
FILE: internal/cli/commands/aws-provider-patch/aws-provider-patch.go
constant defaultKeyParts (line 25) | defaultKeyParts = 2
function Run (line 27) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function runSingle (line 35) | func runSingle(ctx context.Context, l log.Logger, opts *options.Terragru...
function runAll (line 61) | func runAll(ctx context.Context, l log.Logger, opts *options.TerragruntO...
function runAwsProviderPatch (line 102) | func runAwsProviderPatch(l log.Logger, opts *options.TerragruntOptions) ...
type TerraformModulesJSON (line 138) | type TerraformModulesJSON struct
type TerraformModule (line 142) | type TerraformModule struct
function findAllTerraformFilesInModules (line 154) | func findAllTerraformFilesInModules(opts *options.TerragruntOptions) ([]...
function PatchAwsProviderInTerraformCode (line 223) | func PatchAwsProviderInTerraformCode(terraformCode string, terraformFile...
function overrideAttributeInBlock (line 297) | func overrideAttributeInBlock(block *hclwrite.Block, key string, value s...
function traverseBlock (line 364) | func traverseBlock(block *hclwrite.Block, keyParts []string) (*hclwrite....
FILE: internal/cli/commands/aws-provider-patch/aws-provider-patch_test.go
constant terraformCodeExampleOutputOnly (line 11) | terraformCodeExampleOutputOnly = `
constant terraformCodeExampleGcpProvider (line 17) | terraformCodeExampleGcpProvider = `
constant terraformCodeExampleAwsProviderEmptyOriginal (line 29) | terraformCodeExampleAwsProviderEmptyOriginal = `
constant terraformCodeExampleAwsProviderRegionVersionOverridenExpected (line 38) | terraformCodeExampleAwsProviderRegionVersionOverridenExpected = `
constant terraformCodeExampleAwsProviderRegionVersionOverridenReverseOrderExpected (line 49) | terraformCodeExampleAwsProviderRegionVersionOverridenReverseOrderExpecte...
constant terraformCodeExampleAwsProviderNonEmptyOriginal (line 60) | terraformCodeExampleAwsProviderNonEmptyOriginal = `
constant terraformCodeExampleAwsProviderRegionOverridenVersionNotOverriddenExpected (line 71) | terraformCodeExampleAwsProviderRegionOverridenVersionNotOverriddenExpect...
constant terraformCodeExampleAwsMultipleProvidersOriginal (line 82) | terraformCodeExampleAwsMultipleProvidersOriginal = `
constant terraformCodeExampleAwsMultipleProvidersRegionOverridenExpected (line 114) | terraformCodeExampleAwsMultipleProvidersRegionOverridenExpected = `
constant terraformCodeExampleAwsMultipleProvidersRegionVersionOverridenExpected (line 146) | terraformCodeExampleAwsMultipleProvidersRegionVersionOverridenExpected = `
constant terraformCodeExampleAwsMultipleProvidersNonEmptyWithCommentsOriginal (line 178) | terraformCodeExampleAwsMultipleProvidersNonEmptyWithCommentsOriginal = `
constant terraformCodeExampleAwsMultipleProvidersNonEmptyWithCommentsRegionOverriddenExpected (line 208) | terraformCodeExampleAwsMultipleProvidersNonEmptyWithCommentsRegionOverri...
constant terraformCodeExampleAwsMultipleProvidersNonEmptyWithCommentsRegionVersionOverriddenExpected (line 238) | terraformCodeExampleAwsMultipleProvidersNonEmptyWithCommentsRegionVersio...
constant terraformCodeExampleAwsOneProviderNestedBlocks (line 268) | terraformCodeExampleAwsOneProviderNestedBlocks = `
constant terraformCodeExampleAwsOneProviderNestedBlocksRegionRoleArnExpected (line 277) | terraformCodeExampleAwsOneProviderNestedBlocksRegionRoleArnExpected = `
function TestPatchAwsProviderInTerraformCodeHappyPath (line 286) | func TestPatchAwsProviderInTerraformCodeHappyPath(t *testing.T) {
FILE: internal/cli/commands/aws-provider-patch/cli.go
constant CommandName (line 45) | CommandName = "aws-provider-patch"
constant OverrideAttrFlagName (line 47) | OverrideAttrFlagName = "override-attr"
function NewFlags (line 50) | func NewFlags(l log.Logger, opts *options.TerragruntOptions, prefix flag...
function NewCommand (line 66) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/aws-provider-patch/errors.go
type MissingOverrideAttrError (line 5) | type MissingOverrideAttrError
method Error (line 7) | func (flagName MissingOverrideAttrError) Error() string {
type TypeInferenceError (line 11) | type TypeInferenceError struct
method Error (line 16) | func (err TypeInferenceError) Error() string {
type MalformedJSONValError (line 21) | type MalformedJSONValError struct
method Error (line 26) | func (err MalformedJSONValError) Error() string {
FILE: internal/cli/commands/aws-provider-patch/tofu_extensions_test.go
constant tofuCodeExampleAwsProviderOriginal (line 19) | tofuCodeExampleAwsProviderOriginal = `
constant tofuCodeExampleAwsProviderRegionOverridden (line 30) | tofuCodeExampleAwsProviderRegionOverridden = `
constant tofuCodeExampleMultipleProvidersOriginal (line 41) | tofuCodeExampleMultipleProvidersOriginal = `
constant tofuCodeExampleMultipleProvidersRegionOverridden (line 62) | tofuCodeExampleMultipleProvidersRegionOverridden = `
constant tofuCodeExampleNestedBlocksOriginal (line 83) | tofuCodeExampleNestedBlocksOriginal = `
constant tofuCodeExampleNestedBlocksRegionRoleArnOverridden (line 99) | tofuCodeExampleNestedBlocksRegionRoleArnOverridden = `
function TestPatchAwsProviderInTofuCode (line 115) | func TestPatchAwsProviderInTofuCode(t *testing.T) {
function TestFindAllTerraformFilesIncludesTofuFiles (line 180) | func TestFindAllTerraformFilesIncludesTofuFiles(t *testing.T) {
function TestAwsProviderPatchWithMixedFileTypes (line 259) | func TestAwsProviderPatchWithMixedFileTypes(t *testing.T) {
function TestTofuFileExtensionRecognition (line 303) | func TestTofuFileExtensionRecognition(t *testing.T) {
FILE: internal/cli/commands/backend/bootstrap/bootstrap.go
function Run (line 18) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function runBootstrap (line 26) | func runBootstrap(ctx context.Context, l log.Logger, opts *options.Terra...
function runAll (line 37) | func runAll(ctx context.Context, l log.Logger, opts *options.TerragruntO...
FILE: internal/cli/commands/backend/bootstrap/cli.go
constant CommandName (line 13) | CommandName = "bootstrap"
function NewFlags (line 15) | func NewFlags(opts *options.TerragruntOptions) clihelper.Flags {
function NewCommand (line 28) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/backend/cli.go
constant CommandName (line 13) | CommandName = "backend"
function NewCommand (line 15) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/backend/delete/cli.go
constant CommandName (line 14) | CommandName = "delete"
constant BucketFlagName (line 16) | BucketFlagName = "bucket"
constant ForceBackendDeleteFlagName (line 17) | ForceBackendDeleteFlagName = "force"
function NewFlags (line 20) | func NewFlags(l log.Logger, opts *options.TerragruntOptions, prefix flag...
function NewCommand (line 47) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/backend/delete/delete.go
function Run (line 19) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function runDelete (line 27) | func runDelete(ctx context.Context, l log.Logger, opts *options.Terragru...
function runAll (line 54) | func runAll(ctx context.Context, l log.Logger, opts *options.TerragruntO...
FILE: internal/cli/commands/backend/migrate/cli.go
constant CommandName (line 15) | CommandName = "migrate"
constant ForceBackendMigrateFlagName (line 17) | ForceBackendMigrateFlagName = "force"
constant usageText (line 19) | usageText = "terragrunt backend migrate [options] <src-unit> <dst-unit>"
function NewFlags (line 22) | func NewFlags(l log.Logger, opts *options.TerragruntOptions, prefix flag...
function NewCommand (line 42) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/backend/migrate/migrate.go
function Run (line 18) | func Run(ctx context.Context, l log.Logger, srcPath, dstPath string, opt...
FILE: internal/cli/commands/catalog/catalog.go
function Run (line 15) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
FILE: internal/cli/commands/catalog/catalog_test.go
function TestCatalogCommandInitialization (line 22) | func TestCatalogCommandInitialization(t *testing.T) {
FILE: internal/cli/commands/catalog/cli.go
constant CommandName (line 17) | CommandName = "catalog"
function NewFlags (line 20) | func NewFlags(opts *options.TerragruntOptions, prefix flags.Prefix) clih...
function NewCommand (line 24) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/catalog/tui/command/scaffold.go
type Scaffold (line 15) | type Scaffold struct
method Run (line 31) | func (cmd *Scaffold) Run() error {
method SetStdin (line 35) | func (cmd *Scaffold) SetStdin(io.Reader) {
method SetStdout (line 38) | func (cmd *Scaffold) SetStdout(io.Writer) {
method SetStderr (line 41) | func (cmd *Scaffold) SetStderr(io.Writer) {
function NewScaffold (line 22) | func NewScaffold(logger log.Logger, opts *options.TerragruntOptions, svc...
FILE: internal/cli/commands/catalog/tui/components/buttonbar/buttonbar.go
type SelectBtnMsg (line 13) | type SelectBtnMsg
type ActiveBtnMsg (line 16) | type ActiveBtnMsg
constant defaultButtonNameFmt (line 19) | defaultButtonNameFmt = "[ %s ]"
type ButtonBar (line 29) | type ButtonBar struct
method Init (line 51) | func (b *ButtonBar) Init() tea.Cmd {
method Update (line 57) | func (b *ButtonBar) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
method View (line 81) | func (b *ButtonBar) View() string {
method activeBtnCmd (line 100) | func (b *ButtonBar) activeBtnCmd() tea.Msg {
function New (line 39) | func New(buttons []string) *ButtonBar {
FILE: internal/cli/commands/catalog/tui/delegate.go
constant selectedTitleForegroundColorDark (line 10) | selectedTitleForegroundColorDark = "#63C5DA"
constant selectedTitleBorderForegroundColorDark (line 11) | selectedTitleBorderForegroundColorDark = "#63C5DA"
constant selectedDescForegroundColorDark (line 13) | selectedDescForegroundColorDark = "#59788E"
constant selectedDescBorderForegroundColorDark (line 14) | selectedDescBorderForegroundColorDark = "#63C5DA"
function newItemDelegate (line 17) | func newItemDelegate(keys *delegateKeyMap) list.DefaultDelegate {
FILE: internal/cli/commands/catalog/tui/keys.go
function newListKeyMap (line 11) | func newListKeyMap() list.KeyMap {
type delegateKeyMap (line 76) | type delegateKeyMap struct
method ShortHelp (line 83) | func (d delegateKeyMap) ShortHelp() []key.Binding { //nolint:gocritic
method FullHelp (line 92) | func (d delegateKeyMap) FullHelp() [][]key.Binding { //nolint:gocritic
function newDelegateKeyMap (line 102) | func newDelegateKeyMap() *delegateKeyMap {
type pagerKeyMap (line 117) | type pagerKeyMap struct
method ShortHelp (line 146) | func (keys pagerKeyMap) ShortHelp() []key.Binding { //nolint:gocritic
method FullHelp (line 161) | func (keys pagerKeyMap) FullHelp() [][]key.Binding { //nolint:gocritic
function newPagerKeyMap (line 170) | func newPagerKeyMap() pagerKeyMap {
FILE: internal/cli/commands/catalog/tui/model.go
type sessionState (line 17) | type sessionState
type button (line 20) | type button
method String (line 44) | func (b button) String() string {
constant title (line 23) | title = "List of Modules"
constant titleForegroundColor (line 25) | titleForegroundColor = "#A8ACB1"
constant titleBackgroundColor (line 26) | titleBackgroundColor = "#1D252F"
constant ListState (line 30) | ListState sessionState = iota
constant PagerState (line 31) | PagerState
constant ScaffoldState (line 32) | ScaffoldState
constant scaffoldBtn (line 36) | scaffoldBtn button = iota
constant viewSourceBtn (line 37) | viewSourceBtn
type Model (line 51) | type Model struct
method Init (line 120) | func (m Model) Init() tea.Cmd { //nolint:gocritic
function NewModel (line 70) | func NewModel(l log.Logger, opts *options.TerragruntOptions, svc catalog...
FILE: internal/cli/commands/catalog/tui/model_test.go
function createMockCatalogService (line 32) | func createMockCatalogService(t *testing.T, opts *options.TerragruntOpti...
function TestTUIFinalModel (line 116) | func TestTUIFinalModel(t *testing.T) {
function TestTUIInitialOutput (line 151) | func TestTUIInitialOutput(t *testing.T) {
function TestTUINavigationToModuleDetails (line 177) | func TestTUINavigationToModuleDetails(t *testing.T) {
function TestTUIModuleFiltering (line 227) | func TestTUIModuleFiltering(t *testing.T) {
function TestTUIWindowResize (line 282) | func TestTUIWindowResize(t *testing.T) {
function TestTUIScaffoldWithRealRepository (line 319) | func TestTUIScaffoldWithRealRepository(t *testing.T) {
FILE: internal/cli/commands/catalog/tui/tui.go
function Run (line 15) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
FILE: internal/cli/commands/catalog/tui/update.go
function updateList (line 21) | func updateList(msg tea.Msg, m Model) (tea.Model, tea.Cmd) { //nolint:go...
function updatePager (line 110) | func updatePager(msg tea.Msg, m Model) (tea.Model, tea.Cmd) { //nolint:g...
method Update (line 171) | func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { //nolint:gocritic
type rendererErrMsg (line 221) | type rendererErrMsg struct
function rendererErrCmd (line 223) | func rendererErrCmd(err error) tea.Cmd {
type scaffoldFinishedMsg (line 229) | type scaffoldFinishedMsg struct
function scaffoldModuleCmd (line 232) | func scaffoldModuleCmd(l log.Logger, m Model, svc catalog.CatalogService...
FILE: internal/cli/commands/catalog/tui/view.go
method View (line 19) | func (m Model) View() string { //nolint:gocritic
method listView (line 35) | func (m Model) listView() string { //nolint:gocritic
method pagerView (line 39) | func (m Model) pagerView() string { //nolint:gocritic
method footerView (line 43) | func (m Model) footerView() string { //nolint:gocritic
FILE: internal/cli/commands/commands.go
constant MainCommandsCategoryName (line 54) | MainCommandsCategoryName = "Main commands"
constant CatalogCommandsCategoryName (line 56) | CatalogCommandsCategoryName = "Catalog commands"
constant DiscoveryCommandsCategoryName (line 58) | DiscoveryCommandsCategoryName = "Discovery commands"
constant ConfigurationCommandsCategoryName (line 60) | ConfigurationCommandsCategoryName = "Configuration commands"
constant ShortcutsCommandsCategoryName (line 62) | ShortcutsCommandsCategoryName = "OpenTofu shortcuts"
function New (line 67) | func New(l log.Logger, opts *options.TerragruntOptions) clihelper.Comman...
function WrapWithTelemetry (line 132) | func WrapWithTelemetry(l log.Logger, opts *options.TerragruntOptions) fu...
function runAction (line 153) | func runAction(ctx context.Context, cliCtx *clihelper.Context, l log.Log...
constant minTofuVersionForAutoProviderCacheDir (line 209) | minTofuVersionForAutoProviderCacheDir = "1.10.0"
function setupAutoProviderCacheDir (line 214) | func setupAutoProviderCacheDir(ctx context.Context, l log.Logger, opts *...
function initialSetup (line 295) | func initialSetup(cliCtx *clihelper.Context, l log.Logger, opts *options...
FILE: internal/cli/commands/dag/cli.go
constant CommandName (line 13) | CommandName = "dag"
function NewCommand (line 16) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/dag/graph/cli.go
constant CommandName (line 18) | CommandName = "graph"
function NewCommand (line 21) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
function Run (line 38) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
FILE: internal/cli/commands/dag/graph/cli_test.go
function BenchmarkRunGraphDependencies (line 15) | func BenchmarkRunGraphDependencies(b *testing.B) {
FILE: internal/cli/commands/exec/cli.go
constant CommandName (line 16) | CommandName = "exec"
constant InDownloadDirFlagName (line 18) | InDownloadDirFlagName = "in-download-dir"
function NewFlags (line 21) | func NewFlags(l log.Logger, opts *options.TerragruntOptions, cmdOpts *Op...
function NewCommand (line 45) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/exec/exec.go
function Run (line 18) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function runTargetCommand (line 56) | func runTargetCommand(
FILE: internal/cli/commands/exec/options.go
type Options (line 3) | type Options struct
function NewOptions (line 9) | func NewOptions() *Options {
FILE: internal/cli/commands/find/cli.go
constant CommandName (line 18) | CommandName = "find"
constant CommandAlias (line 19) | CommandAlias = "fd"
constant FormatFlagName (line 21) | FormatFlagName = "format"
constant JSONFlagName (line 23) | JSONFlagName = "json"
constant JSONFlagAlias (line 24) | JSONFlagAlias = "j"
constant DAGFlagName (line 26) | DAGFlagName = "dag"
constant HiddenFlagName (line 28) | HiddenFlagName = "hidden"
constant NoHiddenFlagName (line 29) | NoHiddenFlagName = "no-hidden"
constant Dependencies (line 30) | Dependencies = "dependencies"
constant External (line 31) | External = "external"
constant Exclude (line 32) | Exclude = "exclude"
constant Include (line 33) | Include = "include"
constant Reading (line 34) | Reading = "reading"
constant QueueConstructAsFlagName (line 36) | QueueConstructAsFlagName = "queue-construct-as"
constant QueueConstructAsFlagAlias (line 37) | QueueConstructAsFlagAlias = "as"
function NewFlags (line 40) | func NewFlags(l log.Logger, opts *Options, prefix flags.Prefix) clihelpe...
function NewCommand (line 142) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/find/find.go
function Run (line 24) | func Run(ctx context.Context, l log.Logger, opts *Options) error {
type FoundComponents (line 132) | type FoundComponents
type FoundComponent (line 134) | type FoundComponent struct
function discoveredToFound (line 145) | func discoveredToFound(components component.Components, opts *Options) (...
function outputJSON (line 255) | func outputJSON(opts *Options, components FoundComponents) error {
type Colorizer (line 270) | type Colorizer struct
method Colorize (line 293) | func (c *Colorizer) Colorize(foundComponent *FoundComponent) string {
function NewColorizer (line 277) | func NewColorizer(shouldColor bool) *Colorizer {
function outputText (line 325) | func outputText(l log.Logger, opts *Options, components FoundComponents)...
function shouldColor (line 340) | func shouldColor(l log.Logger) bool {
FILE: internal/cli/commands/find/find_test.go
function TestRun (line 20) | func TestRun(t *testing.T) {
function TestColorizer (line 538) | func TestColorizer(t *testing.T) {
FILE: internal/cli/commands/find/options.go
constant FormatText (line 10) | FormatText = "text"
constant FormatJSON (line 13) | FormatJSON = "json"
constant ModeNormal (line 16) | ModeNormal = "normal"
constant ModeDAG (line 19) | ModeDAG = "dag"
type Options (line 22) | type Options struct
method Validate (line 65) | func (o *Options) Validate() error {
method validateFormat (line 83) | func (o *Options) validateFormat() error {
method validateMode (line 94) | func (o *Options) validateMode() error {
function NewOptions (line 57) | func NewOptions(opts *options.TerragruntOptions) *Options {
FILE: internal/cli/commands/hcl/cli.go
constant CommandName (line 12) | CommandName = "hcl"
function NewCommand (line 14) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/hcl/format/cli.go
constant CommandName (line 14) | CommandName = "format"
constant CommandNameAlias (line 15) | CommandNameAlias = "fmt"
constant FileFlagName (line 17) | FileFlagName = "file"
constant ExcludeDirFlagName (line 18) | ExcludeDirFlagName = "exclude-dir"
constant CheckFlagName (line 19) | CheckFlagName = "check"
constant DiffFlagName (line 20) | DiffFlagName = "diff"
constant StdinFlagName (line 21) | StdinFlagName = "stdin"
function NewFlags (line 24) | func NewFlags(l log.Logger, opts *options.TerragruntOptions, prefix flag...
function NewCommand (line 88) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/hcl/format/errors.go
type FileNeedsFormattingError (line 6) | type FileNeedsFormattingError struct
method Error (line 10) | func (e FileNeedsFormattingError) Error() string {
FILE: internal/cli/commands/hcl/format/format.go
function Run (line 42) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function formatFromStdin (line 144) | func formatFromStdin(l log.Logger, opts *options.TerragruntOptions) error {
function formatTgHCL (line 179) | func formatTgHCL(ctx context.Context, l log.Logger, opts *options.Terrag...
function checkErrors (line 231) | func checkErrors(l log.Logger, disableColor bool, contents []byte, tgHcl...
function bytesDiff (line 251) | func bytesDiff(ctx context.Context, l log.Logger, b1, b2 []byte, path st...
FILE: internal/cli/commands/hcl/format/format_bench_test.go
function BenchmarkFormat (line 18) | func BenchmarkFormat(b *testing.B) {
function createFiles (line 71) | func createFiles(workingDir string, content []byte, count int) error {
FILE: internal/cli/commands/hcl/format/format_test.go
function TestHCLFmt (line 19) | func TestHCLFmt(t *testing.T) {
function TestHCLFmtErrors (line 96) | func TestHCLFmtErrors(t *testing.T) {
function TestHCLFmtCheck (line 130) | func TestHCLFmtCheck(t *testing.T) {
function TestHCLFmtCheckErrors (line 174) | func TestHCLFmtCheckErrors(t *testing.T) {
function TestHCLFmtFile (line 217) | func TestHCLFmtFile(t *testing.T) {
function TestHCLFmtStdin (line 274) | func TestHCLFmtStdin(t *testing.T) {
function TestHCLFmtHeredoc (line 314) | func TestHCLFmtHeredoc(t *testing.T) {
function TestHCLFmtFilter (line 339) | func TestHCLFmtFilter(t *testing.T) {
function TestHCLFmtFilterMultiple (line 408) | func TestHCLFmtFilterMultiple(t *testing.T) {
function TestHCLFmtFilterNegation (line 480) | func TestHCLFmtFilterNegation(t *testing.T) {
FILE: internal/cli/commands/hcl/validate/cli.go
constant CommandName (line 14) | CommandName = "validate"
constant StrictFlagName (line 16) | StrictFlagName = "strict"
constant InputsFlagName (line 17) | InputsFlagName = "inputs"
constant ShowConfigPathFlagName (line 18) | ShowConfigPathFlagName = "show-config-path"
constant JSONFlagName (line 19) | JSONFlagName = "json"
function NewFlags (line 22) | func NewFlags(l log.Logger, opts *options.TerragruntOptions) clihelper.F...
function NewCommand (line 83) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/hcl/validate/validate.go
constant splitCount (line 40) | splitCount = 2
function Run (line 42) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function RunValidate (line 62) | func RunValidate(ctx context.Context, l log.Logger, opts *options.Terrag...
function processDiagnostics (line 183) | func processDiagnostics(l log.Logger, opts *options.TerragruntOptions, d...
function writeDiagnostics (line 218) | func writeDiagnostics(l log.Logger, opts *options.TerragruntOptions, dia...
function RunValidateInputs (line 233) | func RunValidateInputs(ctx context.Context, l log.Logger, opts *options....
function runValidateInputs (line 322) | func runValidateInputs(l log.Logger, opts *options.TerragruntOptions, cf...
function getDefinedTerragruntInputs (line 400) | func getDefinedTerragruntInputs(l log.Logger, opts *options.TerragruntOp...
function getTerraformInputNamesFromEnvVar (line 453) | func getTerraformInputNamesFromEnvVar(opts *options.TerragruntOptions, t...
function getTerraformInputNamesFromConfig (line 482) | func getTerraformInputNamesFromConfig(terragruntConfig *config.Terragrun...
function getTerraformInputNamesFromVarFiles (line 493) | func getTerraformInputNamesFromVarFiles(l log.Logger, terragruntConfig *...
function getTerraformInputNamesFromCLIArgs (line 509) | func getTerraformInputNamesFromCLIArgs(l log.Logger, opts *options.Terra...
function getTerraformInputNamesFromAutomaticVarFiles (line 540) | func getTerraformInputNamesFromAutomaticVarFiles(l log.Logger, opts *opt...
function getVarNamesFromVarFiles (line 573) | func getVarNamesFromVarFiles(l log.Logger, varFiles []string) ([]string,...
function getVarNamesFromVarFile (line 590) | func getVarNamesFromVarFile(l log.Logger, varFile string) ([]string, err...
function GetVarFlagsFromArgList (line 617) | func GetVarFlagsFromArgList(argList []string) ([]string, []string, error) {
FILE: internal/cli/commands/hcl/validate/validate_test.go
function TestGetVarFlagsFromExtraArgs (line 12) | func TestGetVarFlagsFromExtraArgs(t *testing.T) {
FILE: internal/cli/commands/help/cli.go
constant CommandName (line 15) | CommandName = "help"
function NewCommand (line 18) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
function Action (line 30) | func Action(ctx context.Context, cliCtx *clihelper.Context, l log.Logger...
FILE: internal/cli/commands/info/cli.go
constant CommandName (line 13) | CommandName = "info"
function NewCommand (line 16) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/info/print/cli.go
constant CommandName (line 14) | CommandName = "print"
function NewCommand (line 17) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/info/print/print.go
function Run (line 24) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function runPrint (line 33) | func runPrint(ctx context.Context, l log.Logger, opts *options.Terragrun...
function runAll (line 62) | func runAll(ctx context.Context, l log.Logger, opts *options.TerragruntO...
type InfoOutput (line 104) | type InfoOutput struct
function printTerragruntContext (line 113) | func printTerragruntContext(l log.Logger, opts *options.TerragruntOption...
FILE: internal/cli/commands/info/strict/command.go
constant CommandName (line 21) | CommandName = "strict"
constant ListCommandName (line 23) | ListCommandName = "list"
constant ShowAllFlagName (line 25) | ShowAllFlagName = "all"
function NewListFlags (line 28) | func NewListFlags(opts *options.TerragruntOptions, prefix flags.Prefix) ...
function NewCommand (line 40) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
function ListAction (line 57) | func ListAction(opts *options.TerragruntOptions) func(ctx context.Contex...
FILE: internal/cli/commands/list/cli.go
constant CommandName (line 18) | CommandName = "list"
constant CommandAlias (line 19) | CommandAlias = "ls"
constant FormatFlagName (line 21) | FormatFlagName = "format"
constant TreeFlagName (line 23) | TreeFlagName = "tree"
constant TreeFlagAlias (line 24) | TreeFlagAlias = "T"
constant LongFlagName (line 26) | LongFlagName = "long"
constant LongFlagAlias (line 27) | LongFlagAlias = "l"
constant HiddenFlagName (line 29) | HiddenFlagName = "hidden"
constant NoHiddenFlagName (line 30) | NoHiddenFlagName = "no-hidden"
constant DependenciesFlagName (line 31) | DependenciesFlagName = "dependencies"
constant ExternalFlagName (line 32) | ExternalFlagName = "external"
constant DAGFlagName (line 34) | DAGFlagName = "dag"
constant QueueConstructAsFlagName (line 36) | QueueConstructAsFlagName = "queue-construct-as"
constant QueueConstructAsFlagAlias (line 37) | QueueConstructAsFlagAlias = "as"
function NewFlags (line 40) | func NewFlags(l log.Logger, opts *Options, prefix flags.Prefix) clihelpe...
function NewCommand (line 131) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/list/list.go
function Run (line 27) | func Run(ctx context.Context, l log.Logger, opts *Options) error {
type ListedComponents (line 135) | type ListedComponents
method Contains (line 145) | func (l ListedComponents) Contains(path string) bool {
method Get (line 156) | func (l ListedComponents) Get(path string) *ListedComponent {
type ListedComponent (line 137) | type ListedComponent struct
function discoveredToListed (line 166) | func discoveredToListed(components component.Components, opts *Options) ...
type Colorizer (line 263) | type Colorizer struct
method Colorize (line 289) | func (c *Colorizer) Colorize(listedComponent *ListedComponent) string {
method ColorizeType (line 320) | func (c *Colorizer) ColorizeType(t component.Kind) string {
method ColorizeHeading (line 333) | func (c *Colorizer) ColorizeHeading(dep string) string {
function NewColorizer (line 271) | func NewColorizer(shouldColor bool) *Colorizer {
function outputText (line 338) | func outputText(l log.Logger, opts *Options, components ListedComponents...
function outputLong (line 345) | func outputLong(l log.Logger, opts *Options, components ListedComponents...
function shouldColor (line 352) | func shouldColor(l log.Logger) bool {
function renderLong (line 357) | func renderLong(opts *Options, components ListedComponents, c *Colorizer...
function buildLongHeadings (line 394) | func buildLongHeadings(opts *Options, c *Colorizer, longestPathLen int) ...
function renderTabular (line 416) | func renderTabular(opts *Options, components ListedComponents, c *Colori...
function outputTree (line 443) | func outputTree(l log.Logger, opts *Options, components ListedComponents...
function outputDot (line 450) | func outputDot(_ log.Logger, opts *Options, components ListedComponents)...
type TreeStyler (line 454) | type TreeStyler struct
method Style (line 472) | func (s *TreeStyler) Style(t *tree.Tree) *tree.Tree {
function NewTreeStyler (line 461) | func NewTreeStyler(shouldColor bool) *TreeStyler {
function generateTree (line 486) | func generateTree(components ListedComponents, s *TreeStyler) *tree.Tree {
function generateDAGTree (line 535) | func generateDAGTree(components ListedComponents, s *TreeStyler) *tree.T...
type pathParts (line 596) | type pathParts struct
function preProcessPath (line 603) | func preProcessPath(path string) pathParts {
function renderTree (line 616) | func renderTree(opts *Options, components ListedComponents, s *TreeStyle...
function getMaxCols (line 639) | func getMaxCols(components ListedComponents) (int, int) {
function getTerminalWidth (line 661) | func getTerminalWidth() int {
function getLongestPathLen (line 675) | func getLongestPathLen(components ListedComponents) int {
function renderDot (line 688) | func renderDot(opts *Options, components ListedComponents) error {
FILE: internal/cli/commands/list/list_test.go
function TestBasicDiscovery (line 19) | func TestBasicDiscovery(t *testing.T) {
function TestHiddenDiscovery (line 100) | func TestHiddenDiscovery(t *testing.T) {
function TestDAGSortingSimpleDependencies (line 172) | func TestDAGSortingSimpleDependencies(t *testing.T) {
function TestDAGSortingReversedDependencies (line 250) | func TestDAGSortingReversedDependencies(t *testing.T) {
function TestDAGSortingComplexDependencies (line 347) | func TestDAGSortingComplexDependencies(t *testing.T) {
function TestColorizer (line 469) | func TestColorizer(t *testing.T) {
function TestDotFormat (line 519) | func TestDotFormat(t *testing.T) {
function TestDotFormatWithoutDependencies (line 584) | func TestDotFormatWithoutDependencies(t *testing.T) {
function TestDotFormatWithComplexDependencies (line 646) | func TestDotFormatWithComplexDependencies(t *testing.T) {
function TestDotFormatWithExcludedComponents (line 724) | func TestDotFormatWithExcludedComponents(t *testing.T) {
function TestDotFormatWithExcludedDependency (line 803) | func TestDotFormatWithExcludedDependency(t *testing.T) {
function TestTextFormatExcludesExcludedComponents (line 874) | func TestTextFormatExcludesExcludedComponents(t *testing.T) {
function TestDotFormatWithMultipleExcludedComponents (line 939) | func TestDotFormatWithMultipleExcludedComponents(t *testing.T) {
FILE: internal/cli/commands/list/options.go
constant FormatText (line 10) | FormatText = "text"
constant FormatTree (line 13) | FormatTree = "tree"
constant FormatLong (line 16) | FormatLong = "long"
constant FormatDot (line 19) | FormatDot = "dot"
constant SortDAG (line 22) | SortDAG = "dag"
constant ModeNormal (line 25) | ModeNormal = "normal"
constant ModeDAG (line 28) | ModeDAG = "dag"
type Options (line 31) | type Options struct
method Validate (line 67) | func (o *Options) Validate() error {
method validateFormat (line 85) | func (o *Options) validateFormat() error {
method validateMode (line 100) | func (o *Options) validateMode() error {
function NewOptions (line 59) | func NewOptions(opts *options.TerragruntOptions) *Options {
FILE: internal/cli/commands/render/cli.go
constant CommandName (line 18) | CommandName = "render"
constant FormatFlagName (line 20) | FormatFlagName = "format"
constant JSONFlagName (line 21) | JSONFlagName = "json"
constant WriteFlagName (line 22) | WriteFlagName = "write"
constant WriteAliasFlagName (line 23) | WriteAliasFlagName = "w"
constant OutFlagName (line 24) | OutFlagName = "out"
constant WithMetadataFlagName (line 25) | WithMetadataFlagName = "with-metadata"
constant DisableDependentModulesFlagName (line 26) | DisableDependentModulesFlagName = "disable-dependent-modules"
function NewFlags (line 29) | func NewFlags(opts *Options, prefix flags.Prefix) clihelper.Flags {
function NewCommand (line 124) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
FILE: internal/cli/commands/render/options.go
constant FormatHCL (line 10) | FormatHCL = "hcl"
constant FormatJSON (line 13) | FormatJSON = "json"
type Options (line 16) | type Options struct
method Clone (line 42) | func (o *Options) Clone() *Options {
method Validate (line 52) | func (o *Options) Validate() error {
method validateFormat (line 60) | func (o *Options) validateFormat() error {
function NewOptions (line 33) | func NewOptions(opts *options.TerragruntOptions) *Options {
FILE: internal/cli/commands/render/render.go
function Run (line 24) | func Run(ctx context.Context, l log.Logger, opts *Options) error {
function runAll (line 41) | func runAll(ctx context.Context, l log.Logger, opts *Options) error {
function runRender (line 93) | func runRender(l log.Logger, opts *Options, cfg *config.TerragruntConfig...
function renderHCL (line 108) | func renderHCL(l log.Logger, opts *Options, cfg *config.TerragruntConfig...
function renderJSON (line 130) | func renderJSON(l log.Logger, opts *Options, cfg *config.TerragruntConfi...
function writeRendered (line 168) | func writeRendered(l log.Logger, opts *Options, data []byte) error {
function marshalCtyValueJSONWithoutType (line 193) | func marshalCtyValueJSONWithoutType(ctyVal cty.Value) ([]byte, error) {
FILE: internal/cli/commands/render/render_test.go
function TestRenderJSON_Basic (line 18) | func TestRenderJSON_Basic(t *testing.T) {
function TestRenderJSON_WithMetadata (line 42) | func TestRenderJSON_WithMetadata(t *testing.T) {
function TestRenderJSON_WriteToFile (line 66) | func TestRenderJSON_WriteToFile(t *testing.T) {
function TestRenderJSON_InvalidFormat (line 92) | func TestRenderJSON_InvalidFormat(t *testing.T) {
function TestRenderJSON_HCLFormat (line 103) | func TestRenderJSON_HCLFormat(t *testing.T) {
function setupTest (line 120) | func setupTest(t *testing.T) (*render.Options, string) {
function validateRenderedJSON (line 135) | func validateRenderedJSON(t *testing.T, result map[string]any, withMetad...
constant testTerragruntConfigFixture (line 200) | testTerragruntConfigFixture = `terraform {
FILE: internal/cli/commands/run/cli.go
constant CommandName (line 17) | CommandName = "run"
function NewCommand (line 20) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
function NewSubcommands (line 57) | func NewSubcommands(l log.Logger, opts *options.TerragruntOptions) clihe...
function Action (line 78) | func Action(l log.Logger, opts *options.TerragruntOptions) clihelper.Act...
FILE: internal/cli/commands/run/flags.go
constant NoAutoInitFlagName (line 22) | NoAutoInitFlagName = "no-auto-init"
constant NoAutoRetryFlagName (line 23) | NoAutoRetryFlagName = "no-auto-retry"
constant NoAutoApproveFlagName (line 24) | NoAutoApproveFlagName = "no-auto-approve"
constant NoAutoProviderCacheDirFlagName (line 25) | NoAutoProviderCacheDirFlagName = "no-auto-provider-cache-dir"
constant NoEngineFlagName (line 26) | NoEngineFlagName = "no-engine"
constant NoDependencyFetchOutputFromStateFlagName (line 27) | NoDependencyFetchOutputFromStateFlagName = "no-dependency-fetch-output-f...
constant TFForwardStdoutFlagName (line 28) | TFForwardStdoutFlagName = "tf-forward-stdout"
constant UnitsThatIncludeFlagName (line 29) | UnitsThatIncludeFlagName = "units-that-include"
constant DependencyFetchOutputFromStateFlagName (line 30) | DependencyFetchOutputFromStateFlagName = "dependency-fetch-output-from...
constant UsePartialParseConfigCacheFlagName (line 31) | UsePartialParseConfigCacheFlagName = "use-partial-parse-config-cache"
constant SummaryPerUnitFlagName (line 32) | SummaryPerUnitFlagName = "summary-per-unit"
constant VersionManagerFileNameFlagName (line 33) | VersionManagerFileNameFlagName = "version-manager-file-name"
constant DisableCommandValidationFlagName (line 35) | DisableCommandValidationFlagName = "disable-command-validation"
constant NoDestroyDependenciesCheckFlagName (line 36) | NoDestroyDependenciesCheckFlagName = "no-destroy-dependencies-check"
constant DestroyDependenciesCheckFlagName (line 37) | DestroyDependenciesCheckFlagName = "destroy-dependencies-check"
constant SourceFlagName (line 39) | SourceFlagName = "source"
constant SourceMapFlagName (line 40) | SourceMapFlagName = "source-map"
constant SourceUpdateFlagName (line 41) | SourceUpdateFlagName = "source-update"
constant NoStackGenerate (line 43) | NoStackGenerate = "no-stack-generate"
constant ProviderCacheFlagName (line 47) | ProviderCacheFlagName = "provider-cache"
constant ProviderCacheDirFlagName (line 48) | ProviderCacheDirFlagName = "provider-cache-dir"
constant ProviderCacheHostnameFlagName (line 49) | ProviderCacheHostnameFlagName = "provider-cache-hostname"
constant ProviderCachePortFlagName (line 50) | ProviderCachePortFlagName = "provider-cache-port"
constant ProviderCacheTokenFlagName (line 51) | ProviderCacheTokenFlagName = "provider-cache-token"
constant ProviderCacheRegistryNamesFlagName (line 52) | ProviderCacheRegistryNamesFlagName = "provider-cache-registry-names"
constant EngineEnableFlagName (line 56) | EngineEnableFlagName = "experimental-engine"
constant EngineCachePathFlagName (line 57) | EngineCachePathFlagName = "engine-cache-path"
constant EngineSkipCheckFlagName (line 58) | EngineSkipCheckFlagName = "engine-skip-check"
constant EngineLogLevelFlagName (line 59) | EngineLogLevelFlagName = "engine-log-level"
constant SummaryDisableFlagName (line 63) | SummaryDisableFlagName = "summary-disable"
constant ReportFileFlagName (line 64) | ReportFileFlagName = "report-file"
constant ReportFormatFlagName (line 65) | ReportFormatFlagName = "report-format"
constant ReportSchemaFlagName (line 66) | ReportSchemaFlagName = "report-schema-file"
constant OutDirFlagName (line 70) | OutDirFlagName = "out-dir"
constant JSONOutDirFlagName (line 71) | JSONOutDirFlagName = "json-out-dir"
constant GraphRootFlagName (line 74) | GraphRootFlagName = "graph-root"
constant ConfigFlagName (line 77) | ConfigFlagName = shared.ConfigFlagName
constant InputsDebugFlagName (line 80) | InputsDebugFlagName = shared.InputsDebugFlagName
constant IAMAssumeRoleFlagName (line 81) | IAMAssumeRoleFlagName = shared.IAMAssumeRoleFlagName
constant IAMAssumeRoleDurationFlagName (line 82) | IAMAssumeRoleDurationFlagName = shared.IAMAssumeRoleDurationFlag...
constant IAMAssumeRoleSessionNameFlagName (line 83) | IAMAssumeRoleSessionNameFlagName = shared.IAMAssumeRoleSessionNameF...
constant IAMAssumeRoleWebIdentityTokenFlagName (line 84) | IAMAssumeRoleWebIdentityTokenFlagName = shared.IAMAssumeRoleWebIdentityT...
function NewFlags (line 88) | func NewFlags(l log.Logger, opts *options.TerragruntOptions, prefix flag...
FILE: internal/cli/commands/run/help.go
constant TFCommandHelpTemplate (line 20) | TFCommandHelpTemplate = `Usage: {{ if .Command.UsageText }}{{ wrap .Comm...
function ShowTFHelp (line 34) | func ShowTFHelp(l log.Logger, opts *options.TerragruntOptions) clihelper...
function runTFHelp (line 56) | func runTFHelp(ctx context.Context, cliCtx *clihelper.Context, l log.Log...
FILE: internal/cli/commands/run/run.go
function Run (line 27) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function isTerraformPath (line 146) | func isTerraformPath(opts *options.TerragruntOptions) bool {
function runVersionCommand (line 152) | func runVersionCommand(ctx context.Context, l log.Logger, opts *options....
function getTFPathFromConfig (line 164) | func getTFPathFromConfig(ctx context.Context, l log.Logger, opts *option...
function checkVersionConstraints (line 185) | func checkVersionConstraints(ctx context.Context, l log.Logger, opts *op...
function getTerragruntConfig (line 238) | func getTerragruntConfig(ctx context.Context, l log.Logger, opts *option...
function confirmActionWithDependentUnits (line 255) | func confirmActionWithDependentUnits(
function findDependentUnits (line 290) | func findDependentUnits(
FILE: internal/cli/commands/scaffold/cli.go
constant CommandName (line 19) | CommandName = "scaffold"
constant OutputFolderFlagName (line 21) | OutputFolderFlagName = "output-folder"
constant VarFlagName (line 22) | VarFlagName = "var"
constant VarFileFlagName (line 23) | VarFileFlagName = "var-file"
constant NoDependencyPrompt (line 24) | NoDependencyPrompt = "no-dependency-prompt"
function NewFlags (line 27) | func NewFlags(opts *options.TerragruntOptions, prefix flags.Prefix) clih...
function NewCommand (line 66) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
function GetDefaultRootFileName (line 96) | func GetDefaultRootFileName(ctx context.Context, opts *options.Terragrun...
FILE: internal/cli/commands/scaffold/scaffold.go
constant sourceURLTypeHTTPS (line 32) | sourceURLTypeHTTPS = "git-https"
constant sourceURLTypeGit (line 33) | sourceURLTypeGit = "git-ssh"
constant sourceGitSSHUser (line 34) | sourceGitSSHUser = "git"
constant sourceURLTypeVar (line 36) | sourceURLTypeVar = "SourceUrlType"
constant sourceGitSSHUserVar (line 37) | sourceGitSSHUserVar = "SourceGitSshUser"
constant refVar (line 38) | refVar = "Ref"
constant refParam (line 40) | refParam = "ref"
constant moduleURLPattern (line 42) | moduleURLPattern = `(?:git|hg|s3|gcs)::([^:]+)://([^/]+)(/.*)`
constant moduleURLParts (line 43) | moduleURLParts = 4
constant DefaultBoilerplateConfig (line 46) | DefaultBoilerplateConfig = `
constant DefaultTerragruntTemplate (line 56) | DefaultTerragruntTemplate = `
constant enableRootInclude (line 106) | enableRootInclude = "EnableRootInclude"
constant rootFileName (line 107) | rootFileName = "RootFileName"
function NewBoilerplateOptions (line 111) | func NewBoilerplateOptions(
function Run (line 131) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function applyCatalogConfigToScaffold (line 252) | func applyCatalogConfigToScaffold(ctx context.Context, l log.Logger, opt...
function generateDefaultTemplate (line 283) | func generateDefaultTemplate(boilerplateDir string) (string, error) {
function downloadTemplate (line 311) | func downloadTemplate(
function prepareBoilerplateFiles (line 368) | func prepareBoilerplateFiles(
function parseVariables (line 425) | func parseVariables(
function parseModuleURL (line 453) | func parseModuleURL(
function rewriteModuleURL (line 485) | func rewriteModuleURL(
function rewriteTemplateURL (line 533) | func rewriteTemplateURL(
function addRefToModuleURL (line 569) | func addRefToModuleURL(
function parseURL (line 608) | func parseURL(l log.Logger, moduleURL string) (*parsedURL, error) {
type parsedURL (line 622) | type parsedURL struct
type failedToParseURLError (line 628) | type failedToParseURLError struct
method Error (line 631) | func (err failedToParseURLError) Error() string {
type NoModuleURLPassed (line 635) | type NoModuleURLPassed struct
method Error (line 638) | func (err NoModuleURLPassed) Error() string {
FILE: internal/cli/commands/scaffold/scaffold_test.go
function newTestBoilerplateOptions (line 25) | func newTestBoilerplateOptions(templateFolder, outputFolder string, vars...
function TestDefaultTemplateVariables (line 40) | func TestDefaultTemplateVariables(t *testing.T) {
function TestCatalogConfigApplication (line 113) | func TestCatalogConfigApplication(t *testing.T) {
function boolPtr (line 368) | func boolPtr(b bool) *bool {
function TestCatalogConfigParsing (line 373) | func TestCatalogConfigParsing(t *testing.T) {
function TestCatalogConfigOptional (line 414) | func TestCatalogConfigOptional(t *testing.T) {
function TestBoilerplateShellTemplateFunctionDisabled (line 451) | func TestBoilerplateShellTemplateFunctionDisabled(t *testing.T) {
function TestBoilerplateShellTemplateFunctionEnabled (line 509) | func TestBoilerplateShellTemplateFunctionEnabled(t *testing.T) {
function TestBoilerplateHooksDisabled (line 565) | func TestBoilerplateHooksDisabled(t *testing.T) {
function TestBoilerplateHooksEnabled (line 633) | func TestBoilerplateHooksEnabled(t *testing.T) {
function TestBoilerplateBothFlagsDisabled (line 701) | func TestBoilerplateBothFlagsDisabled(t *testing.T) {
FILE: internal/cli/commands/shortcuts.go
function NewShortcutsCommands (line 31) | func NewShortcutsCommands(l log.Logger, opts *options.TerragruntOptions)...
FILE: internal/cli/commands/stack/cli.go
constant CommandName (line 16) | CommandName = "stack"
constant OutputFormatFlagName (line 17) | OutputFormatFlagName = "format"
constant JSONFormatFlagName (line 18) | JSONFormatFlagName = "json"
constant RawFormatFlagName (line 19) | RawFormatFlagName = "raw"
constant NoStackValidate (line 20) | NoStackValidate = "no-stack-validate"
constant generateCommandName (line 22) | generateCommandName = "generate"
constant runCommandName (line 23) | runCommandName = "run"
constant outputCommandName (line 24) | outputCommandName = "output"
constant cleanCommandName (line 25) | cleanCommandName = "clean"
constant rawOutputFormat (line 27) | rawOutputFormat = "raw"
constant jsonOutputFormat (line 28) | jsonOutputFormat = "json"
function NewCommand (line 32) | func NewCommand(l log.Logger, opts *options.TerragruntOptions) *clihelpe...
function defaultFlags (line 78) | func defaultFlags(l log.Logger, opts *options.TerragruntOptions, prefix ...
function outputFlags (line 94) | func outputFlags(l log.Logger, opts *options.TerragruntOptions, prefix f...
FILE: internal/cli/commands/stack/output.go
function PrintRawOutputs (line 24) | func PrintRawOutputs(_ *options.TerragruntOptions, writer io.Writer, out...
function extractSingleValue (line 56) | func extractSingleValue(valueMap map[string]cty.Value) (cty.Value, error) {
function traverseNestedObject (line 71) | func traverseNestedObject(topKey string, topValue cty.Value) (cty.Value,...
function writePrimitiveValue (line 109) | func writePrimitiveValue(writer io.Writer, value cty.Value, path string)...
function createUnsupportedValueError (line 141) | func createUnsupportedValueError(path string, value cty.Value) error {
function PrintOutputs (line 151) | func PrintOutputs(writer io.Writer, outputs cty.Value) error {
function PrintJSONOutput (line 173) | func PrintJSONOutput(writer io.Writer, outputs cty.Value) error {
FILE: internal/cli/commands/stack/output_test.go
function TestPrintRawOutputsBasicTypes (line 14) | func TestPrintRawOutputsBasicTypes(t *testing.T) {
function TestPrintRawOutputsComplexObject (line 60) | func TestPrintRawOutputsComplexObject(t *testing.T) {
function TestPrintRawOutputsMultipleKeys (line 77) | func TestPrintRawOutputsMultipleKeys(t *testing.T) {
function TestPrintRawOutputsList (line 92) | func TestPrintRawOutputsList(t *testing.T) {
function TestPrintRawOutputsNil (line 108) | func TestPrintRawOutputsNil(t *testing.T) {
function TestPrintOutputs (line 118) | func TestPrintOutputs(t *testing.T) {
function TestPrintJSONOutput (line 134) | func TestPrintJSONOutput(t *testing.T) {
function TestPrintRawOutputsEdgeCases (line 149) | func TestPrintRawOutputsEdgeCases(t *testing.T) {
function TestPrintRawOutputsDeepNesting (line 240) | func TestPrintRawOutputsDeepNesting(t *testing.T) {
function TestPrintRawOutputsPartialNesting (line 263) | func TestPrintRawOutputsPartialNesting(t *testing.T) {
function TestPrintRawOutputsExactlyOneLeafNode (line 282) | func TestPrintRawOutputsExactlyOneLeafNode(t *testing.T) {
function TestPrintRawOutputsSpecialCharacters (line 301) | func TestPrintRawOutputsSpecialCharacters(t *testing.T) {
function TestPrintRawOutputsNullValue (line 317) | func TestPrintRawOutputsNullValue(t *testing.T) {
function TestPrintOutputsEdgeCases (line 331) | func TestPrintOutputsEdgeCases(t *testing.T) {
function TestPrintJSONOutputEdgeCases (line 392) | func TestPrintJSONOutputEdgeCases(t *testing.T) {
function TestPrintRawOutputsNestedValues (line 454) | func TestPrintRawOutputsNestedValues(t *testing.T) {
function TestPrintRawOutputsSpecialCases (line 501) | func TestPrintRawOutputsSpecialCases(t *testing.T) {
FILE: internal/cli/commands/stack/stack.go
function RunGenerate (line 24) | func RunGenerate(ctx context.Context, l log.Logger, opts *options.Terrag...
function Run (line 80) | func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOpti...
function RunOutput (line 97) | func RunOutput(ctx context.Context, l log.Logger, opts *options.Terragru...
function FilterOutputs (line 142) | func FilterOutputs(outputs cty.Value, index string) cty.Value {
function RunClean (line 179) | func RunClean(ctx context.Context, l log.Logger, opts *options.Terragrun...
FILE: internal/cli/commands/version/cli.go
constant CommandName (line 11) | CommandName = "version"
function NewCommand (line 14) | func NewCommand() *clihelper.Command {
function Action (line 26) | func Action(ctx context.Context, cliCtx *clihelper.Context) error {
FILE: internal/cli/flags/deprecated_flag.go
type DeprecatedFlags (line 15) | type DeprecatedFlags
type DeprecatedFlag (line 18) | type DeprecatedFlag struct
method GetHidden (line 28) | func (flag *DeprecatedFlag) GetHidden() bool {
method AllowedSubcommandScope (line 33) | func (flag *DeprecatedFlag) AllowedSubcommandScope() bool {
method GetEnvVars (line 38) | func (flag *DeprecatedFlag) GetEnvVars() []string {
method Names (line 43) | func (flag *DeprecatedFlag) Names() []string {
method Evaluate (line 48) | func (flag *DeprecatedFlag) Evaluate(ctx context.Context) error {
method SetStrictControls (line 53) | func (flag *DeprecatedFlag) SetStrictControls(mainFlag *Flag, regContr...
type NewValueFunc (line 79) | type NewValueFunc
function NewValue (line 82) | func NewValue(val string) NewValueFunc {
type RegisterStrictControlsFunc (line 89) | type RegisterStrictControlsFunc
function StrictControlsByCommand (line 93) | func StrictControlsByCommand(strictControls strict.Controls, commandName...
function StrictControlsByGlobalFlags (line 104) | func StrictControlsByGlobalFlags(strictControls strict.Controls, control...
function registerStrictControls (line 110) | func registerStrictControls(strictControls strict.Controls,
FILE: internal/cli/flags/error_handler.go
function ErrorHandler (line 14) | func ErrorHandler(commands clihelper.Commands) clihelper.FlagErrHandlerF...
constant maxContextDepth (line 46) | maxContextDepth = 10
function isRunContext (line 49) | func isRunContext(ctx *clihelper.Context) bool {
function findFlagInCommands (line 65) | func findFlagInCommands(commands clihelper.Commands, undefFlag string) (...
FILE: internal/cli/flags/error_handler_test.go
function TestErrorHandler (line 12) | func TestErrorHandler(t *testing.T) {
FILE: internal/cli/flags/errors.go
type GlobalFlagHintError (line 7) | type GlobalFlagHintError struct
method Error (line 21) | func (err GlobalFlagHintError) Error() string {
function NewGlobalFlagHintError (line 13) | func NewGlobalFlagHintError(undefFlag, cmdHint, flagHint string) *Global...
type CommandFlagHintError (line 27) | type CommandFlagHintError struct
method Error (line 43) | func (err CommandFlagHintError) Error() string {
function NewCommandFlagHintError (line 34) | func NewCommandFlagHintError(wrongCmd, undefFlag, cmdHint, flagHint stri...
type PassthroughFlagHintError (line 49) | type PassthroughFlagHintError struct
method Error (line 57) | func (err PassthroughFlagHintError) Error() string {
function NewPassthroughFlagHintError (line 53) | func NewPassthroughFlagHintError(undefFlag string) *PassthroughFlagHintE...
FILE: internal/cli/flags/flag.go
type EvaluateWrapperFunc (line 18) | type EvaluateWrapperFunc
type Flag (line 21) | type Flag struct
method TakesValue (line 45) | func (newFlag *Flag) TakesValue() bool {
method DeprecatedNames (line 60) | func (newFlag *Flag) DeprecatedNames() []string {
method Value (line 75) | func (newFlag *Flag) Value() clihelper.FlagValue {
method Apply (line 102) | func (newFlag *Flag) Apply(set *flag.FlagSet) error {
method RunAction (line 125) | func (newFlag *Flag) RunAction(ctx context.Context, cliCtx *clihelper....
method Parse (line 154) | func (newFlag *Flag) Parse(args clihelper.Args) error {
function NewFlag (line 28) | func NewFlag(new clihelper.Flag, opts ...Option) *Flag {
FILE: internal/cli/flags/flag_opts.go
type Option (line 8) | type Option
function WithDeprecatedFlag (line 18) | func WithDeprecatedFlag(deprecatedFlag clihelper.Flag, newValueFn NewVal...
function WithDeprecatedPrefix (line 44) | func WithDeprecatedPrefix(prefix Prefix, regControlsFn RegisterStrictCon...
function WithDeprecatedNames (line 65) | func WithDeprecatedNames(flagNames []string, regControlsFn RegisterStric...
function WithDeprecatedName (line 80) | func WithDeprecatedName(flagName string, regControlsFn RegisterStrictCon...
function WithDeprecatedNamesEnvVars (line 88) | func WithDeprecatedNamesEnvVars(flagNames, envVars []string, regControls...
function WithDeprecatedEnvVars (line 103) | func WithDeprecatedEnvVars(envVars []string, regControlsFn RegisterStric...
function WithDeprecatedFlagNames (line 117) | func WithDeprecatedFlagNames(flagNames []string, regControlsFn RegisterS...
function WithDeprecatedFlagName (line 131) | func WithDeprecatedFlagName(flagName string, regControlsFn RegisterStric...
function WithEvaluateWrapper (line 138) | func WithEvaluateWrapper(fn EvaluateWrapperFunc) Option {
FILE: internal/cli/flags/flag_test.go
function mockDestValue (line 21) | func mockDestValue[T any](val T) *T {
function newLogger (line 25) | func newLogger() (log.Logger, *bytes.Buffer) {
function TestFlag_TakesValue (line 33) | func TestFlag_TakesValue(t *testing.T) {
function TestFlag_Evaluate (line 76) | func TestFlag_Evaluate(t *testing.T) {
FILE: internal/cli/flags/global/flags.go
constant LogLevelFlagName (line 23) | LogLevelFlagName = "log-level"
constant LogDisableFlagName (line 24) | LogDisableFlagName = "log-disable"
constant ShowLogAbsPathsFlagName (line 25) | ShowLogAbsPathsFlagName = "log-show-abs-paths"
constant LogFormatFlagName (line 26) | LogFormatFlagName = "log-format"
constant LogCustomFormatFlagName (line 27) | LogCustomFormatFlagName = "log-custom-format"
constant NoColorFlagName (line 28) | NoColorFlagName = "no-color"
constant NonInteractiveFlagName (line 30) | NonInteractiveFlagName = "non-interactive"
constant WorkingDirFlagName (line 31) | WorkingDirFlagName = "working-dir"
constant StrictModeFlagName (line 35) | StrictModeFlagName = "strict-mode"
constant StrictControlFlagName (line 36) | StrictControlFlagName = "strict-control"
constant ExperimentModeFlagName (line 40) | ExperimentModeFlagName = "experiment-mode"
constant ExperimentFlagName (line 41) | ExperimentFlagName = "experiment"
constant NoTipsFlagName (line 45) | NoTipsFlagName = "no-tips"
constant NoTipFlagName (line 46) | NoTipFlagName = "no-tip"
constant HelpFlagName (line 50) | HelpFlagName = "help"
constant VersionFlagName (line 51) | VersionFlagName = "version"
constant TelemetryTraceExporterFlagName (line 55) | TelemetryTraceExporterFlagName = "telemetry-trace-expor...
constant TelemetryTraceExporterInsecureEndpointFlagName (line 56) | TelemetryTraceExporterInsecureEndpointFlagName = "telemetry-trace-expor...
constant TelemetryTraceExporterHTTPEndpointFlagName (line 57) | TelemetryTraceExporterHTTPEndpointFlagName = "telemetry-trace-expor...
constant TraceparentFlagName (line 58) | TraceparentFlagName = "traceparent"
constant TelemetryMetricExporterFlagName (line 59) | TelemetryMetricExporterFlagName = "telemetry-metric-expo...
constant TelemetryMetricExporterInsecureEndpointFlagName (line 60) | TelemetryMetricExporterInsecureEndpointFlagName = "telemetry-metric-expo...
constant DeprecatedLogLevelFlagName (line 64) | DeprecatedLogLevelFlagName = "log-level"
constant DeprecatedLogDisableFlagName (line 65) | DeprecatedLogDisableFlagName = "log-disable"
constant DeprecatedShowLogAbsPathsFlagName (line 66) | DeprecatedShowLogAbsPathsFlagName = "log-show-abs-paths"
constant DeprecatedLogFormatFlagName (line 67) | DeprecatedLogFormatFlagName = "log-format"
constant DeprecatedLogCustomFormatFlagName (line 68) | DeprecatedLogCustomFormatFlagName = "log-custom-format"
constant DeprecatedNoColorFlagName (line 69) | DeprecatedNoColorFlagName = "no-color"
constant DeprecatedNonInteractiveFlagName (line 70) | DeprecatedNonInteractiveFlagName = "non-interactive"
constant DeprecatedTFInputFlagName (line 71) | DeprecatedTFInputFlagName = "tf-input"
constant DeprecatedWorkingDirFlagName (line 72) | DeprecatedWorkingDirFlagName = "working-dir"
constant DeprecatedStrictModeFlagName (line 73) | DeprecatedStrictModeFlagName = "strict-mode"
constant DeprecatedStrictControlFlagName (line 74) | DeprecatedStrictControlFlagName = "strict-control"
constant DeprecatedExperimentModeFlagName (line 75) | DeprecatedExperimentModeFlagName = "experiment-mode"
constant DeprecatedExperimentFlagName (line 76) | DeprecatedExperimentFlagName = "experiment"
constant DeprecatedDisableLogFormattingFlagName (line 80) | DeprecatedDisableLogFormattingFlagName = "disable-log-formatting"
constant DeprecatedJSONLogFlagName (line 81) | DeprecatedJSONLogFlagName = "json-log"
constant DeprecatedTfLogJSONFlagName (line 82) | DeprecatedTfLogJSONFlagName = "tf-logs-to-json"
function NewFlags (line 86) | func NewFlags(l log.Logger, opts *options.TerragruntOptions, prefix flag...
function NewTelemetryFlags (line 272) | func NewTelemetryFlags(opts *options.TerragruntOptions, prefix flags.Pre...
function NewLogLevelFlag (line 319) | func NewLogLevelFlag(l log.Logger, opts *options.TerragruntOptions, pref...
function NewHelpVersionFlags (line 349) | func NewHelpVersionFlags(l log.Logger, opts *options.TerragruntOptions) ...
FILE: internal/cli/flags/prefix.go
constant TgPrefix (line 9) | TgPrefix = "TG"
constant TerragruntPrefix (line 12) | TerragruntPrefix = "TERRAGRUNT"
type Prefix (line 35) | type Prefix
method Prepend (line 38) | func (prefix Prefix) Prepend(val string) Prefix {
method Append (line 43) | func (prefix Prefix) Append(val string) Prefix {
method EnvVar (line 49) | func (prefix Prefix) EnvVar(name string) string {
method EnvVars (line 60) | func (prefix Prefix) EnvVars(names ...string) []string {
method FlagName (line 72) | func (prefix Prefix) FlagName(name string) string {
method FlagNames (line 83) | func (prefix Prefix) FlagNames(names ...string) []string {
FILE: internal/cli/flags/shared/all.go
constant AllFlagName (line 13) | AllFlagName = "all"
constant AllFlagAlias (line 14) | AllFlagAlias = "a"
function NewAllFlag (line 18) | func NewAllFlag(opts *options.TerragruntOptions, prefix flags.Prefix) *f...
FILE: internal/cli/flags/shared/auth.go
constant AuthProviderCmdFlagName (line 10) | AuthProviderCmdFlagName = "auth-provider-cmd"
function NewAuthProviderCmdFlag (line 14) | func NewAuthProviderCmdFlag(opts *options.TerragruntOptions, prefix flag...
FILE: internal/cli/flags/shared/backend.go
constant BackendBootstrapFlagName (line 10) | BackendBootstrapFlagName = "backend-bootstrap"
constant BackendRequireBootstrapFlagName (line 11) | BackendRequireBootstrapFlagName = "backend-require-bootstrap"
constant DisableBucketUpdateFlagName (line 12) | DisableBucketUpdateFlagName = "disable-bucket-update"
function NewBackendFlags (line 16) | func NewBackendFlags(opts *options.TerragruntOptions, prefix flags.Prefi...
FILE: internal/cli/flags/shared/config.go
constant ConfigFlagName (line 10) | ConfigFlagName = "config"
function NewConfigFlag (line 14) | func NewConfigFlag(opts *options.TerragruntOptions, prefix flags.Prefix,...
FILE: internal/cli/flags/shared/download.go
constant DownloadDirFlagName (line 10) | DownloadDirFlagName = "download-dir"
function NewDownloadDirFlag (line 14) | func NewDownloadDirFlag(opts *options.TerragruntOptions, prefix flags.Pr...
FILE: internal/cli/flags/shared/errors.go
type AllGraphFlagsError (line 4) | type AllGraphFlagsError
method Error (line 6) | func (err *AllGraphFlagsError) Error() string {
FILE: internal/cli/flags/shared/failfast.go
constant FailFastFlagName (line 10) | FailFastFlagName = "fail-fast"
function NewFailFastFlag (line 14) | func NewFailFastFlag(opts *options.TerragruntOptions) *flags.Flag {
FILE: internal/cli/flags/shared/feature.go
constant FeatureFlagName (line 12) | FeatureFlagName = "feature"
function NewFeatureFlags (line 16) | func NewFeatureFlags(opts *options.TerragruntOptions, prefix flags.Prefi...
FILE: internal/cli/flags/shared/filter.go
constant FilterFlagName (line 15) | FilterFlagName = "filter"
constant FilterAffectedFlagName (line 16) | FilterAffectedFlagName = "filter-affected"
constant FilterAllowDestroyFlagName (line 17) | FilterAllowDestroyFlagName = "filter-allow-destroy"
constant FilterFileFlagName (line 18) | FilterFileFlagName = "filters-file"
constant NoFilterFileFlagName (line 19) | NoFilterFileFlagName = "no-filters-file"
function NewFilterFlags (line 23) | func NewFilterFlags(l log.Logger, opts *options.TerragruntOptions) clihe...
FILE: internal/cli/flags/shared/graph.go
constant GraphFlagName (line 13) | GraphFlagName = "graph"
function NewGraphFlag (line 17) | func NewGraphFlag(opts *options.TerragruntOptions, prefix flags.Prefix) ...
FILE: internal/cli/flags/shared/iamassumerole.go
constant IAMAssumeRoleFlagName (line 10) | IAMAssumeRoleFlagName = "iam-assume-role"
constant IAMAssumeRoleDurationFlagName (line 11) | IAMAssumeRoleDurationFlagName = "iam-assume-role-duration"
constant IAMAssumeRoleSessionNameFlagName (line 12) | IAMAssumeRoleSessionNameFlagName = "iam-assume-role-session-name"
constant IAMAssumeRoleWebIdentityTokenFlagName (line 13) | IAMAssumeRoleWebIdentityTokenFlagName = "iam-assume-role-web-identity-to...
function NewIAMAssumeRoleFlags (line 17) | func NewIAMAssumeRoleFlags(opts *options.TerragruntOptions, prefix flags...
FILE: internal/cli/flags/shared/inputsdebug.go
constant InputsDebugFlagName (line 10) | InputsDebugFlagName = "inputs-debug"
function NewInputsDebugFlag (line 14) | func NewInputsDebugFlag(opts *options.TerragruntOptions, prefix flags.Pr...
FILE: internal/cli/flags/shared/parallelism.go
constant ParallelismFlagName (line 10) | ParallelismFlagName = "parallelism"
function NewParallelismFlag (line 14) | func NewParallelismFlag(opts *options.TerragruntOptions) *flags.Flag {
FILE: internal/cli/flags/shared/queue.go
constant QueueIgnoreErrorsFlagName (line 14) | QueueIgnoreErrorsFlagName = "queue-ignore-errors"
constant QueueIgnoreDAGOrderFlagName (line 15) | QueueIgnoreDAGOrderFlagName = "queue-ignore-dag-order"
constant QueueExcludeExternalFlagName (line 16) | QueueExcludeExternalFlagName = "queue-exclude-external"
constant QueueExcludeDirFlagName (line 17) | QueueExcludeDirFlagName = "queue-exclude-dir"
constant QueueExcludesFileFlagName (line 18) | QueueExcludesFileFlagName = "queue-excludes-file"
constant QueueIncludeDirFlagName (line 19) | QueueIncludeDirFlagName = "queue-include-dir"
constant QueueIncludeExternalFlagName (line 20) | QueueIncludeExternalFlagName = "queue-include-external"
constant QueueStrictIncludeFlagName (line 21) | QueueStrictIncludeFlagName = "queue-strict-include"
constant QueueIncludeUnitsReadingFlagName (line 22) | QueueIncludeUnitsReadingFlagName = "queue-include-units-reading"
function NewQueueFlags (line 26) | func NewQueueFlags(opts *options.TerragruntOptions, prefix flags.Prefix)...
FILE: internal/cli/flags/shared/scaffold.go
constant RootFileNameFlagName (line 12) | RootFileNameFlagName = "root-file-name"
constant NoIncludeRootFlagName (line 13) | NoIncludeRootFlagName = "no-include-root"
constant NoShellFlagName (line 14) | NoShellFlagName = "no-shell"
constant NoHooksFlagName (line 15) | NoHooksFlagName = "no-hooks"
function NewScaffoldingFlags (line 19) | func NewScaffoldingFlags(opts *options.TerragruntOptions, prefix flags.P...
FILE: internal/cli/flags/shared/tfpath.go
constant TFPathFlagName (line 10) | TFPathFlagName = "tf-path"
function NewTFPathFlag (line 14) | func NewTFPathFlag(opts *options.TerragruntOptions) *flags.Flag {
FILE: internal/cli/help.go
constant AppHelpTemplate (line 4) | AppHelpTemplate = `Usage: {{ if .App.UsageText }}{{ wrap .App.UsageText ...
constant CommandHelpTemplate (line 22) | CommandHelpTemplate = `Usage: {{ if .Command.UsageText }}{{ wrap .Comman...
constant AppVersionTemplate (line 42) | AppVersionTemplate = `{{ .App.Name }} version {{ .App.Version }}
FILE: internal/cli/help_test.go
function TestCommandHelpTemplate (line 15) | func TestCommandHelpTemplate(t *testing.T) {
FILE: internal/clihelper/app.go
type App (line 23) | type App struct
method AddFlags (line 101) | func (app *App) AddFlags(flags ...Flag) {
method AddCommands (line 106) | func (app *App) AddCommands(cmds ...*Command) {
method Run (line 111) | func (app *App) Run(arguments []string) error {
method RunContext (line 118) | func (app *App) RunContext(ctx context.Context, arguments []string) (e...
method VisibleFlags (line 160) | func (app *App) VisibleFlags() Flags {
method VisibleCommands (line 165) | func (app *App) VisibleCommands() Commands {
method NewRootCommand (line 173) | func (app *App) NewRootCommand() *Command {
method setupAutocomplete (line 192) | func (app *App) setupAutocomplete(arguments []string) error {
method handleExitCoder (line 243) | func (app *App) handleExitCoder(ctx *Context, err error) error {
function NewApp (line 87) | func NewApp() *App {
FILE: internal/clihelper/args.go
constant tailMinArgsLen (line 10) | tailMinArgsLen = 2
constant BuiltinCmdSep (line 11) | BuiltinCmdSep = "--"
constant SingleDashFlag (line 15) | SingleDashFlag NormalizeActsType = iota
constant DoubleDashFlag (line 16) | DoubleDashFlag
type NormalizeActsType (line 24) | type NormalizeActsType
type Args (line 27) | type Args
method String (line 30) | func (args Args) String() string {
method Split (line 35) | func (args Args) Split(sep string) (Args, Args) {
method WithoutBuiltinCmdSep (line 43) | func (args Args) WithoutBuiltinCmdSep() Args {
method Get (line 50) | func (args Args) Get(n int) string {
method First (line 59) | func (args Args) First() string {
method Second (line 64) | func (args Args) Second() string {
method Last (line 69) | func (args Args) Last() string {
method Tail (line 75) | func (args Args) Tail() Args {
method Remove (line 84) | func (args Args) Remove(name string) Args {
method Len (line 91) | func (args Args) Len() int {
method Present (line 96) | func (args Args) Present() bool {
method Slice (line 101) | func (args Args) Slice() []string {
method Normalize (line 110) | func (args Args) Normalize(acts ...NormalizeActsType) Args {
method CommandNameN (line 134) | func (args Args) CommandNameN(n int) string {
method CommandName (line 152) | func (args Args) CommandName() string {
method SubCommandName (line 158) | func (args Args) SubCommandName() string {
method Contains (line 163) | func (args Args) Contains(target string) bool {
FILE: internal/clihelper/args_test.go
function TestArgsSlice (line 13) | func TestArgsSlice(t *testing.T) {
function TestArgsTail (line 21) | func TestArgsTail(t *testing.T) {
function TestArgsFirst (line 29) | func TestArgsFirst(t *testing.T) {
function TestArgsGet (line 37) | func TestArgsGet(t *testing.T) {
function TestArgsLen (line 45) | func TestArgsLen(t *testing.T) {
function TestArgsPresent (line 53) | func TestArgsPresent(t *testing.T) {
function TestArgsCommandName (line 66) | func TestArgsCommandName(t *testing.T) {
function TestArgsNormalize (line 79) | func TestArgsNormalize(t *testing.T) {
function TestArgsRemove (line 91) | func TestArgsRemove(t *testing.T) {
FILE: internal/clihelper/autocomplete.go
constant defaultAutocompleteInstallFlag (line 20) | defaultAutocompleteInstallFlag = "install-autocomplete"
constant defaultAutocompleteUninstallFlag (line 21) | defaultAutocompleteUninstallFlag = "uninstall-autocomplete"
constant envCompleteLine (line 23) | envCompleteLine = "COMP_LINE"
constant maxDashesInFlag (line 25) | maxDashesInFlag = 2
type AutocompleteInstaller (line 35) | type AutocompleteInstaller interface
type autocompleteInstaller (line 42) | type autocompleteInstaller struct
method Install (line 44) | func (i *autocompleteInstaller) Install(cmd string) error {
method Uninstall (line 52) | func (i *autocompleteInstaller) Uninstall(cmd string) error {
function ShowCompletions (line 61) | func ShowCompletions(ctx context.Context, cliCtx *Context) error {
function defaultComplete (line 69) | func defaultComplete(cliCtx *Context) error {
function printCommandSuggestions (line 87) | func printCommandSuggestions(arg string, commands []*Command, writer io....
function printFlagSuggestions (line 110) | func printFlagSuggestions(arg string, flags []Flag, writer io.Writer) er...
function cliArgContains (line 142) | func cliArgContains(flagName string) bool {
FILE: internal/clihelper/bool_flag.go
type BoolFlag (line 14) | type BoolFlag struct
method Apply (line 53) | func (flag *BoolFlag) Apply(set *libflag.FlagSet) error {
method GetHidden (line 75) | func (flag *BoolFlag) GetHidden() bool {
method GetUsage (line 80) | func (flag *BoolFlag) GetUsage() string {
method GetEnvVars (line 85) | func (flag *BoolFlag) GetEnvVars() []string {
method TakesValue (line 91) | func (flag *BoolFlag) TakesValue() bool {
method GetDefaultText (line 96) | func (flag *BoolFlag) GetDefaultText() string {
method String (line 105) | func (flag *BoolFlag) String() string {
method Names (line 110) | func (flag *BoolFlag) Names() []string {
method RunAction (line 119) | func (flag *BoolFlag) RunAction(ctx context.Context, cliCtx *Context) ...
type boolVar (line 135) | type boolVar struct
method Clone (line 147) | func (val *boolVar) Clone(dest *bool) FlagVariable[bool] {
method Set (line 154) | func (val *boolVar) Set(str string) error {
method String (line 167) | func (val *boolVar) String() string {
function newBoolVar (line 140) | func newBoolVar(dest *bool, negative bool) *boolVar {
FILE: internal/clihelper/bool_flag_test.go
function TestBoolFlagApply (line 17) | func TestBoolFlagApply(t *testing.T) {
function testBoolFlagApply (line 115) | func testBoolFlagApply(t *testing.T, flag *clihelper.BoolFlag, args []st...
FILE: internal/clihelper/category.go
type Category (line 6) | type Category struct
method String (line 14) | func (category *Category) String() string {
type Categories (line 19) | type Categories
method Len (line 22) | func (categories Categories) Len() int {
method Less (line 27) | func (categories Categories) Less(i, j int) bool {
method Swap (line 36) | func (categories Categories) Swap(i, j int) {
method Sort (line 41) | func (categories Categories) Sort() Categories {
FILE: internal/clihelper/command.go
type Command (line 10) | type Command struct
method Names (line 84) | func (cmd *Command) Names() []string {
method HasName (line 89) | func (cmd *Command) HasName(name string) bool {
method Subcommand (line 100) | func (cmd *Command) Subcommand(name string) *Command {
method VisibleFlags (line 111) | func (cmd *Command) VisibleFlags() Flags {
method VisibleSubcommands (line 117) | func (cmd *Command) VisibleSubcommands() Commands {
method Run (line 127) | func (cmd *Command) Run(ctx context.Context, cliCtx *Context, args Arg...
method parseFlags (line 179) | func (cmd *Command) parseFlags(ctx *Context, args Args) ([]string, err...
method flagSetParse (line 244) | func (cmd *Command) flagSetParse(ctx *Context, flagSet *libflag.FlagSe...
method WrapAction (line 302) | func (cmd *Command) WrapAction(fn func(ctx context.Context, cliCtx *Co...
method DisableErrorOnMultipleSetFlag (line 315) | func (cmd *Command) DisableErrorOnMultipleSetFlag() *Command {
FILE: internal/clihelper/command_test.go
function TestCommandRun (line 16) | func TestCommandRun(t *testing.T) {
function TestCommandHasName (line 195) | func TestCommandHasName(t *testing.T) {
function TestCommandNames (line 229) | func TestCommandNames(t *testing.T) {
function TestCommandSubcommand (line 256) | func TestCommandSubcommand(t *testing.T) {
function TestCommandVisibleSubcommand (line 286) | func TestCommandVisibleSubcommand(t *testing.T) {
FILE: internal/clihelper/commands.go
type Commands (line 11) | type Commands
method Get (line 14) | func (commands Commands) Get(name string) *Command {
method Names (line 25) | func (commands Commands) Names() []string {
method Add (line 36) | func (commands *Commands) Add(cmd *Command) {
method FilterByNames (line 41) | func (commands Commands) FilterByNames(names []string) Commands {
method FilterByCategory (line 56) | func (commands Commands) FilterByCategory(categories ...*Category) Com...
method SkipRunning (line 69) | func (commands Commands) SkipRunning() Commands {
method VisibleCommands (line 79) | func (commands Commands) VisibleCommands() Commands {
method Len (line 99) | func (commands Commands) Len() int {
method Less (line 103) | func (commands Commands) Less(i, j int) bool {
method Swap (line 107) | func (commands Commands) Swap(i, j int) {
method WrapAction (line 111) | func (commands Commands) WrapAction(fn func(ctx context.Context, cliCt...
method Sort (line 121) | func (commands Commands) Sort() Commands {
method SetCategory (line 128) | func (commands Commands) SetCategory(category *Category) Commands {
method GetCategories (line 137) | func (commands Commands) GetCategories() Categories {
method Merge (line 150) | func (commands Commands) Merge(cmds ...*Command) Commands {
method DisableErrorOnMultipleSetFlag (line 155) | func (commands Commands) DisableErrorOnMultipleSetFlag() Commands {
FILE: internal/clihelper/context.go
type Context (line 4) | type Context struct
method NewCommandContext (line 19) | func (ctx *Context) NewCommandContext(command *Command, args Args) *Co...
method Parent (line 29) | func (ctx *Context) Parent() *Context {
method Args (line 34) | func (ctx *Context) Args() Args {
method Flag (line 40) | func (ctx *Context) Flag(name string) Flag {
function NewAppContext (line 12) | func NewAppContext(app *App, args Args) *Context {
FILE: internal/clihelper/errors.go
type InvalidCommandNameError (line 12) | type InvalidCommandNameError
method Error (line 14) | func (cmdName InvalidCommandNameError) Error() string {
type InvalidKeyValueError (line 18) | type InvalidKeyValueError struct
method Error (line 27) | func (err InvalidKeyValueError) Error() string {
function NewInvalidKeyValueError (line 23) | func NewInvalidKeyValueError(sep, value string) *InvalidKeyValueError {
type exitError (line 31) | type exitError struct
method Unwrap (line 36) | func (ee *exitError) Unwrap() error {
method Error (line 40) | func (ee *exitError) Error() string {
method ExitCode (line 48) | func (ee *exitError) ExitCode() int {
function NewExitError (line 53) | func NewExitError(message any, exitCode ExitCode) ExitCoder {
function handleExitCoder (line 79) | func handleExitCoder(_ *Context, err error, osExiter func(code int)) err...
type InvalidValueError (line 99) | type InvalidValueError struct
method Error (line 104) | func (err InvalidValueError) Error() string {
method Unwrap (line 108) | func (err InvalidValueError) Unwrap() error {
constant ErrMsgFlagUndefined (line 112) | ErrMsgFlagUndefined = "flag provided but not defined:"
type UndefinedFlagError (line 114) | type UndefinedFlagError
method Error (line 116) | func (flag UndefinedFlagError) Error() string {
function IsMultipleTimesSettingError (line 125) | func IsMultipleTimesSettingError(err error) bool {
FILE: internal/clihelper/exit_code.go
constant ExitCodeSuccess (line 5) | ExitCodeSuccess ExitCode = iota
constant ExitCodeGeneralError (line 6) | ExitCodeGeneralError
type ExitCode (line 10) | type ExitCode
type ExitCoder (line 13) | type ExitCoder interface
FILE: internal/clihelper/flag.go
type FlagSetterFunc (line 27) | type FlagSetterFunc
type MapFlagSetterFunc (line 29) | type MapFlagSetterFunc
type FlagActionFunc (line 33) | type FlagActionFunc
type FlagVariable (line 35) | type FlagVariable interface
type FlagValue (line 40) | type FlagValue interface
type Flag (line 73) | type Flag interface
type LookupEnvFuncType (line 97) | type LookupEnvFuncType
type FlagValueGetter (line 99) | type FlagValueGetter interface
type flagValueGetter (line 105) | type flagValueGetter struct
method EnvSet (line 110) | func (flag *flagValueGetter) EnvSet(val string) error {
method Set (line 130) | func (flag *flagValueGetter) Set(val string) error {
type Value (line 150) | type Value interface
type flagValue (line 156) | type flagValue struct
method MultipleSet (line 166) | func (flag *flagValue) MultipleSet() bool {
method IsBoolFlag (line 171) | func (flag *flagValue) IsBoolFlag() bool {
method IsNegativeBoolFlag (line 177) | func (flag *flagValue) IsNegativeBoolFlag() bool {
method Get (line 181) | func (flag *flagValue) Get() any {
method Set (line 185) | func (flag *flagValue) Set(str string) error {
method String (line 189) | func (flag *flagValue) String() string {
method GetInitialTextValue (line 197) | func (flag *flagValue) GetInitialTextValue() string {
method IsSet (line 201) | func (flag *flagValue) IsSet() bool {
method IsArgSet (line 205) | func (flag *flagValue) IsArgSet() bool {
method IsEnvSet (line 209) | func (flag *flagValue) IsEnvSet() bool {
method GetName (line 213) | func (flag *flagValue) GetName() string {
method Getter (line 217) | func (flag *flagValue) Getter(name string) FlagValueGetter {
type flag (line 222) | type flag struct
method Parse (line 228) | func (flag *flag) Parse(args Args) error {
method LookupEnv (line 232) | func (flag *flag) LookupEnv(envVar string) []string {
method Value (line 246) | func (flag *flag) Value() FlagValue {
method TakesValue (line 252) | func (flag *flag) TakesValue() bool {
method GetValue (line 259) | func (flag *flag) GetValue() string {
method GetCategory (line 265) | func (flag *flag) GetCategory() string {
method AllowedSubcommandScope (line 270) | func (flag *flag) AllowedSubcommandScope() bool {
function ApplyFlag (line 274) | func ApplyFlag(flag Flag, set *libflag.FlagSet) error {
FILE: internal/clihelper/flag_test.go
function mockDestValue (line 3) | func mockDestValue[T any](val T) *T {
FILE: internal/clihelper/flags.go
type Flags (line 12) | type Flags
method Parse (line 14) | func (flags Flags) Parse(args Args) error {
method NewFlagSet (line 24) | func (flags Flags) NewFlagSet(cmdName string, errHandler func(err erro...
method Apply (line 33) | func (flags Flags) Apply(flagSet *libflag.FlagSet, errHandler func(err...
method Get (line 46) | func (flags Flags) Get(name string) Flag {
method Filter (line 57) | func (flags Flags) Filter(names ...string) Flags {
method Add (line 72) | func (flags Flags) Add(newFlags ...Flag) Flags {
method VisibleFlags (line 78) | func (flags Flags) VisibleFlags() Flags {
method Len (line 90) | func (flags Flags) Len() int {
method Less (line 94) | func (flags Flags) Less(i, j int) bool {
method Swap (line 104) | func (flags Flags) Swap(i, j int) {
method RunActions (line 108) | func (flags Flags) RunActions(ctx context.Context, cliCtx *Context) er...
method Sort (line 120) | func (flags Flags) Sort() Flags {
method WithSubcommandScope (line 126) | func (flags Flags) WithSubcommandScope() Flags {
method Names (line 138) | func (flags Flags) Names() []string {
FILE: internal/clihelper/flags_test.go
function TestFalgsGet (line 28) | func TestFalgsGet(t *testing.T) {
function TestFalgsAdd (line 40) | func TestFalgsAdd(t *testing.T) {
function TestFalgsFilter (line 52) | func TestFalgsFilter(t *testing.T) {
function TestFalgsRunActions (line 60) | func TestFalgsRunActions(t *testing.T) {
FILE: internal/clihelper/funcs.go
type CompleteFunc (line 6) | type CompleteFunc
type ActionFunc (line 9) | type ActionFunc
type HelpFunc (line 18) | type HelpFunc
type SplitterFunc (line 21) | type SplitterFunc
type ExitErrHandlerFunc (line 25) | type ExitErrHandlerFunc
type FlagErrHandlerFunc (line 28) | type FlagErrHandlerFunc
FILE: internal/clihelper/generic_flag.go
type GenericType (line 16) | type GenericType interface
type GenericFlag (line 20) | type GenericFlag struct
method Apply (line 52) | func (flag *GenericFlag[T]) Apply(set *libflag.FlagSet) error {
method GetHidden (line 73) | func (flag *GenericFlag[T]) GetHidden() bool {
method GetUsage (line 78) | func (flag *GenericFlag[T]) GetUsage() string {
method GetEnvVars (line 83) | func (flag *GenericFlag[T]) GetEnvVars() []string {
method GetDefaultText (line 88) | func (flag *GenericFlag[T]) GetDefaultText() string {
method String (line 97) | func (flag *GenericFlag[T]) String() string {
method Names (line 102) | func (flag *GenericFlag[T]) Names() []string {
method RunAction (line 111) | func (flag *GenericFlag[T]) RunAction(ctx context.Context, cliCtx *Conte...
type genericValue (line 127) | type genericValue struct
function newGenericValue (line 132) | func newGenericValue[T comparable](value FlagVariable[T], setter FlagSet...
method Reset (line 139) | func (flag *genericValue[T]) Reset() {}
method Set (line 141) | func (flag *genericValue[T]) Set(str string) error {
method Get (line 153) | func (flag *genericValue[T]) Get() any {
method String (line 157) | func (flag *genericValue[T]) String() string {
type genericVar (line 164) | type genericVar struct
method Clone (line 168) | func (val *genericVar[T]) Clone(dest *T) FlagVariable[T] {
method Set (line 176) | func (val *genericVar[T]) Set(str string) error {
method Get (line 224) | func (val *genericVar[T]) Get() any {
method String (line 233) | func (val *genericVar[T]) String() string {
FILE: internal/clihelper/generic_flag_test.go
function TestGenericFlagStringApply (line 15) | func TestGenericFlagStringApply(t *testing.T) {
function TestGenericFlagIntApply (line 65) | func TestGenericFlagIntApply(t *testing.T) {
function TestGenericFlagInt64Apply (line 108) | func TestGenericFlagInt64Apply(t *testing.T) {
function testGenericFlagApply (line 151) | func testGenericFlagApply[T clihelper.GenericType](t *testing.T, flag *c...
FILE: internal/clihelper/help.go
function ShowAppHelp (line 26) | func ShowAppHelp(_ context.Context, cliCtx *Context) error {
function ShowCommandHelp (line 49) | func ShowCommandHelp(ctx context.Context, cliCtx *Context) error {
function HelpPrinterCustom (line 76) | func HelpPrinterCustom(cliCtx *Context, tpl string, customFuncs map[stri...
function ShowVersion (line 89) | func ShowVersion(_ context.Context, cliCtx *Context) error {
function parentCommands (line 104) | func parentCommands(ctx *Context) Commands {
function offsetCommands (line 123) | func offsetCommands(cmds Commands, fixed int) int {
FILE: internal/clihelper/map_flag.go
type MapFlagKeyType (line 25) | type MapFlagKeyType interface
type MapFlagValueType (line 29) | type MapFlagValueType interface
type MapFlag (line 34) | type MapFlag struct
method Apply (line 75) | func (flag *MapFlag[K, V]) Apply(set *libflag.FlagSet) error {
method GetHidden (line 122) | func (flag *MapFlag[K, V]) GetHidden() bool {
method GetUsage (line 127) | func (flag *MapFlag[K, V]) GetUsage() string {
method GetEnvVars (line 132) | func (flag *MapFlag[K, V]) GetEnvVars() []string {
method GetDefaultText (line 137) | func (flag *MapFlag[K, V]) GetDefaultText() string {
method String (line 146) | func (flag *MapFlag[K, V]) String() string {
method Names (line 151) | func (flag *MapFlag[K, V]) Names() []string {
method RunAction (line 160) | func (flag *MapFlag[K, V]) RunAction(ctx context.Context, cliCtx *Contex...
type mapValue (line 170) | type mapValue struct
function newMapValue (line 180) | func newMapValue[K, V comparable](keyType FlagVariable[K], valType FlagV...
method Reset (line 192) | func (flag *mapValue[K, V]) Reset() {
method Set (line 196) | func (flag *mapValue[K, V]) Set(str string) error {
method Get (line 221) | func (flag *mapValue[K, V]) Get() any {
method String (line 230) | func (flag *mapValue[K, V]) String() string {
FILE: internal/clihelper/map_flag_test.go
function TestMapFlagStringStringApply (line 15) | func TestMapFlagStringStringApply(t *testing.T) {
function TestMapFlagStringIntApply (line 61) | func TestMapFlagStringIntApply(t *testing.T) {
function testMapFlagApply (line 104) | func testMapFlagApply[K clihelper.MapFlagKeyType, V clihelper.MapFlagVal...
FILE: internal/clihelper/slice_flag.go
type SliceFlagType (line 19) | type SliceFlagType interface
type SliceFlag (line 24) | type SliceFlag struct
method Apply (line 62) | func (flag *SliceFlag[T]) Apply(set *libflag.FlagSet) error {
method GetHidden (line 102) | func (flag *SliceFlag[T]) GetHidden() bool {
method GetUsage (line 107) | func (flag *SliceFlag[T]) GetUsage() string {
method GetEnvVars (line 112) | func (flag *SliceFlag[T]) GetEnvVars() []string {
method GetDefaultText (line 117) | func (flag *SliceFlag[T]) GetDefaultText() string {
method String (line 126) | func (flag *SliceFlag[T]) String() string {
method Names (line 131) | func (flag *SliceFlag[T]) Names() []string {
method RunAction (line 140) | func (flag *SliceFlag[T]) RunAction(ctx context.Context, cliCtx *Context...
type sliceValue (line 151) | type sliceValue struct
function newSliceValue (line 158) | func newSliceValue[T comparable](valueType FlagVariable[T], valSep strin...
method Reset (line 167) | func (flag *sliceValue[T]) Reset() {
method Set (line 171) | func (flag *sliceValue[T]) Set(str string) error {
method Get (line 186) | func (flag *sliceValue[T]) Get() any {
method String (line 195) | func (flag *sliceValue[T]) String() string {
FILE: internal/clihelper/slice_flag_test.go
function TestSliceFlagStringApply (line 15) | func TestSliceFlagStringApply(t *testing.T) {
function TestSliceFlagIntApply (line 60) | func TestSliceFlagIntApply(t *testing.T) {
function TestSliceFlagInt64Apply (line 96) | func TestSliceFlagInt64Apply(t *testing.T) {
function testSliceFlagApply (line 132) | func testSliceFlagApply[T clihelper.SliceFlagType](t *testing.T, flag *c...
FILE: internal/clihelper/sort.go
function LexicographicLess (line 6) | func LexicographicLess(i, j string) bool {
FILE: internal/clihelper/sort_test.go
function TestLexicographicLess (line 11) | func TestLexicographicLess(t *testing.T) {
FILE: internal/cloner/clone.go
function Clone (line 7) | func Clone[T any](src T, opts ...Option) T { //nolint:ireturn
function WithShadowCopyTypes (line 20) | func WithShadowCopyTypes(values ...any) Option {
function WithSkippingTypes (line 30) | func WithSkippingTypes(values ...any) Option {
function WithShadowCopyInversePkgPrefixes (line 40) | func WithShadowCopyInversePkgPrefixes(prefixes ...string) Option {
FILE: internal/cloner/cloner.go
constant fieldTagName (line 9) | fieldTagName = "clone"
constant fieldTagValueRequired (line 12) | fieldTagValueRequired = "required"
constant fieldTagValueShadowCopy (line 14) | fieldTagValueShadowCopy = "shadowcopy"
constant fieldTagValueSkip (line 16) | fieldTagValueSkip = "skip"
constant fieldTagValueSkipAlias (line 17) | fieldTagValueSkipAlias = "-"
type Option (line 21) | type Option
type Config (line 23) | type Config struct
type Cloner (line 32) | type Cloner struct
method Clone (line 36) | func (cloner *Cloner[T]) Clone(src T) T {
method getDstValue (line 46) | func (cloner *Cloner[T]) getDstValue(src reflect.Value) (reflect.Value, ...
method cloneValue (line 90) | func (cloner *Cloner[T]) cloneValue(src reflect.Value) reflect.Value {
method cloneInt (line 127) | func (cloner *Cloner[T]) cloneInt(src reflect.Value) reflect.Value {
method cloneUint (line 134) | func (cloner *Cloner[T]) cloneUint(src reflect.Value) reflect.Value {
method cloneFloat (line 141) | func (cloner *Cloner[T]) cloneFloat(src reflect.Value) reflect.Value {
method cloneBool (line 148) | func (cloner *Cloner[T]) cloneBool(src reflect.Value) reflect.Value {
method cloneString (line 155) | func (cloner *Cloner[T]) cloneString(src reflect.Value) reflect.Value {
method cloneSlice (line 163) | func (cloner *Cloner[T]) cloneSlice(src reflect.Value) reflect.Value {
method cloneArray (line 176) | func (cloner *Cloner[T]) cloneArray(src reflect.Value) reflect.Value {
method cloneMap (line 189) | func (cloner *Cloner[T]) cloneMap(src reflect.Value) reflect.Value {
method clonePointer (line 202) | func (cloner *Cloner[T]) clonePointer(src reflect.Value) reflect.Value {
method cloneStruct (line 216) | func (cloner *Cloner[T]) cloneStruct(src reflect.Value) reflect.Value {
FILE: internal/codegen/errors.go
type UnknownGenerateIfExistsVal (line 7) | type UnknownGenerateIfExistsVal struct
method Error (line 11) | func (err UnknownGenerateIfExistsVal) Error() string {
type UnknownGenerateIfDisabledVal (line 19) | type UnknownGenerateIfDisabledVal struct
method Error (line 23) | func (err UnknownGenerateIfDisabledVal) Error() string {
type GenerateFileExistsError (line 31) | type GenerateFileExistsError struct
method Error (line 35) | func (err GenerateFileExistsError) Error() string {
type GenerateFileRemoveError (line 39) | type GenerateFileRemoveError struct
method Error (line 43) | func (err GenerateFileRemoveError) Error() string {
FILE: internal/codegen/generate.go
constant TerragruntGeneratedSignature (line 26) | TerragruntGeneratedSignature = "Generated by Terragrunt. Sig: nIlQXj57tb...
constant DefaultCommentPrefix (line 29) | DefaultCommentPrefix = "# "
type GenerateConfigExists (line 33) | type GenerateConfigExists
constant ExistsError (line 36) | ExistsError GenerateConfigExists = iota
constant ExistsSkip (line 37) | ExistsSkip
constant ExistsOverwrite (line 38) | ExistsOverwrite
constant ExistsOverwriteTerragrunt (line 39) | ExistsOverwriteTerragrunt
constant ExistsUnknown (line 40) | ExistsUnknown
type GenerateConfigDisabled (line 44) | type GenerateConfigDisabled
constant DisabledSkip (line 47) | DisabledSkip GenerateConfigDisabled = iota
constant DisabledRemove (line 48) | DisabledRemove
constant DisabledRemoveTerragrunt (line 49) | DisabledRemoveTerragrunt
constant DisabledUnknown (line 50) | DisabledUnknown
constant ExistsErrorStr (line 54) | ExistsErrorStr = "error"
constant ExistsSkipStr (line 55) | ExistsSkipStr = "skip"
constant ExistsOverwriteStr (line 56) | ExistsOverwriteStr = "overwrite"
constant ExistsOverwriteTerragruntStr (line 57) | ExistsOverwriteTerragruntStr = "overwrite_terragrunt"
constant DisabledSkipStr (line 59) | DisabledSkipStr = "skip"
constant DisabledRemoveStr (line 60) | DisabledRemoveStr = "remove"
constant DisabledRemoveTerragruntStr (line 61) | DisabledRemoveTerragruntStr = "remove_terragrunt"
constant assumeRoleConfigKey (line 63) | assumeRoleConfigKey = "assume_role"
constant assumeRoleWithWebIdentityConfigKey (line 64) | assumeRoleWithWebIdentityConfigKey = "assume_role_with_web_identity"
constant encryptionBlockName (line 66) | encryptionBlockName = "encryption"
constant EncryptionKeyProviderKey (line 68) | EncryptionKeyProviderKey = "key_provider"
constant encryptionResourceName (line 69) | encryptionResourceName = "default"
constant encryptionMethodKey (line 71) | encryptionMethodKey = "method"
constant encryptionDefaultMethod (line 72) | encryptionDefaultMethod = "aes_gcm"
constant encryptionKeysAttributeName (line 74) | encryptionKeysAttributeName = "keys"
constant encryptionStateBlockName (line 76) | encryptionStateBlockName = "state"
constant encryptionPlanBlockName (line 77) | encryptionPlanBlockName = "plan"
type GenerateConfig (line 81) | type GenerateConfig struct
function WriteToFile (line 99) | func WriteToFile(l log.Logger, basePath string, config *GenerateConfig) ...
function shouldContinueWithFileExists (line 174) | func shouldContinueWithFileExists(l log.Logger, path string, ifExists Ge...
function shouldRemoveWithFileExists (line 215) | func shouldRemoveWithFileExists(l log.Logger, path string, ifDisable Gen...
function fileWasGeneratedByTerragrunt (line 252) | func fileWasGeneratedByTerragrunt(path string) (bool, error) {
constant terraformBlock (line 270) | terraformBlock = "terraform"
constant backendBlock (line 271) | backendBlock = "backend"
function RemoteStateConfigToTerraformCode (line 275) | func RemoteStateConfigToTerraformCode(backend string, config map[string]...
function convertValue (line 533) | func convertValue(v any) (ctyjson.SimpleJSONValue, error) {
function ReplaceAllCommasOutsideQuotesWithNewLines (line 567) | func ReplaceAllCommasOutsideQuotesWithNewLines(s string) string {
function GenerateConfigExistsFromString (line 584) | func GenerateConfigExistsFromString(val string) (GenerateConfigExists, e...
function GenerateConfigDisabledFromString (line 600) | func GenerateConfigDisabledFromString(val string) (GenerateConfigDisable...
FILE: internal/codegen/generate_test.go
function TestRemoteStateConfigToTerraformCode (line 17) | func TestRemoteStateConfigToTerraformCode(t *testing.T) {
function TestRemoteStateConfigToTerraformCode_BoolValues (line 208) | func TestRemoteStateConfigToTerraformCode_BoolValues(t *testing.T) {
function TestRemoteStateConfigToTerraformCode_StringBoolProducesQuotedValue (line 238) | func TestRemoteStateConfigToTerraformCode_StringBoolProducesQuotedValue(...
function TestFmtGeneratedFile (line 255) | func TestFmtGeneratedFile(t *testing.T) {
function TestGenerateDisabling (line 325) | func TestGenerateDisabling(t *testing.T) {
function TestReplaceAllCommasOutsideQuotesWithNewLines (line 379) | func TestReplaceAllCommasOutsideQuotesWithNewLines(t *testing.T) {
FILE: internal/component/component.go
type Kind (line 20) | type Kind
type Component (line 24) | type Component interface
type Origin (line 56) | type Origin
constant OriginUnknown (line 59) | OriginUnknown Origin = "unknown"
constant OriginWorktreeDiscovery (line 60) | OriginWorktreeDiscovery Origin = "worktree-discovery"
constant OriginGraphDiscovery (line 61) | OriginGraphDiscovery Origin = "graph-discovery"
constant OriginPathDiscovery (line 62) | OriginPathDiscovery Origin = "path-discovery"
constant OriginRelationshipDiscovery (line 63) | OriginRelationshipDiscovery Origin = "relationship-discovery"
type DiscoveryContext (line 72) | type DiscoveryContext struct
method Copy (line 83) | func (dc *DiscoveryContext) Copy() *DiscoveryContext {
method CopyWithNewOrigin (line 96) | func (dc *DiscoveryContext) CopyWithNewOrigin(origin Origin) *Discover...
method Origin (line 104) | func (dc *DiscoveryContext) Origin() Origin {
method SuggestOrigin (line 117) | func (dc *DiscoveryContext) SuggestOrigin(origin Origin) {
type Components (line 124) | type Components
method Sort (line 127) | func (c Components) Sort() Components {
method Filter (line 136) | func (c Components) Filter(kind Kind) Components {
method FilterByPath (line 153) | func (c Components) FilterByPath(path string) Components {
method RemoveByPath (line 166) | func (c Components) RemoveByPath(path string) Components {
method Paths (line 183) | func (c Components) Paths() []string {
method CycleCheck (line 200) | func (c Components) CycleCheck() (Component, error) {
type ThreadSafeComponents (line 244) | type ThreadSafeComponents struct
method resolvedPathFor (line 268) | func (tsc *ThreadSafeComponents) resolvedPathFor(path string) string {
method EnsureComponent (line 281) | func (tsc *ThreadSafeComponents) EnsureComponent(c Component) (Compone...
method findComponent (line 293) | func (tsc *ThreadSafeComponents) findComponent(c Component) (Component...
method addComponent (line 313) | func (tsc *ThreadSafeComponents) addComponent(c Component) (Component,...
method FindByPath (line 339) | func (tsc *ThreadSafeComponents) FindByPath(path string) Component {
method ToComponents (line 355) | func (tsc *ThreadSafeComponents) ToComponents() Components {
method Len (line 367) | func (tsc *ThreadSafeComponents) Len() int {
function NewThreadSafeComponents (line 251) | func NewThreadSafeComponents(components Components) *ThreadSafeComponents {
FILE: internal/component/component_test.go
function TestComponentsSort (line 12) | func TestComponentsSort(t *testing.T) {
function TestComponentsFilter (line 32) | func TestComponentsFilter(t *testing.T) {
function TestComponentsCycleCheck (line 64) | func TestComponentsCycleCheck(t *testing.T) {
function TestUnitStringConcurrent (line 148) | func TestUnitStringConcurrent(t *testing.T) {
function TestThreadSafeComponentsEnsureNoDuplicates (line 175) | func TestThreadSafeComponentsEnsureNoDuplicates(t *testing.T) {
function TestThreadSafeComponentsFindByPath (line 193) | func TestThreadSafeComponentsFindByPath(t *testing.T) {
function TestThreadSafeComponentsConcurrentAccess (line 209) | func TestThreadSafeComponentsConcurrentAccess(t *testing.T) {
FILE: internal/component/stack.go
constant StackKind (line 15) | StackKind Kind = "stack"
type Stack (line 19) | type Stack struct
method WithDiscoveryContext (line 42) | func (s *Stack) WithDiscoveryContext(ctx *DiscoveryContext) *Stack {
method Config (line 49) | func (s *Stack) Config() *config.StackConfig {
method StoreConfig (line 54) | func (s *Stack) StoreConfig(cfg *config.StackConfig) {
method Kind (line 59) | func (s *Stack) Kind() Kind {
method Path (line 64) | func (s *Stack) Path() string {
method SetPath (line 69) | func (s *Stack) SetPath(path string) {
method DisplayPath (line 75) | func (s *Stack) DisplayPath() string {
method External (line 88) | func (s *Stack) External() bool {
method SetExternal (line 93) | func (s *Stack) SetExternal() {
method Reading (line 98) | func (s *Stack) Reading() []string {
method SetReading (line 103) | func (s *Stack) SetReading(files ...string) {
method Sources (line 110) | func (s *Stack) Sources() []string {
method ConfigFile (line 115) | func (s *Stack) ConfigFile() string {
method DiscoveryContext (line 120) | func (s *Stack) DiscoveryContext() *DiscoveryContext {
method SetDiscoveryContext (line 125) | func (s *Stack) SetDiscoveryContext(ctx *DiscoveryContext) {
method Origin (line 130) | func (s *Stack) Origin() Origin {
method lock (line 139) | func (s *Stack) lock() {
method unlock (line 144) | func (s *Stack) unlock() {
method rLock (line 149) | func (s *Stack) rLock() {
method rUnlock (line 154) | func (s *Stack) rUnlock() {
method AddDependency (line 163) | func (s *Stack) AddDependency(dependency Component) {
method ensureDependency (line 170) | func (s *Stack) ensureDependency(dependency Component) {
method ensureDependent (line 180) | func (s *Stack) ensureDependent(dependent Component) {
method AddDependent (line 194) | func (s *Stack) AddDependent(dependent Component) {
method Dependencies (line 201) | func (s *Stack) Dependencies() Components {
method Dependents (line 209) | func (s *Stack) Dependents() Components {
method String (line 223) | func (s *Stack) String() string {
method FindUnitByPath (line 240) | func (s *Stack) FindUnitByPath(path string) *Unit {
function NewStack (line 32) | func NewStack(path string) *Stack {
FILE: internal/component/unit.go
constant UnitKind (line 16) | UnitKind Kind = "unit"
type Unit (line 20) | type Unit struct
method WithReading (line 46) | func (u *Unit) WithReading(files ...string) *Unit {
method WithConfig (line 53) | func (u *Unit) WithConfig(cfg *config.TerragruntConfig) *Unit {
method WithDiscoveryContext (line 60) | func (u *Unit) WithDiscoveryContext(ctx *DiscoveryContext) *Unit {
method Config (line 67) | func (u *Unit) Config() *config.TerragruntConfig {
method StoreConfig (line 72) | func (u *Unit) StoreConfig(cfg *config.TerragruntConfig) {
method ConfigFile (line 77) | func (u *Unit) ConfigFile() string {
method SetConfigFile (line 82) | func (u *Unit) SetConfigFile(filename string) {
method Kind (line 87) | func (u *Unit) Kind() Kind {
method Path (line 92) | func (u *Unit) Path() string {
method SetPath (line 97) | func (u *Unit) SetPath(path string) {
method External (line 102) | func (u *Unit) External() bool {
method SetExternal (line 107) | func (u *Unit) SetExternal() {
method Excluded (line 112) | func (u *Unit) Excluded() bool {
method SetExcluded (line 117) | func (u *Unit) SetExcluded(excluded bool) {
method Reading (line 122) | func (u *Unit) Reading() []string {
method SetReading (line 127) | func (u *Unit) SetReading(files ...string) {
method Sources (line 132) | func (u *Unit) Sources() []string {
method DiscoveryContext (line 141) | func (u *Unit) DiscoveryContext() *DiscoveryContext {
method SetDiscoveryContext (line 146) | func (u *Unit) SetDiscoveryContext(ctx *DiscoveryContext) {
method Origin (line 151) | func (u *Unit) Origin() Origin {
method lock (line 160) | func (u *Unit) lock() {
method unlock (line 165) | func (u *Unit) unlock() {
method rLock (line 170) | func (u *Unit) rLock() {
method rUnlock (line 175) | func (u *Unit) rUnlock() {
method AddDependency (line 184) | func (u *Unit) AddDependency(dependency Component) {
method ensureDependency (line 191) | func (u *Unit) ensureDependency(dependency Component) {
method ensureDependent (line 201) | func (u *Unit) ensureDependent(dependent Component) {
method AddDependent (line 215) | func (u *Unit) AddDependent(dependent Component) {
method Dependencies (line 222) | func (u *Unit) Dependencies() Components {
method Dependents (line 230) | func (u *Unit) Dependents() Components {
method String (line 242) | func (u *Unit) String() string {
method DisplayPath (line 262) | func (u *Unit) DisplayPath() string {
method FindInPaths (line 276) | func (u *Unit) FindInPaths(targetDirs []string) bool {
method PlanFile (line 290) | func (u *Unit) PlanFile(rootWorkingDir, outputFolder, jsonOutputFolder...
method OutputFile (line 305) | func (u *Unit) OutputFile(rootWorkingDir, outputFolder string) string {
method OutputJSONFile (line 310) | func (u *Unit) OutputJSONFile(rootWorkingDir, jsonOutputFolder string)...
method planFilePath (line 315) | func (u *Unit) planFilePath(rootWorkingDir, outputFolder, fileName str...
function NewUnit (line 34) | func NewUnit(path string) *Unit {
FILE: internal/component/unit_output.go
type flusher (line 10) | type flusher interface
type writerUnwrapper (line 16) | type writerUnwrapper interface
function unitOutputLock (line 24) | func unitOutputLock(key string) *sync.Mutex {
function FlushOutput (line 41) | func FlushOutput(u *Unit, w io.Writer) error {
FILE: internal/configbridge/bridge.go
function NewParsingContext (line 20) | func NewParsingContext(ctx context.Context, l log.Logger, opts *options....
function populateFromOpts (line 28) | func populateFromOpts(pctx *config.ParsingContext, opts *options.Terragr...
function ShellRunOptsFromOpts (line 71) | func ShellRunOptsFromOpts(opts *options.TerragruntOptions) *shell.ShellO...
function BackendOptsFromOpts (line 88) | func BackendOptsFromOpts(opts *options.TerragruntOptions) *backend.Optio...
function RemoteStateOptsFromOpts (line 99) | func RemoteStateOptsFromOpts(opts *options.TerragruntOptions) *remotesta...
function TFRunOptsFromOpts (line 108) | func TFRunOptsFromOpts(opts *options.TerragruntOptions) *tf.TFOptions {
function NewRunOptions (line 121) | func NewRunOptions(opts *options.TerragruntOptions) *run.Options {
FILE: internal/ctyhelper/helper.go
function ParseCtyValueToMap (line 27) | func ParseCtyValueToMap(value cty.Value) (map[string]any, error) {
type CtyJSONOutput (line 61) | type CtyJSONOutput struct
function UpdateUnknownCtyValValues (line 67) | func UpdateUnknownCtyValValues(value cty.Value) (cty.Value, error) {
FILE: internal/ctyhelper/helper_test.go
function TestUpdateUnknownCtyValValues (line 13) | func TestUpdateUnknownCtyValValues(t *testing.T) {
FILE: internal/discovery/benchmark_test.go
function BenchmarkDiscovery (line 22) | func BenchmarkDiscovery(b *testing.B) {
function benchmarkPathExpression (line 50) | func benchmarkPathExpression(b *testing.B, n int) {
function benchmarkGraphExpression (line 78) | func benchmarkGraphExpression(b *testing.B, n int) {
function benchmarkPathAndGraphExpression (line 106) | func benchmarkPathAndGraphExpression(b *testing.B, n int) {
function newDiscardLogger (line 132) | func newDiscardLogger() log.Logger {
function createFixtures (line 143) | func createFixtures(b *testing.B, tmpDir string, n int) {
FILE: internal/discovery/constructor.go
type DiscoveryCommandOptions (line 15) | type DiscoveryCommandOptions struct
type HCLCommandOptions (line 29) | type HCLCommandOptions struct
type StackGenerateOptions (line 36) | type StackGenerateOptions struct
function NewForDiscoveryCommand (line 43) | func NewForDiscoveryCommand(l log.Logger, opts *DiscoveryCommandOptions)...
function NewForHCLCommand (line 105) | func NewForHCLCommand(l log.Logger, opts HCLCommandOptions) (*Discovery,...
function NewForStackGenerate (line 116) | func NewForStackGenerate(l log.Logger, opts StackGenerateOptions) (*Disc...
function NewDiscovery (line 127) | func NewDiscovery(dir string) *Discovery {
FILE: internal/discovery/discovery.go
method Discover (line 22) | func (d *Discovery) Discover(
method runFilesystemPhase (line 112) | func (d *Discovery) runFilesystemPhase(
method runParsePhase (line 203) | func (d *Discovery) runParsePhase(
method runGraphPhase (line 238) | func (d *Discovery) runGraphPhase(
method runRelationshipPhase (line 302) | func (d *Discovery) runRelationshipPhase(
method buildDependencyGraph (line 321) | func (d *Discovery) buildDependencyGraph(
method buildComponentDependencies (line 361) | func (d *Discovery) buildComponentDependencies(
function removeCycles (line 424) | func removeCycles(components component.Components) (component.Components...
method filterGraphTarget (line 447) | func (d *Discovery) filterGraphTarget(components component.Components) c...
function canonicalizeGraphTarget (line 464) | func canonicalizeGraphTarget(baseDir, target string) string {
function buildDependentsIndex (line 493) | func buildDependentsIndex(components component.Components) map[string][]...
function propagateTransitiveDependents (line 510) | func propagateTransitiveDependents(dependentUnits map[string][]string) {
function buildAllowSet (line 545) | func buildAllowSet(targetPath string, dependentUnits map[string][]string...
function filterByAllowSet (line 559) | func filterByAllowSet(components component.Components, allowed map[strin...
method applyQueueFilters (line 574) | func (d *Discovery) applyQueueFilters(opts *options.TerragruntOptions, c...
method applyExcludeModules (line 581) | func (d *Discovery) applyExcludeModules(opts *options.TerragruntOptions,...
FILE: internal/discovery/discovery_integration_test.go
function TestDiscovery_BasicWithHiddenDirectories (line 19) | func TestDiscovery_BasicWithHiddenDirectories(t *testing.T) {
function TestDiscovery_StackHiddenDiscovered (line 110) | func TestDiscovery_StackHiddenDiscovered(t *testing.T) {
function TestDiscovery_WithDependencies (line 135) | func TestDiscovery_WithDependencies(t *testing.T) {
function TestDiscovery_CycleDetection (line 269) | func TestDiscovery_CycleDetection(t *testing.T) {
function TestDiscovery_CycleDetectionWithDisabledDependency (line 333) | func TestDiscovery_CycleDetectionWithDisabledDependency(t *testing.T) {
function TestDiscovery_WithParseExclude (line 397) | func TestDiscovery_WithParseExclude(t *testing.T) {
function TestDiscovery_WithCustomConfigFilenames (line 488) | func TestDiscovery_WithCustomConfigFilenames(t *testing.T) {
function TestDiscovery_WithReadFiles (line 545) | func TestDiscovery_WithReadFiles(t *testing.T) {
function TestDiscovery_WithStackConfigParsing (line 617) | func TestDiscovery_WithStackConfigParsing(t *testing.T) {
function TestDiscovery_IncludeExcludeFilterSemantics (line 704) | func TestDiscovery_IncludeExcludeFilterSemantics(t *testing.T) {
function TestDiscovery_HiddenIncludedByIncludeDirs (line 778) | func TestDiscovery_HiddenIncludedByIncludeDirs(t *testing.T) {
function TestDiscovery_ExternalDependencies (line 806) | func TestDiscovery_ExternalDependencies(t *testing.T) {
function TestDiscovery_BreakCycles (line 877) | func TestDiscovery_BreakCycles(t *testing.T) {
function TestDiscovery_WithNumWorkers (line 935) | func TestDiscovery_WithNumWorkers(t *testing.T) {
function TestDiscovery_WithMaxDependencyDepth (line 964) | func TestDiscovery_WithMaxDependencyDepth(t *testing.T) {
function TestDiscovery_SuppressParseErrors (line 1054) | func TestDiscovery_SuppressParseErrors(t *testing.T) {
function TestDiscovery_ExcludeDependencies (line 1096) | func TestDiscovery_ExcludeDependencies(t *testing.T) {
function TestDiscovery_OriginalTerragruntConfigPath (line 1190) | func TestDiscovery_OriginalTerragruntConfigPath(t *testing.T) {
FILE: internal/discovery/discovery_test.go
function TestCandidacyClassifier_Analyze (line 18) | func TestCandidacyClassifier_Analyze(t *testing.T) {
function TestCandidacyClassifier_ClassifyComponent (line 116) | func TestCandidacyClassifier_ClassifyComponent(t *testing.T) {
function TestDiscovery_SimpleFilesystem (line 219) | func TestDiscovery_SimpleFilesystem(t *testing.T) {
function TestDiscovery_WithPathFilter (line 254) | func TestDiscovery_WithPathFilter(t *testing.T) {
function TestDiscovery_WithNegatedFilter (line 294) | func TestDiscovery_WithNegatedFilter(t *testing.T) {
function TestDiscovery_CombinedFilters (line 339) | func TestDiscovery_CombinedFilters(t *testing.T) {
function TestPhaseKind_String (line 384) | func TestPhaseKind_String(t *testing.T) {
function TestDiscoveryStatus_String (line 408) | func TestDiscoveryStatus_String(t *testing.T) {
function TestCandidacyReason_String (line 429) | func TestCandidacyReason_String(t *testing.T) {
function TestDiscovery_PopulatesReadingField (line 452) | func TestDiscovery_PopulatesReadingField(t *testing.T) {
function TestDiscovery_BothHclAndStackFileInSameDir (line 520) | func TestDiscovery_BothHclAndStackFileInSameDir(t *testing.T) {
function TestDiscovery_SingleUnitNoDuplicateError (line 556) | func TestDiscovery_SingleUnitNoDuplicateError(t *testing.T) {
FILE: internal/discovery/errors.go
type GitFilterCommandError (line 12) | type GitFilterCommandError struct
method Error (line 17) | func (e GitFilterCommandError) Error() string {
function NewGitFilterCommandError (line 37) | func NewGitFilterCommandError(cmd string, args []string) error {
type MissingDiscoveryContextError (line 47) | type MissingDiscoveryContextError struct
method Error (line 51) | func (e MissingDiscoveryContextError) Error() string {
function NewMissingDiscoveryContextError (line 62) | func NewMissingDiscoveryContextError(componentPath string) error {
type MissingWorkingDirectoryError (line 71) | type MissingWorkingDirectoryError struct
method Error (line 75) | func (e MissingWorkingDirectoryError) Error() string {
function NewMissingWorkingDirectoryError (line 86) | func NewMissingWorkingDirectoryError(componentPath string) error {
type ClassificationError (line 93) | type ClassificationError struct
method Error (line 98) | func (e ClassificationError) Error() string {
function NewClassificationError (line 106) | func NewClassificationError(componentPath, reason string) error {
type CoexistenceError (line 115) | type CoexistenceError struct
method Error (line 121) | func (e CoexistenceError) Error() string {
function NewCoexistenceError (line 130) | func NewCoexistenceError(componentPath, unitConfigFile, stackConfigFile ...
FILE: internal/discovery/filter_test.go
function TestDiscovery_GraphExpressionFilters (line 20) | func TestDiscovery_GraphExpressionFilters(t *testing.T) {
function TestDiscovery_GraphExpressionFilters_ComplexGraph (line 111) | func TestDiscovery_GraphExpressionFilters_ComplexGraph(t *testing.T) {
function TestDiscovery_GraphExpressionFilters_OnlyMatchingComponentsTriggerDiscovery (line 192) | func TestDiscovery_GraphExpressionFilters_OnlyMatchingComponentsTriggerD...
function TestDiscovery_GraphExpressionFilters_FiltersAppliedAfterDiscovery (line 253) | func TestDiscovery_GraphExpressionFilters_FiltersAppliedAfterDiscovery(t...
function TestDiscovery_ReadingAttributeFilters (line 318) | func TestDiscovery_ReadingAttributeFilters(t *testing.T) {
function TestDiscovery_ReadingAttributeFiltersAbsolutePaths (line 502) | func TestDiscovery_ReadingAttributeFiltersAbsolutePaths(t *testing.T) {
function TestDiscovery_ReadingAttributeFiltersErrorHandling (line 553) | func TestDiscovery_ReadingAttributeFiltersErrorHandling(t *testing.T) {
function TestDiscovery_AttributeFilters (line 597) | func TestDiscovery_AttributeFilters(t *testing.T) {
function TestDiscovery_FilterEdgeCases (line 759) | func TestDiscovery_FilterEdgeCases(t *testing.T) {
function TestDiscovery_FilterErrorHandling (line 853) | func TestDiscovery_FilterErrorHandling(t *testing.T) {
function TestDiscovery_ExternalAttributeFilter (line 938) | func TestDiscovery_ExternalAttributeFilter(t *testing.T) {
function TestDiscovery_DependentDiscovery_Standalone (line 1021) | func TestDiscovery_DependentDiscovery_Standalone(t *testing.T) {
function TestDiscovery_DependentDiscovery_ExcludeTarget (line 1091) | func TestDiscovery_DependentDiscovery_ExcludeTarget(t *testing.T) {
function TestDiscovery_DependencyDiscovery_ExcludeTarget (line 1157) | func TestDiscovery_DependencyDiscovery_ExcludeTarget(t *testing.T) {
function TestDiscovery_DependentDiscovery_Bidirectional (line 1227) | func TestDiscovery_DependentDiscovery_Bidirectional(t *testing.T) {
function TestDiscovery_DependentDiscovery_OutsideWorkingDir (line 1298) | func TestDiscovery_DependentDiscovery_OutsideWorkingDir(t *testing.T) {
function TestDiscovery_DependentDiscovery_OutsideWorkingDir_MultipleLevels (line 1377) | func TestDiscovery_DependentDiscovery_OutsideWorkingDir_MultipleLevels(t...
function TestDiscovery_DependentDiscovery_DirectDependentOnly (line 1466) | func TestDiscovery_DependentDiscovery_DirectDependentOnly(t *testing.T) {
function TestDiscovery_NegatedGraphFilters (line 1545) | func TestDiscovery_NegatedGraphFilters(t *testing.T) {
FILE: internal/discovery/graph_option.go
type graphTargetOption (line 5) | type graphTargetOption struct
method Apply (line 18) | func (o graphTargetOption) Apply(stack common.StackRunner) {}
method GraphTarget (line 21) | func (o graphTargetOption) GraphTarget() string {
function WithGraphTarget (line 13) | func WithGraphTarget(targetDir string) common.Option {
FILE: internal/discovery/graph_target_test.go
function TestDiscoveryWithGraphTarget_RetainsTargetAndDependents (line 21) | func TestDiscoveryWithGraphTarget_RetainsTargetAndDependents(t *testing....
function TestDiscoveryGraphTarget_ParityWithFilterQueries (line 72) | func TestDiscoveryGraphTarget_ParityWithFilterQueries(t *testing.T) {
function TestDiscoveryWithGraphTarget_NoDependents (line 132) | func TestDiscoveryWithGraphTarget_NoDependents(t *testing.T) {
function TestDiscoveryWithOptions_GraphTarget (line 173) | func TestDiscoveryWithOptions_GraphTarget(t *testing.T) {
type mockGraphTargetOption (line 217) | type mockGraphTargetOption struct
method GraphTarget (line 221) | func (m *mockGraphTargetOption) GraphTarget() string {
FILE: internal/discovery/helpers.go
constant defaultDiscoveryWorkers (line 19) | defaultDiscoveryWorkers = 4
constant maxDiscoveryWorkers (line 22) | maxDiscoveryWorkers = defaultDiscoveryWorkers * 2
constant defaultMaxDependencyDepth (line 25) | defaultMaxDependencyDepth = 1000
constant maxCycleRemovalAttempts (line 28) | maxCycleRemovalAttempts = 100
type stringSet (line 36) | type stringSet struct
method LoadOrStore (line 50) | func (s *stringSet) LoadOrStore(key string) (loaded bool) {
method Load (line 64) | func (s *stringSet) Load(key string) bool {
function newStringSet (line 42) | func newStringSet() *stringSet {
function isExternal (line 76) | func isExternal(workingDir string, componentPath string) bool {
function componentFromDependencyPath (line 105) | func componentFromDependencyPath(path string, components *component.Thre...
function createComponentFromPath (line 119) | func createComponentFromPath(
function validateNoCoexistence (line 160) | func validateNoCoexistence(results []DiscoveryResult) error {
function deduplicateResults (line 182) | func deduplicateResults(results []DiscoveryResult) []DiscoveryResult {
function resultsToComponents (line 199) | func resultsToComponents(results []DiscoveryResult) component.Components {
function sanitizeReadFiles (line 209) | func sanitizeReadFiles(files []string) []string {
function extractDependencyPaths (line 224) | func extractDependencyPaths(cfg *config.TerragruntConfig, c component.Co...
FILE: internal/discovery/options.go
method WithDiscoveryContext (line 11) | func (d *Discovery) WithDiscoveryContext(ctx *component.DiscoveryContext...
method WithWorktrees (line 17) | func (d *Discovery) WithWorktrees(w *worktrees.Worktrees) *Discovery {
method WithConfigFilenames (line 23) | func (d *Discovery) WithConfigFilenames(filenames []string) *Discovery {
method WithParserOptions (line 29) | func (d *Discovery) WithParserOptions(opts []hclparse.Option) *Discovery {
method WithFilters (line 35) | func (d *Discovery) WithFilters(filters filter.Filters) *Discovery {
method WithMaxDependencyDepth (line 55) | func (d *Discovery) WithMaxDependencyDepth(depth int) *Discovery {
method WithNumWorkers (line 61) | func (d *Discovery) WithNumWorkers(numWorkers int) *Discovery {
method WithNoHidden (line 70) | func (d *Discovery) WithNoHidden() *Discovery {
method WithRequiresParse (line 76) | func (d *Discovery) WithRequiresParse() *Discovery {
method WithParseExclude (line 82) | func (d *Discovery) WithParseExclude() *Discovery {
method WithParseIncludes (line 90) | func (d *Discovery) WithParseIncludes() *Discovery {
method WithReadFiles (line 98) | func (d *Discovery) WithReadFiles() *Discovery {
method WithSuppressParseErrors (line 106) | func (d *Discovery) WithSuppressParseErrors() *Discovery {
method WithBreakCycles (line 112) | func (d *Discovery) WithBreakCycles() *Discovery {
method WithRelationships (line 118) | func (d *Discovery) WithRelationships() *Discovery {
method WithGitRoot (line 124) | func (d *Discovery) WithGitRoot(gitRoot string) *Discovery {
method WithGraphTarget (line 130) | func (d *Discovery) WithGraphTarget(target string) *Discovery {
method WithOptions (line 138) | func (d *Discovery) WithOptions(opts ...any) *Discovery {
FILE: internal/discovery/phase_filesystem.go
type FilesystemPhase (line 16) | type FilesystemPhase struct
method Name (line 31) | func (p *FilesystemPhase) Name() string {
method Kind (line 36) | func (p *FilesystemPhase) Kind() PhaseKind {
method Run (line 41) | func (p *FilesystemPhase) Run(ctx context.Context, l log.Logger, input...
method skipDirIfIgnorable (line 100) | func (p *FilesystemPhase) skipDirIfIgnorable(discovery *Discovery, dir...
method processFile (line 116) | func (p *FilesystemPhase) processFile(
function NewFilesystemPhase (line 22) | func NewFilesystemPhase(numWorkers int) *FilesystemPhase {
FILE: internal/discovery/phase_graph.go
type GraphPhase (line 21) | type GraphPhase struct
method Name (line 52) | func (p *GraphPhase) Name() string {
method Kind (line 57) | func (p *GraphPhase) Kind() PhaseKind {
method Run (line 62) | func (p *GraphPhase) Run(ctx context.Context, l log.Logger, input *Pha...
method processGraphTarget (line 171) | func (p *GraphPhase) processGraphTarget(
method discoverDependencies (line 240) | func (p *GraphPhase) discoverDependencies(
method discoverDependents (line 340) | func (p *GraphPhase) discoverDependents(
method discoverDependentsUpstream (line 418) | func (p *GraphPhase) discoverDependentsUpstream(
method processUpstreamCandidate (line 596) | func (p *GraphPhase) processUpstreamCandidate(
method resolveDependency (line 720) | func (p *GraphPhase) resolveDependency(
type graphTraversalState (line 29) | type graphTraversalState struct
function NewGraphPhase (line 38) | func NewGraphPhase(numWorkers, maxDepth int) *GraphPhase {
type upstreamDiscoveryState (line 403) | type upstreamDiscoveryState struct
FILE: internal/discovery/phase_parse.go
type ParsePhase (line 23) | type ParsePhase struct
method Name (line 38) | func (p *ParsePhase) Name() string {
method Kind (line 43) | func (p *ParsePhase) Kind() PhaseKind {
method Run (line 48) | func (p *ParsePhase) Run(ctx context.Context, l log.Logger, input *Pha...
method parseAndReclassify (line 130) | func (p *ParsePhase) parseAndReclassify(
function NewParsePhase (line 29) | func NewParsePhase(numWorkers int) *ParsePhase {
function parseComponent (line 193) | func parseComponent(
FILE: internal/discovery/phase_relationship.go
type RelationshipPhase (line 18) | type RelationshipPhase struct
method Name (line 48) | func (p *RelationshipPhase) Name() string {
method Kind (line 53) | func (p *RelationshipPhase) Kind() PhaseKind {
method Run (line 58) | func (p *RelationshipPhase) Run(ctx context.Context, l log.Logger, inp...
method runRelationshipDiscovery (line 67) | func (p *RelationshipPhase) runRelationshipDiscovery(
method discoverRelationships (line 134) | func (p *RelationshipPhase) discoverRelationships(
method dependencyToDiscover (line 236) | func (p *RelationshipPhase) dependencyToDiscover(
type relationshipTraversalState (line 26) | type relationshipTraversalState struct
function NewRelationshipPhase (line 34) | func NewRelationshipPhase(numWorkers, maxDepth int) *RelationshipPhase {
type terminalTracker (line 275) | type terminalTracker struct
method remove (line 286) | func (t *terminalTracker) remove(path string) {
method isEmpty (line 295) | func (t *terminalTracker) isEmpty() bool {
function newTerminalTracker (line 280) | func newTerminalTracker(components component.Components) *terminalTracker {
FILE: internal/discovery/phase_test.go
function TestFilesystemPhase_BasicDiscovery (line 19) | func TestFilesystemPhase_BasicDiscovery(t *testing.T) {
function TestFilesystemPhase_SkipsIgnorableDirs (line 69) | func TestFilesystemPhase_SkipsIgnorableDirs(t *testing.T) {
function TestFilesystemPhase_WithNoHidden (line 106) | func TestFilesystemPhase_WithNoHidden(t *testing.T) {
function TestParsePhase_ParsesConfigsForParseRequiredFilters (line 154) | func TestParsePhase_ParsesConfigsForParseRequiredFilters(t *testing.T) {
function TestGraphPhase_DependencyDiscovery (line 201) | func TestGraphPhase_DependencyDiscovery(t *testing.T) {
function TestGraphPhase_DependentDiscoveryRequiresRelationships (line 278) | func TestGraphPhase_DependentDiscoveryRequiresRelationships(t *testing.T) {
function TestRelationshipPhase_BuildsRelationships (line 341) | func TestRelationshipPhase_BuildsRelationships(t *testing.T) {
function TestCandidacyClassifier_AnalyzesFiltersCorrectly (line 402) | func TestCandidacyClassifier_AnalyzesFiltersCorrectly(t *testing.T) {
function TestCandidacyClassifier_ClassifiesComponentsCorrectly (line 507) | func TestCandidacyClassifier_ClassifiesComponentsCorrectly(t *testing.T) {
function TestClassifier_ParseExpressions (line 619) | func TestClassifier_ParseExpressions(t *testing.T) {
function TestClassifier_NegatedExpressions (line 634) | func TestClassifier_NegatedExpressions(t *testing.T) {
function TestClassifier_HasDependentFilters (line 649) | func TestClassifier_HasDependentFilters(t *testing.T) {
function TestGraphPhase_DependentDiscovery_WithPreBuiltGraph (line 707) | func TestGraphPhase_DependentDiscovery_WithPreBuiltGraph(t *testing.T) {
FILE: internal/discovery/phase_worktree.go
type WorktreePhase (line 27) | type WorktreePhase struct
method Name (line 47) | func (p *WorktreePhase) Name() string {
method Kind (line 52) | func (p *WorktreePhase) Kind() PhaseKind {
method NumWorkers (line 57) | func (p *WorktreePhase) NumWorkers() int {
method Run (line 62) | func (p *WorktreePhase) Run(ctx context.Context, l log.Logger, input *...
method discoverInWorktree (line 172) | func (p *WorktreePhase) discoverInWorktree(
method discoverChangesInWorktreeStacks (line 220) | func (p *WorktreePhase) discoverChangesInWorktreeStacks(
method walkChangedStack (line 271) | func (p *WorktreePhase) walkChangedStack(
function NewWorktreePhase (line 35) | func NewWorktreePhase(gitExpressions filter.GitExpressions, numWorkers i...
type ComponentPair (line 432) | type ComponentPair struct
function MatchComponentPairs (line 438) | func MatchComponentPairs(
type WorktreeKind (line 477) | type WorktreeKind
constant FromWorktreeKind (line 481) | FromWorktreeKind WorktreeKind = iota
constant ToWorktreeKind (line 483) | ToWorktreeKind
function TranslateDiscoveryContextArgsForWorktree (line 487) | func TranslateDiscoveryContextArgsForWorktree(
function GenerateDirSHA256 (line 524) | func GenerateDirSHA256(rootDir string) (string, error) {
FILE: internal/discovery/phase_worktree_integration_test.go
function TestWorktreePhase_Integration_UnitLifecycle (line 28) | func TestWorktreePhase_Integration_UnitLifecycle(t *testing.T) {
function TestWorktreePhase_Integration_CommandArgs (line 90) | func TestWorktreePhase_Integration_CommandArgs(t *testing.T) {
function TestWorktreePhase_Integration_EmptyFilters (line 273) | func TestWorktreePhase_Integration_EmptyFilters(t *testing.T) {
function TestWorktreePhase_Integration_EmptyDiffs (line 306) | func TestWorktreePhase_Integration_EmptyDiffs(t *testing.T) {
function TestWorktreePhase_Integration_Stacks (line 342) | func TestWorktreePhase_Integration_Stacks(t *testing.T) {
function TestWorktreePhase_Integration_FileRename (line 545) | func TestWorktreePhase_Integration_FileRename(t *testing.T) {
function TestWorktreePhase_Integration_FileMove (line 583) | func TestWorktreePhase_Integration_FileMove(t *testing.T) {
function TestWorktreePhase_Integration_NestedUnits (line 630) | func TestWorktreePhase_Integration_NestedUnits(t *testing.T) {
function TestWorktreePhase_Integration_MultipleGitExpressions (line 669) | func TestWorktreePhase_Integration_MultipleGitExpressions(t *testing.T) {
function TestWorktreePhase_Integration_GitFilterCombinedWithOtherFilters (line 707) | func TestWorktreePhase_Integration_GitFilterCombinedWithOtherFilters(t *...
function TestWorktreePhase_Integration_FromSubdirectory (line 850) | func TestWorktreePhase_Integration_FromSubdirectory(t *testing.T) {
function setupMultiCommitTestRepo (line 945) | func setupMultiCommitTestRepo(t *testing.T) string {
function TestWorktreePhase_Integration_NegatedGitGraphExpressions (line 1039) | func TestWorktreePhase_Integration_NegatedGitGraphExpressions(t *testing...
function TestWorktreePhase_Integration_FromSubdirectory_MultipleCommits (line 1206) | func TestWorktreePhase_Integration_FromSubdirectory_MultipleCommits(t *t...
function setupGitRepo (line 1310) | func setupGitRepo(t *testing.T) (string, *git.GitRunner) {
function commitChanges (line 1336) | func commitChanges(t *testing.T, runner *git.GitRunner, message string) {
function createUnit (line 1353) | func createUnit(t *testing.T, baseDir, unitName, content string) string {
function TestWorktreePhase_Integration_StackReadingChanges (line 1369) | func TestWorktreePhase_Integration_StackReadingChanges(t *testing.T) {
function TestWorktreePhase_Integration_StackReadingDedup (line 1539) | func TestWorktreePhase_Integration_StackReadingDedup(t *testing.T) {
function TestWorktreePhase_Integration_StackReadingNestedPath (line 1688) | func TestWorktreePhase_Integration_StackReadingNestedPath(t *testing.T) {
function runWorktreeDiscovery (line 1853) | func runWorktreeDiscovery(
FILE: internal/discovery/phase_worktree_test.go
function TestNewWorktreePhase (line 16) | func TestNewWorktreePhase(t *testing.T) {
function TestGenerateDirSHA256 (line 62) | func TestGenerateDirSHA256(t *testing.T) {
function TestMatchComponentPairs (line 237) | func TestMatchComponentPairs(t *testing.T) {
function TestTranslateDiscoveryContextArgsForWorktree (line 387) | func TestTranslateDiscoveryContextArgsForWorktree(t *testing.T) {
function TestWorktreeKind (line 540) | func TestWorktreeKind(t *testing.T) {
function createTestComponent (line 549) | func createTestComponent(path, workingDir string) component.Component {
function getRelativePath (line 559) | func getRelativePath(c component.Component) string {
FILE: internal/discovery/types.go
constant StatusDiscovered (line 28) | StatusDiscovered = filter.StatusDiscovered
constant StatusCandidate (line 29) | StatusCandidate = filter.StatusCandidate
constant StatusExcluded (line 30) | StatusExcluded = filter.StatusExcluded
constant CandidacyReasonNone (line 35) | CandidacyReasonNone = filter.CandidacyReasonNone
constant CandidacyReasonGraphTarget (line 36) | CandidacyReasonGraphTarget = filter.CandidacyReasonGraphTarget
constant CandidacyReasonRequiresParse (line 37) | CandidacyReasonRequiresParse = filter.CandidacyReasonRequiresParse
constant CandidacyReasonPotentialDependent (line 38) | CandidacyReasonPotentialDependent = filter.CandidacyReasonPotentialDepen...
type PhaseKind (line 42) | type PhaseKind
method String (line 60) | func (pk PhaseKind) String() string {
constant PhaseFilesystem (line 46) | PhaseFilesystem PhaseKind = iota
constant PhaseWorktree (line 48) | PhaseWorktree
constant PhaseParse (line 50) | PhaseParse
constant PhaseGraph (line 52) | PhaseGraph
constant PhaseRelationship (line 54) | PhaseRelationship
constant PhaseFinal (line 56) | PhaseFinal
type DiscoveryResult (line 80) | type DiscoveryResult struct
type PhaseResults (line 96) | type PhaseResults struct
method AddDiscovered (line 111) | func (pr *PhaseResults) AddDiscovered(result DiscoveryResult) {
method AddCandidate (line 119) | func (pr *PhaseResults) AddCandidate(result DiscoveryResult) {
function NewPhaseResults (line 106) | func NewPhaseResults() *PhaseResults {
type PhaseInput (line 127) | type PhaseInput struct
type Phase (line 136) | type Phase interface
type Discovery (line 146) | type Discovery struct
FILE: internal/engine/engine.go
constant engineVersion (line 44) | engineVersion = 1
constant engineCookieKey (line 45) | engineCookieKey = "engine"
constant engineCookieValue (line 46) | engineCookieValue = "terragrunt"
constant defaultCacheDir (line 48) | defaultCacheDir = ".cache"
constant defaultEngineCachePath (line 49) | defaultEngineCachePath = "terragrunt/plugins/iac-en...
constant prefixTrim (line 50) | prefixTrim = "terragrunt-"
constant fileNameFormat (line 51) | fileNameFormat = "terragrunt-iac-%s_%s_%s_%...
constant checksumFileNameFormat (line 52) | checksumFileNameFormat = "terragrunt-iac-%s_%s_%s_S...
constant engineLogLevelEnv (line 53) | engineLogLevelEnv = "TG_ENGINE_LOG_LEVEL"
constant defaultEngineRepoRoot (line 54) | defaultEngineRepoRoot = "github.com/"
constant terraformCommandContextKey (line 55) | terraformCommandContextKey engineClientsKey = iota
constant locksContextKey (line 56) | locksContextKey engineLocksKey = iota
constant latestVersionsContextKey (line 57) | latestVersionsContextKey engineLocksKey = iota
constant dirPerm (line 59) | dirPerm = 0755
constant errMsgEngineClientsFetch (line 61) | errMsgEngineClientsFetch = "failed to fetch engine clients from context"
constant errMsgEngineClientsCast (line 62) | errMsgEngineClientsCast = "failed to cast engine clients from context"
constant errMsgVersionsCacheFetch (line 63) | errMsgVersionsCacheFetch = "failed to fetch engine versions cache from c...
constant errMsgVersionsCacheCast (line 64) | errMsgVersionsCacheCast = "failed to cast engine versions cache from co...
type engineClientsKey (line 68) | type engineClientsKey
type engineLocksKey (line 69) | type engineLocksKey
type ExecutionOptions (line 72) | type ExecutionOptions struct
type engineInstance (line 87) | type engineInstance struct
function Run (line 94) | func Run(
function WithEngineValues (line 147) | func WithEngineValues(ctx context.Context) context.Context {
function downloadEngine (line 156) | func downloadEngine(ctx context.Context, l log.Logger, execOptions *Exec...
function lastReleaseVersion (line 263) | func lastReleaseVersion(ctx context.Context, opts *ExecutionOptions) (st...
function extractArchive (line 288) | func extractArchive(l log.Logger, downloadFile string, engineFile string...
function engineDir (line 348) | func engineDir(opts *ExecutionOptions) (string, error) {
function engineFileName (line 371) | func engineFileName(e *EngineConfig) string {
function engineChecksumName (line 386) | func engineChecksumName(e *EngineConfig) string {
function engineChecksumSigName (line 395) | func engineChecksumSigName(e *EngineConfig) string {
function enginePackageName (line 400) | func enginePackageName(e *EngineConfig) string {
function isArchiveByHeader (line 405) | func isArchiveByHeader(l log.Logger, filePath string) bool {
function engineClientsFromContext (line 412) | func engineClientsFromContext(ctx context.Context) (*sync.Map, error) {
function downloadLocksFromContext (line 427) | func downloadLocksFromContext(ctx context.Context) (*util.KeyLocks, erro...
function engineVersionsCacheFromContext (line 441) | func engineVersionsCacheFromContext(ctx context.Context) (*cache.Cache[s...
constant gracefulExitTimeout (line 456) | gracefulExitTimeout = 5 * time.Second
constant pluginExitPollInterval (line 457) | pluginExitPollInterval = 50 * time.Millisecond
function Shutdown (line 461) | func Shutdown(ctx context.Context, l log.Logger, experiments experiment....
function waitForPluginExit (line 504) | func waitForPluginExit(client *plugin.Client, timeout time.Duration) bool {
function logEngineMessage (line 525) | func logEngineMessage(l log.Logger, logLevel proto.LogLevel, content str...
function createEngine (line 542) | func createEngine(
function invoke (line 650) | func invoke(ctx context.Context, l log.Logger, runOptions *ExecutionOpti...
function processStream (line 774) | func processStream(data string, lineBuf *bytes.Buffer, output io.Writer)...
function flushBuffer (line 791) | func flushBuffer(lineBuf *bytes.Buffer, output io.Writer) error {
function initialize (line 804) | func initialize(ctx context.Context, l log.Logger, runOptions *Execution...
function shutdown (line 868) | func shutdown(ctx context.Context, l log.Logger, runOptions *ExecutionOp...
type OutputLine (line 933) | type OutputLine struct
type outputFn (line 938) | type outputFn
function ReadEngineOutput (line 942) | func ReadEngineOutput(runOptions *ExecutionOptions, forceStdErr bool, ou...
function ConvertMetaToProtobuf (line 979) | func ConvertMetaToProtobuf(meta map[string]any) (map[string]*anypb.Any, ...
function extract (line 1008) | func extract(l log.Logger, zipFile, destDir string) error {
function detectFileType (line 1078) | func detectFileType(l log.Logger, filePath string) (string, error) {
FILE: internal/engine/engine_test.go
function TestConvertMetaToProtobuf (line 13) | func TestConvertMetaToProtobuf(t *testing.T) {
function TestReadEngineOutput (line 27) | func TestReadEngineOutput(t *testing.T) {
FILE: internal/engine/public_keys.go
constant PublicKey (line 3) | PublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
FILE: internal/engine/types.go
type EngineOptions (line 4) | type EngineOptions struct
type EngineConfig (line 16) | type EngineConfig struct
FILE: internal/engine/verification.go
function verifyFile (line 17) | func verifyFile(checkedFile, checksumsFile, signatureFile string) error {
FILE: internal/errorconfig/types.go
type Config (line 19) | type Config struct
method AttemptErrorRecovery (line 69) | func (c *Config) AttemptErrorRecovery(l log.Logger, err error, current...
type RetryConfig (line 25) | type RetryConfig struct
type IgnoreConfig (line 33) | type IgnoreConfig struct
type Pattern (line 41) | type Pattern struct
type Action (line 47) | type Action struct
type MaxAttemptsReachedError (line 59) | type MaxAttemptsReachedError struct
method Error (line 64) | func (e *MaxAttemptsReachedError) Error() string {
function ExtractErrorMessage (line 125) | func ExtractErrorMessage(err error) string {
function MatchesAnyRegexpPattern (line 144) | func MatchesAnyRegexpPattern(input string, patterns []*Pattern) bool {
FILE: internal/errorconfig/types_test.go
function TestExtractErrorMessage_ExcludesCommandFlags (line 15) | func TestExtractErrorMessage_ExcludesCommandFlags(t *testing.T) {
function TestExtractErrorMessage_DoesNotFalselyMatchTimeout (line 40) | func TestExtractErrorMessage_DoesNotFalselyMatchTimeout(t *testing.T) {
function TestExtractErrorMessage_StillMatchesRealTimeout (line 69) | func TestExtractErrorMessage_StillMatchesRealTimeout(t *testing.T) {
function TestExtractErrorMessage_StillMatchesTimeoutInStderrWithFlags (line 94) | func TestExtractErrorMessage_StillMatchesTimeoutInStderrWithFlags(t *tes...
function TestExtractErrorMessage_NonProcessError (line 120) | func TestExtractErrorMessage_NonProcessError(t *testing.T) {
function TestErrorCleanPattern_PreservesCharacters (line 138) | func TestErrorCleanPattern_PreservesCharacters(t *testing.T) {
function TestMatchesAnyRegexpPattern_NoMatch (line 178) | func TestMatchesAnyRegexpPattern_NoMatch(t *testing.T) {
function TestMatchesAnyRegexpPattern_NegativePattern (line 190) | func TestMatchesAnyRegexpPattern_NegativePattern(t *testing.T) {
FILE: internal/errors/errors.go
constant newSkip (line 11) | newSkip = 2
constant errorfSkip (line 12) | errorfSkip = 2
function New (line 17) | func New(val any) error {
function Errorf (line 28) | func Errorf(format string, vals ...any) error {
function newWithSkip (line 32) | func newWithSkip(skip int, val any) error {
function errorfWithSkip (line 40) | func errorfWithSkip(skip int, format string, vals ...any) error {
FILE: internal/errors/export.go
function As (line 7) | func As(err error, target any) bool {
function Is (line 12) | func Is(err, target error) bool {
function Join (line 17) | func Join(errs ...error) error {
function Unwrap (line 24) | func Unwrap(err error) error {
FILE: internal/errors/multierror.go
type MultiError (line 11) | type MultiError struct
method WrappedErrors (line 16) | func (errs *MultiError) WrappedErrors() []error {
method Unwrap (line 24) | func (errs *MultiError) Unwrap() []error {
method ErrorOrNil (line 30) | func (errs *MultiError) ErrorOrNil() error {
method Append (line 44) | func (errs *MultiError) Append(appendErrs ...error) *MultiError {
method Len (line 57) | func (errs *MultiError) Len() int {
method Swap (line 70) | func (errs *MultiError) Swap(i, j int) {
method Less (line 75) | func (errs *MultiError) Less(i, j int) bool {
method Error (line 80) | func (errs *MultiError) Error() string {
function addIndent (line 98) | func addIndent(str string) string {
FILE: internal/errors/util.go
function ErrorStack (line 15) | func ErrorStack(err error) string {
function ContainsStackTrace (line 35) | func ContainsStackTrace(err error) bool {
function IsContextCanceled (line 52) | func IsContextCanceled(err error) bool {
function IsError (line 58) | func IsError(actual error, expected error) bool {
function Recover (line 64) | func Recover(onPanic func(cause error)) {
function UnwrapMultiErrors (line 76) | func UnwrapMultiErrors(err error) []error {
function UnwrapErrors (line 102) | func UnwrapErrors(err error) []error {
FILE: internal/experiment/errors.go
type InvalidExperimentNameError (line 8) | type InvalidExperimentNameError struct
method Error (line 18) | func (err InvalidExperimentNameError) Error() string {
method Is (line 22) | func (err InvalidExperimentNameError) Is(target error) bool {
function NewInvalidExperimentNameError (line 12) | func NewInvalidExperimentNameError(allowedNames []string) *InvalidExperi...
FILE: internal/experiment/experiment.go
constant Symlinks (line 18) | Symlinks = "symlinks"
constant CLIRedesign (line 20) | CLIRedesign = "cli-redesign"
constant Stacks (line 22) | Stacks = "stacks"
constant CAS (line 25) | CAS = "cas"
constant Report (line 27) | Report = "report"
constant RunnerPool (line 29) | RunnerPool = "runner-pool"
constant AutoProviderCacheDir (line 34) | AutoProviderCacheDir = "auto-provider-cache-dir"
constant FilterFlag (line 36) | FilterFlag = "filter-flag"
constant IacEngine (line 38) | IacEngine = "iac-engine"
constant DependencyFetchOutputFromState (line 41) | DependencyFetchOutputFromState = "dependency-fetch-output-from-state"
constant StatusOngoing (line 46) | StatusOngoing byte = iota
constant StatusCompleted (line 48) | StatusCompleted
type Experiments (line 51) | type Experiments
method Names (line 98) | func (exps Experiments) Names() []string {
method FilterByStatus (line 111) | func (exps Experiments) FilterByStatus(status byte) Experiments {
method Find (line 124) | func (exps Experiments) Find(name string) *Experiment {
method ExperimentMode (line 135) | func (exps Experiments) ExperimentMode() {
method EnableExperiment (line 144) | func (exps Experiments) EnableExperiment(name string) error {
method NotifyCompletedExperiments (line 156) | func (exps Experiments) NotifyCompletedExperiments(logger log.Logger) {
method Evaluate (line 173) | func (exps Experiments) Evaluate(name string) bool {
function NewExperiments (line 56) | func NewExperiments() Experiments {
type Experiment (line 183) | type Experiment struct
method String (line 192) | func (exps Experiment) String() string {
method Evaluate (line 199) | func (exps Experiment) Evaluate() bool {
FILE: internal/experiment/experiment_test.go
constant testOngoingA (line 17) | testOngoingA = "test-ongoing-a"
constant testOngoingB (line 18) | testOngoingB = "test-ongoing-b"
constant testCompletedA (line 19) | testCompletedA = "test-completed-a"
function newTestLogger (line 22) | func newTestLogger() (log.Logger, *bytes.Buffer) {
function TestValidateExperiments (line 30) | func TestValidateExperiments(t *testing.T) {
FILE: internal/experiment/warnings.go
type CompletedExperimentsWarning (line 8) | type CompletedExperimentsWarning struct
method String (line 18) | func (w CompletedExperimentsWarning) String() string {
function NewCompletedExperimentsWarning (line 12) | func NewCompletedExperimentsWarning(experimentsNames []string) *Complete...
FILE: internal/filter/ast.go
type Expression (line 12) | type Expression interface
type Expressions (line 30) | type Expressions
type PathExpression (line 33) | type PathExpression struct
method Glob (line 51) | func (p *PathExpression) Glob() glob.Glob {
method expressionNode (line 55) | func (p *PathExpression) expressionNode() {}
method String (line 56) | func (p *PathExpression) String() string { retu...
method RequiresDiscovery (line 57) | func (p *PathExpression) RequiresDiscovery() (Expression, bool) { retu...
method RequiresParse (line 58) | func (p *PathExpression) RequiresParse() (Expression, bool) { retu...
method IsRestrictedToStacks (line 59) | func (p *PathExpression) IsRestrictedToStacks() bool { retu...
method Negated (line 60) | func (p *PathExpression) Negated() Expression { retu...
function NewPathFilter (line 39) | func NewPathFilter(value string) (*PathExpression, error) {
type AttributeExpression (line 63) | type AttributeExpression struct
method Glob (line 99) | func (a *AttributeExpression) Glob() glob.Glob {
method supportsGlob (line 104) | func (a *AttributeExpression) supportsGlob() bool {
method expressionNode (line 108) | func (a *AttributeExpression) expressionNode() {}
method String (line 109) | func (a *AttributeExpression) String() string {...
method RequiresDiscovery (line 110) | func (a *AttributeExpression) RequiresDiscovery() (Expression, bool) {...
method RequiresParse (line 111) | func (a *AttributeExpression) RequiresParse() (Expression, bool) {
method IsRestrictedToStacks (line 125) | func (a *AttributeExpression) IsRestrictedToStacks() bool {
method Negated (line 128) | func (a *AttributeExpression) Negated() Expression {
function NewAttributeExpression (line 71) | func NewAttributeExpression(key string, value string) (*AttributeExpress...
function NewTypeExpression (line 94) | func NewTypeExpression(kind component.Kind) *AttributeExpression {
type PrefixExpression (line 133) | type PrefixExpression struct
method expressionNode (line 143) | func (p *PrefixExpression) expressionNode() {}
method String (line 144) | func (p *PrefixExpression) String() string { return p.Operator + p.Ri...
method RequiresDiscovery (line 145) | func (p *PrefixExpression) RequiresDiscovery() (Expression, bool) {
method RequiresParse (line 148) | func (p *PrefixExpression) RequiresParse() (Expression, bool) {
method IsRestrictedToStacks (line 151) | func (p *PrefixExpression) IsRestrictedToStacks() bool {
method Negated (line 169) | func (p *PrefixExpression) Negated() Expression {
function NewPrefixExpression (line 139) | func NewPrefixExpression(operator string, right Expression) *PrefixExpre...
type InfixExpression (line 179) | type InfixExpression struct
method expressionNode (line 190) | func (i *InfixExpression) expressionNode() {}
method String (line 191) | func (i *InfixExpression) String() string {
method RequiresDiscovery (line 194) | func (i *InfixExpression) RequiresDiscovery() (Expression, bool) {
method RequiresParse (line 205) | func (i *InfixExpression) RequiresParse() (Expression, bool) {
method IsRestrictedToStacks (line 216) | func (i *InfixExpression) IsRestrictedToStacks() bool {
method Negated (line 224) | func (i *InfixExpression) Negated() Expression {
function NewInfixExpression (line 186) | func NewInfixExpression(left Expression, operator string, right Expressi...
type GraphExpression (line 235) | type GraphExpression struct
method WithDependents (line 254) | func (g *GraphExpression) WithDependents() *GraphExpression {
method WithDependencies (line 260) | func (g *GraphExpression) WithDependencies() *GraphExpression {
method WithExcludeTarget (line 266) | func (g *GraphExpression) WithExcludeTarget() *GraphExpression {
method expressionNode (line 271) | func (g *GraphExpression) expressionNode() {}
method String (line 272) | func (g *GraphExpression) String() string {
method RequiresDiscovery (line 299) | func (g *GraphExpression) RequiresDiscovery() (Expression, bool) {
method RequiresParse (line 303) | func (g *GraphExpression) RequiresParse() (Expression, bool) {
method IsRestrictedToStacks (line 307) | func (g *GraphExpression) IsRestrictedToStacks() bool { return false }
method Negated (line 308) | func (g *GraphExpression) Negated() Expression {
function NewGraphExpression (line 247) | func NewGraphExpression(target Expression) *GraphExpression {
type GitExpression (line 314) | type GitExpression struct
method expressionNode (line 323) | func (g *GitExpression) expressionNode() {}
method String (line 324) | func (g *GitExpression) String() string {
method RequiresDiscovery (line 327) | func (g *GitExpression) RequiresDiscovery() (Expression, bool) {
method RequiresParse (line 331) | func (g *GitExpression) RequiresParse() (Expression, bool) {
method IsRestrictedToStacks (line 335) | func (g *GitExpression) IsRestrictedToStacks() bool { return false }
method Negated (line 336) | func (g *GitExpression) Negated() Expression {
function NewGitExpression (line 319) | func NewGitExpression(fromRef, toRef string) *GitExpression {
type GitExpressions (line 341) | type GitExpressions
method UniqueGitRefs (line 344) | func (e GitExpressions) UniqueGitRefs() []string {
FILE: internal/filter/ast_test.go
function TestRestrictToStacks (line 11) | func TestRestrictToStacks(t *testing.T) {
function mustPath (line 103) | func mustPath(t *testing.T, value string) *filter.PathExpression {
function mustAttr (line 112) | func mustAttr(t *testing.T, key, value string) *filter.AttributeExpressi...
FILE: internal/filter/candidacy.go
type GraphDirection (line 4) | type GraphDirection
method String (line 18) | func (d GraphDirection) String() string {
constant GraphDirectionNone (line 8) | GraphDirectionNone GraphDirection = iota
constant GraphDirectionDependencies (line 10) | GraphDirectionDependencies
constant GraphDirectionDependents (line 12) | GraphDirectionDependents
constant GraphDirectionBoth (line 14) | GraphDirectionBoth
function IsNegated (line 34) | func IsNegated(expr Expression) bool {
FILE: internal/filter/candidacy_test.go
function TestIsNegated (line 10) | func TestIsNegated(t *testing.T) {
function TestGraphDirection_String (line 80) | func TestGraphDirection_String(t *testing.T) {
FILE: internal/filter/classifier.go
type ClassificationStatus (line 10) | type ClassificationStatus
method String (line 22) | func (cs ClassificationStatus) String() string {
constant StatusDiscovered (line 14) | StatusDiscovered ClassificationStatus = iota
constant StatusCandidate (line 16) | StatusCandidate
constant StatusExcluded (line 18) | StatusExcluded
type CandidacyReason (line 36) | type CandidacyReason
method String (line 54) | func (cr CandidacyReason) String() string {
constant CandidacyReasonNone (line 40) | CandidacyReasonNone CandidacyReason = iota
constant CandidacyReasonGraphTarget (line 43) | CandidacyReasonGraphTarget
constant CandidacyReasonRequiresParse (line 46) | CandidacyReasonRequiresParse
constant CandidacyReasonPotentialDependent (line 50) | CandidacyReasonPotentialDependent
type ClassificationContext (line 70) | type ClassificationContext struct
type GraphExpressionInfo (line 76) | type GraphExpressionInfo struct
type Classifier (line 99) | type Classifier struct
method Classify (line 142) | func (c *Classifier) Classify(comp component.Component, classCtx Class...
method analyzeExpression (line 192) | func (c *Classifier) analyzeExpression(expr Expression, filterIndex in...
method extractNegatedGraphExpressions (line 249) | func (c *Classifier) extractNegatedGraphExpressions(expr Expression, f...
method matchesAnyNegated (line 271) | func (c *Classifier) matchesAnyNegated(comp component.Component) bool {
method matchesAnyPositive (line 278) | func (c *Classifier) matchesAnyPositive(comp component.Component, clas...
method matchesGitExpression (line 302) | func (c *Classifier) matchesGitExpression(comp component.Component) bo...
method matchesFilesystemExpression (line 314) | func (c *Classifier) matchesFilesystemExpression(comp component.Compon...
method matchesGraphExpressionTarget (line 323) | func (c *Classifier) matchesGraphExpressionTarget(comp component.Compo...
method matchesNegatedGraphExpressionTarget (line 342) | func (c *Classifier) matchesNegatedGraphExpressionTarget(comp componen...
method GraphExpressions (line 359) | func (c *Classifier) GraphExpressions() []*GraphExpressionInfo {
method HasPositiveFilters (line 364) | func (c *Classifier) HasPositiveFilters() bool {
method HasParseRequiredFilters (line 369) | func (c *Classifier) HasParseRequiredFilters() bool {
method HasGraphFilters (line 374) | func (c *Classifier) HasGraphFilters() bool {
method HasDependentFilters (line 381) | func (c *Classifier) HasDependentFilters() bool {
method ParseExpressions (line 388) | func (c *Classifier) ParseExpressions() []Expression {
method NegatedExpressions (line 393) | func (c *Classifier) NegatedExpressions() []Expression {
function NewClassifier (line 111) | func NewClassifier(filters Filters) *Classifier {
FILE: internal/filter/classifier_test.go
function TestClassifier_NegatedGraphExpression_HasGraphFilters (line 12) | func TestClassifier_NegatedGraphExpression_HasGraphFilters(t *testing.T) {
function TestClassifier_NegatedGraphExpression_IsNegatedFlag (line 76) | func TestClassifier_NegatedGraphExpression_IsNegatedFlag(t *testing.T) {
function TestClassifier_MixedNegatedAndNonNegatedGraphFilters (line 127) | func TestClassifier_MixedNegatedAndNonNegatedGraphFilters(t *testing.T) {
function TestClassifier_NestedNegatedGraphExpression (line 155) | func TestClassifier_NestedNegatedGraphExpression(t *testing.T) {
function TestClassifier_NegatedBidirectionalGraphExpression (line 178) | func TestClassifier_NegatedBidirectionalGraphExpression(t *testing.T) {
function TestClassifier_Classify (line 201) | func TestClassifier_Classify(t *testing.T) {
function TestClassifier_Classify_StatusString (line 404) | func TestClassifier_Classify_StatusString(t *testing.T) {
function TestClassifier_Classify_CandidacyReasonString (line 425) | func TestClassifier_Classify_CandidacyReasonString(t *testing.T) {
function newTestComponent (line 447) | func newTestComponent(path string) component.Component {
function newTestComponentWithRef (line 453) | func newTestComponentWithRef(path, ref string) component.Component {
FILE: internal/filter/complex_test.go
function TestParser_ComplexDepthExpressions (line 12) | func TestParser_ComplexDepthExpressions(t *testing.T) {
FILE: internal/filter/diagnostic.go
constant ansiReset (line 10) | ansiReset = "\033[0m"
constant ansiBold (line 11) | ansiBold = "\033[1m"
constant ansiRed (line 12) | ansiRed = "\033[31m"
constant ansiBlue (line 13) | ansiBlue = "\033[34m"
constant ansiCyan (line 14) | ansiCyan = "\033[36m"
function FormatDiagnostic (line 32) | func FormatDiagnostic(err *ParseError, filterIndex int, useColor bool) s...
FILE: internal/filter/diagnostic_test.go
function testLoggerForDiagnostics (line 14) | func testLoggerForDiagnostics() log.Logger {
function TestFormatDiagnostic_UnexpectedToken (line 21) | func TestFormatDiagnostic_UnexpectedToken(t *testing.T) {
function TestFormatDiagnostic_WithFilterIndex (line 49) | func TestFormatDiagnostic_WithFilterIndex(t *testing.T) {
function TestFormatDiagnostic_MissingClosingBracket (line 68) | func TestFormatDiagnostic_MissingClosingBracket(t *testing.T) {
function TestFormatDiagnostic_EmptyGitFilter (line 91) | func TestFormatDiagnostic_EmptyGitFilter(t *testing.T) {
function TestFormatDiagnostic_WithColor (line 112) | func TestFormatDiagnostic_WithColor(t *testing.T) {
function TestFormatDiagnostic_NoColor (line 131) | func TestFormatDiagnostic_NoColor(t *testing.T) {
function TestGetHint_CaretAfterIdentifier (line 150) | func TestGetHint_CaretAfterIdentifier(t *testing.T) {
function TestGetHint_CaretAtStart (line 160) | func TestGetHint_CaretAtStart(t *testing.T) {
function TestGetHint_MissingClosingBracket (line 169) | func TestGetHint_MissingClosingBracket(t *testing.T) {
function TestGetHint_MissingClosingBrace (line 178) | func TestGetHint_MissingClosingBrace(t *testing.T) {
function TestGetHint_EmptyGitFilter (line 187) | func TestGetHint_EmptyGitFilter(t *testing.T) {
function TestGetHint_PipeOperator (line 195) | func TestGetHint_PipeOperator(t *testing.T) {
function TestParseFilterQueries_RichDiagnostics (line 204) | func TestParseFilterQueries_RichDiagnostics(t *testing.T) {
function TestParseFilterQueries_MultipleErrors (line 221) | func TestParseFilterQueries_MultipleErrors(t *testing.T) {
function TestParseFilterQueries_ValidFilters (line 238) | func TestParseFilterQueries_ValidFilters(t *testing.T) {
function TestParseFilterQueries_EmptyInput (line 247) | func TestParseFilterQueries_EmptyInput(t *testing.T) {
FILE: internal/filter/errors.go
type ErrorCode (line 10) | type ErrorCode
constant ErrorCodeUnknown (line 13) | ErrorCodeUnknown ErrorCode = iota
constant ErrorCodeUnexpectedToken (line 14) | ErrorCodeUnexpectedToken
constant ErrorCodeUnexpectedEOF (line 15) | ErrorCodeUnexpectedEOF
constant ErrorCodeEmptyExpression (line 16) | ErrorCodeEmptyExpression
constant ErrorCodeMissingClosingBracket (line 17) | ErrorCodeMissingClosingBracket
constant ErrorCodeMissingClosingBrace (line 18) | ErrorCodeMissingClosingBrace
constant ErrorCodeIllegalToken (line 19) | ErrorCodeIllegalToken
constant ErrorCodeMissingOperand (line 20) | ErrorCodeMissingOperand
constant ErrorCodeEmptyGitFilter (line 21) | ErrorCodeEmptyGitFilter
constant ErrorCodeMissingGitRef (line 22) | ErrorCodeMissingGitRef
constant ErrorCodeInvalidGlob (line 23) | ErrorCodeInvalidGlob
type ParseError (line 27) | type ParseError struct
method Error (line 52) | func (e ParseError) Error() string {
function NewParseError (line 57) | func NewParseError(message string, position int) error {
function NewParseErrorWithContext (line 62) | func NewParseErrorWithContext(title, message string, position, errorPosi...
type EvaluationError (line 76) | type EvaluationError struct
method Error (line 81) | func (e EvaluationError) Error() string {
function NewEvaluationError (line 90) | func NewEvaluationError(message string) error {
function NewEvaluationErrorWithCause (line 95) | func NewEvaluationErrorWithCause(message string, cause error) error {
type FilterQueryRequiresDiscoveryError (line 100) | type FilterQueryRequiresDiscoveryError struct
method Error (line 104) | func (e FilterQueryRequiresDiscoveryError) Error() string {
FILE: internal/filter/evaluator.go
constant AttributeName (line 13) | AttributeName = "name"
constant AttributeType (line 14) | AttributeType = "type"
constant AttributeExternal (line 15) | AttributeExternal = "external"
constant AttributeReading (line 16) | AttributeReading = "reading"
constant AttributeSource (line 17) | AttributeSource = "source"
constant AttributeTypeValueUnit (line 19) | AttributeTypeValueUnit = string(component.UnitKind)
constant AttributeTypeValueStack (line 20) | AttributeTypeValueStack = string(component.StackKind)
constant AttributeExternalValueTrue (line 22) | AttributeExternalValueTrue = "true"
constant AttributeExternalValueFalse (line 23) | AttributeExternalValueFalse = "false"
constant MaxTraversalDepth (line 26) | MaxTraversalDepth = 1000000
type graphTraversalParams (line 30) | type graphTraversalParams struct
type EvaluationContext (line 38) | type EvaluationContext struct
function Evaluate (line 48) | func Evaluate(l log.Logger, expr Expression, components component.Compon...
function evaluatePathFilter (line 72) | func evaluatePathFilter(filter *PathExpression, components component.Com...
function evaluateAttributeFilter (line 85) | func evaluateAttributeFilter(filter *AttributeExpression, components []c...
function evaluatePrefixExpression (line 177) | func evaluatePrefixExpression(l log.Logger, expr *PrefixExpression, comp...
function evaluateInfixExpression (line 216) | func evaluateInfixExpression(l log.Logger, expr *InfixExpression, compon...
function evaluateGraphExpression (line 235) | func evaluateGraphExpression(l log.Logger, expr *GraphExpression, compon...
function evaluateGitFilter (line 312) | func evaluateGitFilter(filter *GitExpression, components component.Compo...
function traverseGraph (line 333) | func traverseGraph(
FILE: internal/filter/evaluator_test.go
function TestEvaluate_PathFilter (line 15) | func TestEvaluate_PathFilter(t *testing.T) {
function TestEvaluate_AttributeFilter (line 112) | func TestEvaluate_AttributeFilter(t *testing.T) {
function TestEvaluate_AttributeFilter_InvalidKey (line 179) | func TestEvaluate_AttributeFilter_InvalidKey(t *testing.T) {
function TestEvaluate_AttributeFilter_Reading (line 195) | func TestEvaluate_AttributeFilter_Reading(t *testing.T) {
function TestEvaluate_AttributeFilter_Source (line 294) | func TestEvaluate_AttributeFilter_Source(t *testing.T) {
function TestEvaluate_AttributeFilter_Reading_ComponentAddedOnlyOnce (line 355) | func TestEvaluate_AttributeFilter_Reading_ComponentAddedOnlyOnce(t *test...
function TestEvaluate_PrefixExpression (line 373) | func TestEvaluate_PrefixExpression(t *testing.T) {
function TestEvaluate_InfixExpression (line 472) | func TestEvaluate_InfixExpression(t *testing.T) {
function TestEvaluate_ComplexExpressions (line 552) | func TestEvaluate_ComplexExpressions(t *testing.T) {
function TestEvaluate_EdgeCases (line 653) | func TestEvaluate_EdgeCases(t *testing.T) {
function TestEvaluate_GraphExpression (line 687) | func TestEvaluate_GraphExpression(t *testing.T) {
function TestEvaluate_GraphExpression_ComplexGraph (line 857) | func TestEvaluate_GraphExpression_ComplexGraph(t *testing.T) {
function TestEvaluate_GraphExpression_EmptyResults (line 938) | func TestEvaluate_GraphExpression_EmptyResults(t *testing.T) {
function TestEvaluate_GraphExpression_NoDependencies (line 963) | func TestEvaluate_GraphExpression_NoDependencies(t *testing.T) {
function TestEvaluate_GraphExpression_CircularDependencies (line 1005) | func TestEvaluate_GraphExpression_CircularDependencies(t *testing.T) {
function TestEvaluate_GraphExpression_WithPathFilter (line 1058) | func TestEvaluate_GraphExpression_WithPathFilter(t *testing.T) {
function TestEvaluate_GraphExpression_DepthLimited (line 1099) | func TestEvaluate_GraphExpression_DepthLimited(t *testing.T) {
function TestEvaluate_GraphExpression_DepthLimited_MultipleTargets (line 1201) | func TestEvaluate_GraphExpression_DepthLimited_MultipleTargets(t *testin...
function TestEvaluate_GitFilter (line 1253) | func TestEvaluate_GitFilter(t *testing.T) {
function TestEvaluate_GitFilterString (line 1435) | func TestEvaluate_GitFilterString(t *testing.T) {
function TestGitFilter_RequiresDiscovery (line 1464) | func TestGitFilter_RequiresDiscovery(t *testing.T) {
function TestGitFilter_RequiresParse (line 1474) | func TestGitFilter_RequiresParse(t *testing.T) {
function TestEvaluate_GraphExpressionWithGitExpressionTarget (line 1489) | func TestEvaluate_GraphExpressionWithGitExpressionTarget(t *testing.T) {
function TestEvaluate_GraphExpressionWithGitTarget_DependencyChain (line 1817) | func TestEvaluate_GraphExpressionWithGitTarget_DependencyChain(t *testin...
FILE: internal/filter/examples_test.go
function exampleLogger (line 15) | func exampleLogger() log.Logger {
function Example_basicPathFilter (line 23) | func Example_basicPathFilter() {
function Example_attributeFilter (line 48) | func Example_attributeFilter() {
function Example_exclusionFilter (line 72) | func Example_exclusionFilter() {
function Example_intersectionFilter (line 97) | func Example_intersectionFilter() {
function Example_complexQuery (line 125) | func Example_complexQuery() {
function Example_parseAndEvaluate (line 156) | func Example_parseAndEvaluate() {
function Example_recursiveWildcard (line 187) | func Example_recursiveWildcard() {
function Example_errorHandling (line 214) | func Example_errorHandling() {
function Example_multipleFilters (line 233) | func Example_multipleFilters() {
FILE: internal/filter/filter.go
type Filter (line 9) | type Filter struct
method String (line 37) | func (f *Filter) String() string {
method Evaluate (line 43) | func (f *Filter) Evaluate(l log.Logger, components component.Component...
method Expression (line 49) | func (f *Filter) Expression() Expression {
method RequiresParse (line 54) | func (f *Filter) RequiresParse() (Expression, bool) {
method Negated (line 61) | func (f *Filter) Negated() *Filter {
function Parse (line 16) | func Parse(filterString string) (*Filter, error) {
function NewFilter (line 32) | func NewFilter(expr Expression, originalQuery string) *Filter {
function Apply (line 81) | func Apply(l log.Logger, filterString string, components component.Compo...
FILE: internal/filter/filter_test.go
function TestFilter_ParseAndEvaluate (line 38) | func TestFilter_ParseAndEvaluate(t *testing.T) {
function TestFilter_Apply (line 195) | func TestFilter_Apply(t *testing.T) {
function TestFilter_Expression (line 264) | func TestFilter_Expression(t *testing.T) {
function TestFilter_RealWorldScenarios (line 281) | func TestFilter_RealWorldScenarios(t *testing.T) {
function TestFilter_EdgeCasesAndErrorHandling (line 358) | func TestFilter_EdgeCasesAndErrorHandling(t *testing.T) {
FILE: internal/filter/filters.go
type Filters (line 17) | type Filters
method HasPositiveFilter (line 64) | func (f Filters) HasPositiveFilter() bool {
method RequiresDiscovery (line 75) | func (f Filters) RequiresDiscovery() (Expression, bool) {
method RequiresParse (line 86) | func (f Filters) RequiresParse() (Expression, bool) {
method DependencyGraphExpressions (line 97) | func (f Filters) DependencyGraphExpressions() []Expression {
method DependentGraphExpressions (line 108) | func (f Filters) DependentGraphExpressions() []Expression {
method UniqueGitFilters (line 119) | func (f Filters) UniqueGitFilters() GitExpressions {
method RestrictToStacks (line 141) | func (f Filters) RestrictToStacks() Filters {
method Evaluate (line 217) | func (f Filters) Evaluate(l log.Logger, components component.Component...
method EvaluateOnFiles (line 286) | func (f Filters) EvaluateOnFiles(l log.Logger, files []string, working...
method String (line 337) | func (f Filters) String() string {
function ParseFilterQueries (line 23) | func ParseFilterQueries(l log.Logger, filterStrings []string) (Filters, ...
function collectGraphExpressionTargetsWithDependencies (line 152) | func collectGraphExpressionTargetsWithDependencies(expr Expression) []Ex...
function collectGraphExpressionTargetsWithDependents (line 167) | func collectGraphExpressionTargetsWithDependents(expr Expression) []Expr...
function collectWorktreeExpressions (line 182) | func collectWorktreeExpressions(expr Expression) []*GitExpression {
function collectGitReferences (line 197) | func collectGitReferences(expr Expression) []string {
function initialComponents (line 310) | func initialComponents(l log.Logger, positiveFilters []*Filter, componen...
FILE: internal/filter/filters_test.go
function testLogger (line 15) | func testLogger() log.Logger {
function TestFilters_ParseFilterQueries (line 22) | func TestFilters_ParseFilterQueries(t *testing.T) {
function TestFilters_Evaluate (line 109) | func TestFilters_Evaluate(t *testing.T) {
function TestFilters_HasPositiveFilter (line 317) | func TestFilters_HasPositiveFilter(t *testing.T) {
function TestFilters_String (line 377) | func TestFilters_String(t *testing.T) {
function TestFilters_RequiresDependencyDiscovery (line 405) | func TestFilters_RequiresDependencyDiscovery(t *testing.T) {
function TestFilters_RequiresDependentDiscovery (line 497) | func TestFilters_RequiresDependentDiscovery(t *testing.T) {
function TestFilters_RestrictToStacks (line 588) | func TestFilters_RestrictToStacks(t *testing.T) {
function TestFilters_RequiresGitReferences (line 632) | func TestFilters_RequiresGitReferences(t *testing.T) {
function TestFilters_GitExpressionAsGraphTarget (line 736) | func TestFilters_GitExpressionAsGraphTarget(t *testing.T) {
FILE: internal/filter/fuzz_test.go
function FuzzParse (line 11) | func FuzzParse(f *testing.F) {
function FuzzLexer (line 111) | func FuzzLexer(f *testing.F) {
function FuzzParser (line 184) | func FuzzParser(f *testing.F) {
FILE: internal/filter/hints.go
function GetHint (line 9) | func GetHint(code ErrorCode, token, query string, position int) string {
function getUnexpectedTokenHint (line 37) | func getUnexpectedTokenHint(token, query string, position int) string {
function getCaretHint (line 62) | func getCaretHint(query string, position int) string {
function getUnexpectedEOFHint (line 96) | func getUnexpectedEOFHint(query string) string {
function getMissingClosingBracketHint (line 111) | func getMissingClosingBracketHint(query string) string {
function getMissingClosingBraceHint (line 120) | func getMissingClosingBraceHint(query string) string {
FILE: internal/filter/hints_test.go
function TestHints_Golden (line 15) | func TestHints_Golden(t *testing.T) {
function TestHints_ErrorCodeCoverage (line 225) | func TestHints_ErrorCodeCoverage(t *testing.T) {
function TestHints_CaretContextualHints (line 400) | func TestHints_CaretContextualHints(t *testing.T) {
function TestHints_FormatDiagnosticStructure (line 442) | func TestHints_FormatDiagnosticStructure(t *testing.T) {
function TestHints_FilterIndexInDiagnostic (line 481) | func TestHints_FilterIndexInDiagnostic(t *testing.T) {
function stripTimestampPrefix (line 509) | func stripTimestampPrefix(s string) string {
function renderParseError (line 516) | func renderParseError(query string) (string, error) {
FILE: internal/filter/lexer.go
type Lexer (line 9) | type Lexer struct
method Input (line 26) | func (l *Lexer) Input() string {
method NextToken (line 31) | func (l *Lexer) NextToken() Token {
method readChar (line 138) | func (l *Lexer) readChar() {
method peekChar (line 153) | func (l *Lexer) peekChar() byte {
method skipWhitespace (line 162) | func (l *Lexer) skipWhitespace() {
method readIdentifier (line 172) | func (l *Lexer) readIdentifier() string {
method readAttributeValue (line 194) | func (l *Lexer) readAttributeValue() string {
method readPath (line 215) | func (l *Lexer) readPath(startPosition int) Token {
method containsSlashBeforeSpecialChar (line 237) | func (l *Lexer) containsSlashBeforeSpecialChar() bool {
function NewLexer (line 18) | func NewLexer(input string) *Lexer {
function isSpecialChar (line 256) | func isSpecialChar(ch byte) bool {
function isPathSeparator (line 261) | func isPathSeparator(ch byte) bool {
function isIdentifierChar (line 266) | func isIdentifierChar(ch byte) bool {
function isAttributeValueChar (line 272) | func isAttributeValueChar(ch byte) bool {
function isPathChar (line 277) | func isPathChar(ch byte) bool {
FILE: internal/filter/lexer_test.go
function TestLexer_SingleTokens (line 10) | func TestLexer_SingleTokens(t *testing.T) {
function TestLexer_ComplexQueries (line 244) | func TestLexer_ComplexQueries(t *testing.T) {
function TestLexer_EdgeCases (line 336) | func TestLexer_EdgeCases(t *testing.T) {
function TestTokenType_String (line 479) | func TestTokenType_String(t *testing.T) {
FILE: internal/filter/matcher.go
function MatchComponent (line 11) | func MatchComponent(c component.Component, expr Expression) bool {
function matchPath (line 49) | func matchPath(c component.Component, expr *PathExpression) bool {
function matchAttribute (line 75) | func matchAttribute(c component.Component, expr *AttributeExpression) bo...
function matchGit (line 117) | func matchGit(c component.Component, expr *GitExpression) bool {
FILE: internal/filter/parser.go
type Parser (line 9) | type Parser struct
method ParseExpression (line 46) | func (p *Parser) ParseExpression() (Expression, error) {
method createError (line 65) | func (p *Parser) createError(code ErrorCode, title, msg string) error {
method Errors (line 84) | func (p *Parser) Errors() []error {
method nextToken (line 89) | func (p *Parser) nextToken() {
method parseExpression (line 95) | func (p *Parser) parseExpression(precedence int) Expression {
method parsePrefixExpression (line 243) | func (p *Parser) parsePrefixExpression() Expression {
method parseInfixExpression (line 276) | func (p *Parser) parseInfixExpression(left Expression) Expression {
method parsePathFilter (line 299) | func (p *Parser) parsePathFilter() Expression {
method parseBracedPath (line 312) | func (p *Parser) parseBracedPath() Expression {
method parseAttributeFilter (line 352) | func (p *Parser) parseAttributeFilter() Expression {
method parseGitFilter (line 379) | func (p *Parser) parseGitFilter() Expression {
method expectPeek (line 448) | func (p *Parser) expectPeek(t TokenType) bool {
method curPrecedence (line 460) | func (p *Parser) curPrecedence() int {
method addError (line 469) | func (p *Parser) addError(msg string) {
method addErrorWithCode (line 474) | func (p *Parser) addErrorWithCode(code ErrorCode, title, msg string) {
method addMissingOperandError (line 495) | func (p *Parser) addMissingOperandError(title, msg string) {
method addErrorAtPosition (line 515) | func (p *Parser) addErrorAtPosition(code ErrorCode, title, msg string,...
constant _ (line 19) | _ int = iota
constant LOWEST (line 20) | LOWEST
constant INTERSECTION (line 21) | INTERSECTION
constant PREFIX (line 22) | PREFIX
function NewParser (line 31) | func NewParser(lexer *Lexer) *Parser {
function isPurelyNumeric (line 212) | func isPurelyNumeric(s string) bool {
function parseDepth (line 228) | func parseDepth(literal string) int {
FILE: internal/filter/parser_test.go
function TestParser_SimpleExpressions (line 11) | func Test
Condensed preview — 4072 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,528K chars).
[
{
"path": ".coderabbit.yaml",
"chars": 1938,
"preview": "# https://docs.coderabbit.ai/guides/configure-coderabbit\nlanguage: \"en-US\"\nearly_access: false\nchat: { auto_reply: true "
},
{
"path": ".codespellrc",
"chars": 135,
"preview": "[codespell]\nskip = go.mod,go.sum,*.svg,Gemfile.lock,bun.lock,package-lock.json,node_modules,dist\nignore-words-list = dRa"
},
{
"path": ".gitattributes",
"chars": 107,
"preview": "# Ensure golden test files are not treated as text files to prevent line ending conversions\n*.golden -text\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 68,
"preview": "# These are supported funding model platforms\n\ngithub: gruntwork-io\n"
},
{
"path": ".github/ISSUE_TEMPLATE/01-bug_report.md",
"chars": 2161,
"preview": "---\nname: Bug report\nabout: Create a bug report to help us improve Terragrunt.\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n"
},
{
"path": ".github/ISSUE_TEMPLATE/02-bad_error_message.md",
"chars": 1236,
"preview": "---\nname: Bad Error Message Report\nabout: Report an error message that is unclear, unhelpful, or confusing to users.\ntit"
},
{
"path": ".github/ISSUE_TEMPLATE/03-rfc.yml",
"chars": 5453,
"preview": "# Inspired by:\n# - The previous RFC template.\n# - the OpenTofu RFC template: https://raw.githubusercontent.com/opentofu/"
},
{
"path": ".github/ISSUE_TEMPLATE/04-feature-request.md",
"chars": 737,
"preview": "---\nname: Enhancement\nabout: Request a simple feature or enhancement.\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n"
},
{
"path": ".github/assets/release-assets-config.json",
"chars": 1684,
"preview": "{\n \"platforms\": [\n {\n \"os\": \"darwin\",\n \"arch\": \"amd64\",\n \"signed\": true,\n \"binary\": \"terragrunt_"
},
{
"path": ".github/cloud-nuke/config.yml",
"chars": 302,
"preview": "s3:\n timeout: 1h\n include:\n names_regex:\n - \"^terragrunt-test-bucket-[a-zA-Z0-9]{6}.*\"\n\nvpc:\n include:\n na"
},
{
"path": ".github/dependabot.yml",
"chars": 1329,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/pull_request_template.md",
"chars": 1062,
"preview": "<!-- Prepend '[WIP]' to the title if this PR is still a work-in-progress. Remove it when it is ready for review! -->\n\n##"
},
{
"path": ".github/scripts/announce-release.sh",
"chars": 1888,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nURL=\"${URL:?Required environment variable URL}\"\nREPO=\"${REPO:?Required environme"
},
{
"path": ".github/scripts/gopls/check-for-changes.sh",
"chars": 297,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n: \"${HAS_FIXES:?}\"\n\nif [[ \"$HAS_FIXES\" != \"true\" ]]; then\n echo \"has_changes=fa"
},
{
"path": ".github/scripts/gopls/create-issue.js",
"chars": 1943,
"preview": "const fs = require('fs');\n\n/**\n * Creates a GitHub issue for gopls quickfix problems found\n * @param {Object} params - P"
},
{
"path": ".github/scripts/gopls/create-pr.js",
"chars": 2937,
"preview": "const fs = require('fs');\n\n/**\n * Creates a GitHub pull request for gopls quickfixes\n * @param {Object} params - Paramet"
},
{
"path": ".github/scripts/gopls/run.sh",
"chars": 1324,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nmise use -g go:golang.org/x/tools/gopls@v0.18.1\n\ngopls version\n\nTEMP_DIR=$(mktem"
},
{
"path": ".github/scripts/release/README.md",
"chars": 16675,
"preview": "# Release Scripts\n\nThis directory contains scripts used by the GitHub Actions release workflow to build, sign, and publi"
},
{
"path": ".github/scripts/release/check-release-exists.sh",
"chars": 1656,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to check if a GitHub release exists for a given tag\n# Usage: check-rele"
},
{
"path": ".github/scripts/release/create-archives.sh",
"chars": 1187,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to create ZIP and TAR.GZ archives for each binary\n# Usage: create-archi"
},
{
"path": ".github/scripts/release/generate-checksums.sh",
"chars": 723,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to generate SHA256 checksums for all release files\n# Usage: generate-ch"
},
{
"path": ".github/scripts/release/generate-upload-summary.sh",
"chars": 1876,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to generate GitHub Actions step summary for release uploads\n# Usage: ge"
},
{
"path": ".github/scripts/release/get-version.sh",
"chars": 1719,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to get the version from either workflow dispatch input or git ref\n# Usa"
},
{
"path": ".github/scripts/release/install-go-winres.ps1",
"chars": 807,
"preview": "# Script to install go-winres tool\n# Usage: install-go-winres.ps1\n\n$ErrorActionPreference = 'Stop'\n\nWrite-Host \"Installi"
},
{
"path": ".github/scripts/release/install-gon.sh",
"chars": 2028,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to download and install gon binary for macOS code signing\n# Usage: inst"
},
{
"path": ".github/scripts/release/lib-release-config.sh",
"chars": 2291,
"preview": "#!/usr/bin/env bash\n\n# Library script to read release assets configuration\n# Usage: source .github/scripts/release/lib-r"
},
{
"path": ".github/scripts/release/prepare-macos-artifacts.sh",
"chars": 903,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to prepare macOS artifacts for signing\n# Usage: prepare-macos-artifacts"
},
{
"path": ".github/scripts/release/prepare-windows-artifacts.ps1",
"chars": 1064,
"preview": "# Script to prepare Windows artifacts for signing\n# Usage: prepare-windows-artifacts.ps1 -ArtifactsDirectory <path> -Bin"
},
{
"path": ".github/scripts/release/restore-p12-certificate.ps1",
"chars": 1367,
"preview": "# Script to restore P12 client certificate from base64\n# Usage: restore-p12-certificate.ps1\n# Environment variables:\n# "
},
{
"path": ".github/scripts/release/set-permissions.sh",
"chars": 1030,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to set execution permissions on binaries\n# Usage: set-permissions.sh <b"
},
{
"path": ".github/scripts/release/sign-checksums.sh",
"chars": 2381,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to sign SHA256SUMS with GPG and Cosign\n# Usage: sign-checksums.sh <bin-"
},
{
"path": ".github/scripts/release/sign-macos-binaries.sh",
"chars": 3693,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to sign macOS binaries using gon and Apple notarization\n# Usage: sign-m"
},
{
"path": ".github/scripts/release/sign-windows.ps1",
"chars": 13051,
"preview": "# Script to sign Windows binaries using DigiCert and patch with go-winres\n# Usage: sign-windows.ps1 -BinDirectory <path>"
},
{
"path": ".github/scripts/release/upload-assets.sh",
"chars": 1538,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to upload release assets to GitHub\n# Usage: upload-assets.sh <bin-direc"
},
{
"path": ".github/scripts/release/verify-assets-uploaded.sh",
"chars": 3176,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to verify all assets were uploaded to the GitHub release\n# Usage: verif"
},
{
"path": ".github/scripts/release/verify-binaries-downloaded.sh",
"chars": 1497,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to verify all expected binaries were downloaded\n# Usage: verify-binarie"
},
{
"path": ".github/scripts/release/verify-files.sh",
"chars": 1141,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to verify all required files are present before upload\n# Usage: verify-"
},
{
"path": ".github/scripts/release/verify-smctl.ps1",
"chars": 728,
"preview": "# Script to verify smctl installation\n# Usage: verify-smctl.ps1\n\n$ErrorActionPreference = 'Stop'\n\nWrite-Host \"Checking s"
},
{
"path": ".github/scripts/release/verify-static-binary.sh",
"chars": 2580,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Script to verify that binaries are statically linked\n# Usage: verify-static-bi"
},
{
"path": ".github/scripts/setup/cas.sh",
"chars": 155,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n: \"${ENV_FILE:?ENV_FILE is not set}\"\n\ntouch \"$ENV_FILE\"\n\nprintf \"export TG_EXPER"
},
{
"path": ".github/scripts/setup/engine.sh",
"chars": 429,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\nexport TOFU_ENGINE_VERSION=\"v0.0.20\"\nexport REPO=\"gruntwork-io/terragrunt-engine-"
},
{
"path": ".github/scripts/setup/experiment-mode.sh",
"chars": 159,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n: \"${ENV_FILE:?ENV_FILE is not set}\"\n\ntouch \"$ENV_FILE\"\n\nprintf \"export TG_EXPER"
},
{
"path": ".github/scripts/setup/gcp.sh",
"chars": 657,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n: \"${ENV_FILE:?ENV_FILE is not set}\"\n\ntouch \"$ENV_FILE\"\n\necho \"$GCLOUD_SERVICE_K"
},
{
"path": ".github/scripts/setup/generate-mocks.sh",
"chars": 60,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nmake generate-mocks\n"
},
{
"path": ".github/scripts/setup/generate-secrets.sh",
"chars": 3576,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Required environment variables\n: \"${NAME:?NAME is not set}\"\n: \"${ENV_FILE:?ENV"
},
{
"path": ".github/scripts/setup/mac-sign.sh",
"chars": 3229,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Apple certificate used to validate developer certificates https://www.apple.co"
},
{
"path": ".github/scripts/setup/provider-cache-server.sh",
"chars": 157,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n: \"${ENV_FILE:?ENV_FILE is not set}\"\n\ntouch \"$ENV_FILE\"\n\nprintf \"export TG_PROVI"
},
{
"path": ".github/scripts/setup/run-setup-scripts.sh",
"chars": 443,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Required environment variables\n: \"${ENV_FILE:?ENV_FILE is not set}\"\n\n# Optiona"
},
{
"path": ".github/scripts/setup/sops.sh",
"chars": 114,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\ngpg --import --no-tty --batch --yes ./test/fixtures/sops/test_pgp_key.asc\n"
},
{
"path": ".github/scripts/setup/ssh.sh",
"chars": 187,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nSSH_KEY=\"${GHA_DEPLOY_KEY:?Required environment variable GHA_DEPLOY_KEY}\"\n\nmkdir"
},
{
"path": ".github/scripts/setup/terraform-switch-latest.sh",
"chars": 116,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n# Install Terraform 1.14.4\n.github/scripts/setup/terraform-switch.sh 1.14.4\n"
},
{
"path": ".github/scripts/setup/terraform-switch.sh",
"chars": 337,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n: \"${ENV_FILE:?ENV_FILE is not set}\"\n\nif [[ $# -lt 1 ]]; then\n echo \"Usage: $0 "
},
{
"path": ".github/scripts/setup/tofu-switch.sh",
"chars": 202,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n: \"${ENV_FILE:?ENV_FILE is not set}\"\n\ntouch \"$ENV_FILE\"\n\nmise uninstall --all te"
},
{
"path": ".github/scripts/setup/windows-setup.ps1",
"chars": 627,
"preview": "git config --global core.compression 9\ngit config --system core.longpaths true\ngit config --global core.longpaths true\ng"
},
{
"path": ".github/workflows/announce-release.yml",
"chars": 918,
"preview": "name: Announce Release\non:\n release:\n # This is intentionally not `published` to avoid announcing pre-releases\n t"
},
{
"path": ".github/workflows/base-test.yml",
"chars": 4608,
"preview": "name: Base Tests\n\non:\n workflow_call:\n\njobs:\n test:\n name: Test (${{ matrix.os }})\n runs-on: ${{ matrix.os }}-la"
},
{
"path": ".github/workflows/build-no-proxy.yml",
"chars": 2708,
"preview": "name: Build Without Go Proxy\n\non:\n workflow_call:\n workflow_dispatch:\n\njobs:\n build-no-proxy:\n name: Build (${{ ma"
},
{
"path": ".github/workflows/build.yml",
"chars": 6740,
"preview": "name: Build\n\non:\n workflow_call:\n\njobs:\n detect_release:\n name: Detect if this is a release build\n runs-on: ubun"
},
{
"path": ".github/workflows/ci.yml",
"chars": 2348,
"preview": "name: CI\n\non:\n push:\n\nconcurrency:\n group: ci-${{ github.ref }}\n cancel-in-progress: ${{ github.ref != 'refs/heads/ma"
},
{
"path": ".github/workflows/cloud-nuke.yml",
"chars": 1541,
"preview": "name: Hourly Cloud Nuke\non:\n schedule:\n - cron: \"0 * * * *\" # Runs every hour\n workflow_dispatch:\n\n\njobs:\n run_clo"
},
{
"path": ".github/workflows/codespell.yml",
"chars": 632,
"preview": "name: Codespell\n\non:\n workflow_call:\n\njobs:\n codespell:\n name: Check Spelling\n runs-on: ubuntu-slim\n\n env:\n "
},
{
"path": ".github/workflows/flake.yml",
"chars": 2525,
"preview": "name: Flake\non:\n release:\n types: [prereleased]\n workflow_dispatch:\n\njobs:\n test:\n name: Flake Test (${{ matrix"
},
{
"path": ".github/workflows/fuzz.yml",
"chars": 1972,
"preview": "name: Fuzz\n\non:\n workflow_call:\n\njobs:\n fuzz:\n name: Fuzz Tests\n runs-on: ubuntu-latest\n env:\n MISE_PROF"
},
{
"path": ".github/workflows/go-mod-tidy-check.yml",
"chars": 962,
"preview": "name: Go Mod Tidy Check\n\non:\n workflow_call:\n\njobs:\n go-mod-tidy-check:\n name: Check go.mod and go.sum are tidy\n "
},
{
"path": ".github/workflows/gopls.yml",
"chars": 2830,
"preview": "name: Gopls Quickfix Check\n\non:\n schedule:\n - cron: '0 2 1 * *'\n\n workflow_dispatch:\n\njobs:\n gopls-quickfix:\n n"
},
{
"path": ".github/workflows/install-script-test.yml",
"chars": 685,
"preview": "name: Install Script Test\n\non:\n workflow_call:\n\njobs:\n install-script-test:\n name: Install Script Tests (${{ matrix"
},
{
"path": ".github/workflows/integration-test.yml",
"chars": 10837,
"preview": "name: Integration Tests\n\non:\n workflow_call:\n\njobs:\n test:\n name: Test (${{ matrix.integration.name }})\n runs-on"
},
{
"path": ".github/workflows/license-check.yml",
"chars": 1833,
"preview": "name: License Check\n\non:\n workflow_call:\n\njobs:\n license-check:\n name: License Check\n runs-on: ubuntu-slim\n e"
},
{
"path": ".github/workflows/lint.yml",
"chars": 5117,
"preview": "name: Lint\n\non:\n workflow_call:\n\njobs:\n lint:\n name: Lint (${{ matrix.os }})\n runs-on: ${{ matrix.os }}-latest\n "
},
{
"path": ".github/workflows/markdownlint.yml",
"chars": 412,
"preview": "name: Markdown Lint\n\non:\n workflow_call:\n\njobs:\n markdownlint:\n name: Run Lint\n runs-on: ubuntu-slim\n steps:\n"
},
{
"path": ".github/workflows/oidc-integration-test.yml",
"chars": 5590,
"preview": "# These tests require different top-level permissions\n# than the other integration tests, so we're keeping them\n# in a s"
},
{
"path": ".github/workflows/precommit.yml",
"chars": 1387,
"preview": "name: Pre-commit\n\non:\n workflow_call:\n\njobs:\n precommit:\n name: Run pre-commit hooks\n runs-on: ubuntu-latest\n "
},
{
"path": ".github/workflows/release.yml",
"chars": 3938,
"preview": "name: Release\n\non:\n push:\n tags:\n - 'v*'\n - 'alpha*'\n - 'beta*'\n workflow_dispatch:\n inputs:\n "
},
{
"path": ".github/workflows/sign-macos.yml",
"chars": 3295,
"preview": "name: Sign MacOS Binaries\n\non:\n workflow_dispatch:\n inputs:\n artifact-pattern:\n description: 'Pattern fo"
},
{
"path": ".github/workflows/sign-windows.yml",
"chars": 2825,
"preview": "name: Sign Windows Binaries\n\non:\n workflow_call:\n inputs:\n artifact_pattern:\n description: 'Pattern for "
},
{
"path": ".github/workflows/stale.yml",
"chars": 942,
"preview": "name: 'Close stale issues and PRs'\non:\n schedule:\n - cron: '30 1 * * *'\n\njobs:\n stale:\n permissions:\n conte"
},
{
"path": ".github/workflows/update-codified-remote-deps.yml",
"chars": 2241,
"preview": "name: Update Codified Remote Dependencies\n\non:\n schedule:\n - cron: '0 9 * * 1' # Every Monday at 9:00 UTC\n workflow"
},
{
"path": ".gitignore",
"chars": 296,
"preview": ".*.sw?\n.idea\nterragrunt.iml\nvendor\n.terraform\n.vscode\n*.tfstate\n*.tfstate.backup\n*.out\n.terragrunt-cache\n.bundle\n.ruby-v"
},
{
"path": ".golangci.yml",
"chars": 2742,
"preview": "version: \"2\"\nrun:\n go: \"1.26\"\n issues-exit-code: 1\n tests: true\noutput:\n formats:\n text:\n path: stdout\n "
},
{
"path": ".gon_amd64.hcl",
"chars": 455,
"preview": "# See https://github.com/gruntwork-io/terraform-aws-ci/blob/main/modules/sign-binary-helpers/\n# for further instructions"
},
{
"path": ".gon_arm64.hcl",
"chars": 455,
"preview": "# See https://github.com/gruntwork-io/terraform-aws-ci/blob/main/modules/sign-binary-helpers/\n# for further instructions"
},
{
"path": ".licensei.toml",
"chars": 316,
"preview": "approved = [\n \"apache-2.0\",\n \"bsd-2-clause\",\n \"bsd-3-clause\",\n \"isc\",\n \"mpl-2.0\",\n \"mit\",\n]\n\nignored = [\n \"github"
},
{
"path": ".markdownlint-cli2.yaml",
"chars": 210,
"preview": "config:\n # Disable line length limit\n MD013: false\n\n # Disable multiple headers with the same content\n MD024: false\n"
},
{
"path": ".pre-commit-config.yaml",
"chars": 183,
"preview": "repos:\n - repo: https://github.com/gruntwork-io/pre-commit\n rev: v0.1.29\n hooks:\n - id: tofu-fmt\n exc"
},
{
"path": ".sonarcloud.properties",
"chars": 247,
"preview": "# Source File Exclusions: Patterns used to exclude some source files from analysis.\nsonar.exclusions=**/*_test.go\n# Test"
},
{
"path": "CODEOWNERS",
"chars": 35,
"preview": "* @denis256 @thisguycodes @yhakbar\n"
},
{
"path": "KEYS",
"chars": 429,
"preview": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmDMEaWUgtBYJKwYBBAHaRw8BAQdA9b1hTzoHHbAYEqd4F+8hBnuw89vQ35F5gaWE\n9Tpns760NEdydW50d"
},
{
"path": "LICENSE.txt",
"chars": 1079,
"preview": "The MIT License (MIT)\nCopyright (c) 2016 Gruntwork, LLC\n\nPermission is hereby granted, free of charge, to any person obt"
},
{
"path": "Makefile",
"chars": 2200,
"preview": "GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)\n\nhelp:\n\t@echo \"Various utilities for managing the terragrunt repos"
},
{
"path": "README.md",
"chars": 1550,
"preview": "# Terragrunt\n\n[](h"
},
{
"path": "SECURITY.md",
"chars": 3018,
"preview": "# Reporting Security Issues\n\nGruntwork takes security seriously, and we value the input of independent security research"
},
{
"path": "docs/.gitignore",
"chars": 254,
"preview": "# build output\ndist/\n\n# generated types\n.astro/\n\n# dependencies\nnode_modules/\n\n# logs\nnpm-debug.log*\nyarn-debug.log*\nyar"
},
{
"path": "docs/.vercelignore",
"chars": 45,
"preview": "node_modules\n.env\n.env.local\n.env.production\n"
},
{
"path": "docs/README.md",
"chars": 1540,
"preview": "# Terragrunt Documentation\n\nThis is the documentation for Terragrunt (hosted at <https://docs.terragrunt.com>), built us"
},
{
"path": "docs/astro.config.mjs",
"chars": 12851,
"preview": "// @ts-check\nimport { defineConfig } from \"astro/config\";\n\nimport starlight from \"@astrojs/starlight\";\nimport sitemap fr"
},
{
"path": "docs/components.json",
"chars": 665,
"preview": "{\n \"_comment\": \"This file configures the shadcn/ui CLI for adding new components. Use 'npx shadcn@latest add [compone"
},
{
"path": "docs/mise.toml",
"chars": 22,
"preview": "[tools]\nbun = \"1.2.2\"\n"
},
{
"path": "docs/package.json",
"chars": 940,
"preview": "{\n \"name\": \"docs\",\n \"type\": \"module\",\n \"version\": \"0.0.1\",\n \"scripts\": {\n \"dev\": \"astro dev\",\n \"start\": \"astro"
},
{
"path": "docs/public/install",
"chars": 20057,
"preview": "#!/usr/bin/env bash\n# Terragrunt Installer\n#\n# Supported platforms: Linux, macOS (Darwin)\n# Supported architectures: x86"
},
{
"path": "docs/public/robots.txt",
"chars": 79,
"preview": "User-agent: *\nAllow: /\n\nSitemap: https://docs.terragrunt.com/sitemap-index.xml\n"
},
{
"path": "docs/public/schemas/auth-provider-cmd/v1/schema.json",
"chars": 1942,
"preview": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://terragrunt.gruntwork.io/schemas/auth-pr"
},
{
"path": "docs/public/schemas/auth-provider-cmd/v2/schema.json",
"chars": 1938,
"preview": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://docs.terragrunt.com/schemas/auth-provid"
},
{
"path": "docs/public/schemas/run/report/v1/schema.json",
"chars": 1222,
"preview": "{\n \"items\": {\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://terragrunt.gruntwork.i"
},
{
"path": "docs/public/schemas/run/report/v2/schema.json",
"chars": 1189,
"preview": "{\n \"items\": {\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://terragrunt.gruntwork.i"
},
{
"path": "docs/public/schemas/run/report/v3/schema.json",
"chars": 1393,
"preview": "{\n \"items\": {\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://terragrunt.gruntwork.i"
},
{
"path": "docs/public/schemas/run/report/v4/schema.json",
"chars": 1385,
"preview": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://docs.terragrunt.com/schemas/run/report/"
},
{
"path": "docs/src/assets/icons/terragrunt-icon-accent.astro",
"chars": 1140,
"preview": "---\n\n---\n\n<svg width=\"137\" height=\"138\" viewBox=\"0 0 137 138\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fi"
},
{
"path": "docs/src/components/Command.astro",
"chars": 1275,
"preview": "---\nimport { Aside, Code } from '@astrojs/starlight/components';\nimport { getEntry, render } from 'astro:content';\nimpor"
},
{
"path": "docs/src/components/CompactFooter.astro",
"chars": 1378,
"preview": "---\nimport GruntworkLogo from '@assets/gruntwork-logo.svg';\nimport { Image } from 'astro:assets';\nimport PatternDots fro"
},
{
"path": "docs/src/components/CompatibilityTable.astro",
"chars": 1014,
"preview": "---\nimport { getCollection } from 'astro:content';\n\ninterface Props {\n tool: 'opentofu' | 'terraform';\n}\n\nconst { tool "
},
{
"path": "docs/src/components/Flag.astro",
"chars": 1355,
"preview": "---\nimport { Badge } from '@astrojs/starlight/components';\nimport Card from '@components/vendored/starlight/Card.astro';"
},
{
"path": "docs/src/components/Header.astro",
"chars": 11213,
"preview": "---\nimport config from 'virtual:starlight/user-config';\nimport { Image } from 'astro:assets';\n// @ts-ignore\nimport Searc"
},
{
"path": "docs/src/components/InstallTab.astro",
"chars": 3344,
"preview": "---\nimport { TabItem } from '@astrojs/starlight/components';\nimport { Code } from '@astrojs/starlight/components';\n\ncons"
},
{
"path": "docs/src/components/InstallTabs.astro",
"chars": 626,
"preview": "---\nimport { Tabs } from '@astrojs/starlight/components';\nimport InstallTab from './InstallTab.astro';\n\nconst tabs = [\n\t"
},
{
"path": "docs/src/components/PageSidebar.astro",
"chars": 1166,
"preview": "---\nimport DefaultPageSidebar from '@astrojs/starlight/components/PageSidebar.astro';\nimport { Icon } from '@astrojs/sta"
},
{
"path": "docs/src/components/SectionSpacer.astro",
"chars": 46,
"preview": "---\n---\n\n<div class=\"w-full h-[150px]\"></div>\n"
},
{
"path": "docs/src/components/SiteTitle.astro",
"chars": 1454,
"preview": "---\nimport { logos } from 'virtual:starlight/user-images';\nimport config from 'virtual:starlight/user-config';\nimport ty"
},
{
"path": "docs/src/components/SkipLink.astro",
"chars": 133,
"preview": "---\nimport DefaultSkipLink from '@astrojs/starlight/components/SkipLink.astro';\n---\n\n<DefaultSkipLink>\n <slot />\n</Defa"
},
{
"path": "docs/src/components/ThemeToggle.astro",
"chars": 3688,
"preview": "---\n\nconst {\n className: customClass = \"\",\n id: uniqueId = `themeToggle-${Math.random().toString(36).substr(2, 9)}`\n} "
},
{
"path": "docs/src/components/dv-IconButton.astro",
"chars": 692,
"preview": "---\nimport '@styles/global.css';\nimport { Image } from \"astro:assets\";\nimport type { ImageMetadata } from 'astro';\n\ninte"
},
{
"path": "docs/src/components/ui/Button.tsx",
"chars": 3280,
"preview": "// Generated with 'npx shadcn@latest add button'\n// Customize this as needed!\n\nimport { cn } from \"../../lib/utils\";\nimp"
},
{
"path": "docs/src/components/ui/ButtonLink.tsx",
"chars": 1019,
"preview": "// A plain Button is often used as a link, so rather than wrapping plain button in an <a> tag, we can use this component"
},
{
"path": "docs/src/components/vendored/starlight/Card.astro",
"chars": 1710,
"preview": "---\nimport Icon from './Icon.astro';\nimport type { StarlightIcon } from './Icons';\n\ninterface Props {\n\ticon?: StarlightI"
},
{
"path": "docs/src/components/vendored/starlight/FileTree.astro",
"chars": 3412,
"preview": "---\nimport { processFileTree } from './rehype-file-tree';\n\nconst fileTreeHtml = await Astro.slots.render('default');\ncon"
},
{
"path": "docs/src/components/vendored/starlight/Icon.astro",
"chars": 892,
"preview": "---\nimport { Icons, type StarlightIcon } from './Icons';\n\ninterface Props {\n\tname: StarlightIcon;\n\tlabel?: string;\n\tcolo"
},
{
"path": "docs/src/components/vendored/starlight/Icons.ts",
"chars": 53882,
"preview": "import { FileIcons } from './file-tree-icons';\n\nexport const BuiltInIcons = {\n\t'up-caret':\n\t\t'<path d=\"m17 13.41-4.29-4."
},
{
"path": "docs/src/components/vendored/starlight/README.md",
"chars": 2270,
"preview": "# Vendored Starlight Components\n\nThis directory contains components vendored from `@astrojs/starlight` version 0.35.2.\n\n"
},
{
"path": "docs/src/components/vendored/starlight/file-tree-icons.ts",
"chars": 329216,
"preview": "/**\n * This file was generated by the `file-icons-generator` package.\n * Do not edit this file directly as it will be ov"
},
{
"path": "docs/src/components/vendored/starlight/rehype-file-tree.ts",
"chars": 8702,
"preview": "import { AstroError } from 'astro/errors';\nimport type { Element, ElementContent, Text } from 'hast';\nimport { type Chil"
},
{
"path": "docs/src/content/docs/01-getting-started/01-quick-start.mdx",
"chars": 28082,
"preview": "---\ntitle: Quick Start\ndescription: Start using Terragrunt today!\nslug: getting-started/quick-start\nsidebar:\n order: 1\n"
},
{
"path": "docs/src/content/docs/01-getting-started/02-overview.mdx",
"chars": 43461,
"preview": "---\ntitle: Overview\ndescription: Get a high level overview of the most important Terragrunt features.\nslug: getting-star"
},
{
"path": "docs/src/content/docs/01-getting-started/03-install.mdx",
"chars": 7390,
"preview": "---\ntitle: Install\ndescription: Install Terragrunt!\nslug: getting-started/install\nsidebar:\n order: 3\n---\n\nimport Instal"
},
{
"path": "docs/src/content/docs/01-getting-started/04-terminology.md",
"chars": 21710,
"preview": "---\ntitle: Terminology\ndescription: Quickly understand commonly use terms in Terragrunt.\nslug: getting-started/terminolo"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/01-introduction.md",
"chars": 3956,
"preview": "---\ntitle: Introduction\ndescription: Introduction to the Terralith to Terragrunt guide\nslug: guides/terralith-to-terragr"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/02-overview.md",
"chars": 3050,
"preview": "---\ntitle: Overview\ndescription: Overview of the Terralith to Terragrunt guide\nslug: guides/terralith-to-terragrunt/over"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/03-setup.mdx",
"chars": 4898,
"preview": "---\ntitle: Setup\ndescription: Setup of the Terralith to Terragrunt guide\nslug: guides/terralith-to-terragrunt/setup\nside"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/04-step-1-starting-the-terralith.mdx",
"chars": 11718,
"preview": "---\ntitle: \"Step 1: Starting the Terralith\"\ndescription: Starting the Terralith\nslug: guides/terralith-to-terragrunt/ste"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/05-step-2-refactoring.mdx",
"chars": 16961,
"preview": "---\ntitle: \"Step 2: Refactoring\"\ndescription: Refactoring\nslug: guides/terralith-to-terragrunt/step-2-refactoring\nsideba"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/06-step-3-adding-dev.mdx",
"chars": 10216,
"preview": "---\ntitle: \"Step 3: Adding dev\"\ndescription: Adding dev\nslug: guides/terralith-to-terragrunt/step-3-adding-dev\nsidebar:\n"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/07-step-4-breaking-the-terralith.mdx",
"chars": 12065,
"preview": "---\ntitle: \"Step 4: Breaking the Terralith\"\ndescription: Breaking the Terralith\nslug: guides/terralith-to-terragrunt/ste"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/08-step-5-adding-terragrunt.mdx",
"chars": 14702,
"preview": "---\ntitle: \"Step 5: Adding Terragrunt\"\ndescription: Adding Terragrunt\nslug: guides/terralith-to-terragrunt/step-5-adding"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/09-step-6-breaking-the-terralith-further.mdx",
"chars": 18633,
"preview": "---\ntitle: \"Step 6: Breaking the Terralith Further\"\ndescription: Breaking the Terralith Further\nslug: guides/terralith-t"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/10-step-7-taking-advantage-of-terragrunt-stacks.mdx",
"chars": 9612,
"preview": "---\ntitle: \"Step 7: Taking advantage of Terragrunt Stacks\"\ndescription: Taking advantage of Terragrunt Stacks\nslug: guid"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/11-step-8-refactoring-state-with-terragrunt-stacks.mdx",
"chars": 11053,
"preview": "---\ntitle: \"Step 8: Refactoring state with Terragrunt Stacks\"\ndescription: Refactoring state with Terragrunt Stacks\nslug"
},
{
"path": "docs/src/content/docs/02-guides/01-terralith-to-terragrunt/12-wrap-up.mdx",
"chars": 4754,
"preview": "---\ntitle: \"Wrap Up\"\ndescription: Wrap Up\nslug: guides/terralith-to-terragrunt/wrap-up\nsidebar:\n order: 12\nnext: false\n"
},
{
"path": "docs/src/content/docs/03-features/01-units/02-includes.mdx",
"chars": 15066,
"preview": "---\ntitle: Includes\ndescription: Learn how to reuse partial Terragrunt configurations to DRY up your configurations.\nslu"
},
{
"path": "docs/src/content/docs/03-features/01-units/03-state-backend.mdx",
"chars": 20319,
"preview": "---\ntitle: State Backend\ndescription: Learn how Terragrunt can create and manage remote state backends.\nslug: features/u"
},
{
"path": "docs/src/content/docs/03-features/01-units/04-extra-arguments.mdx",
"chars": 9231,
"preview": "---\ntitle: Extra Arguments\ndescription: Learn how to pass extra arguments to every OpenTofu/Terraform run.\nslug: feature"
},
{
"path": "docs/src/content/docs/03-features/01-units/05-authentication.mdx",
"chars": 15839,
"preview": "---\ntitle: Authentication\ndescription: Learn how Terragrunt helps you automate authentication workflows.\nslug: features/"
},
{
"path": "docs/src/content/docs/03-features/01-units/06-hooks.mdx",
"chars": 9128,
"preview": "---\ntitle: Hooks\ndescription: Learn how to execute custom code before or after running OpenTofu/Terraform, or when error"
},
{
"path": "docs/src/content/docs/03-features/01-units/07-auto-init.mdx",
"chars": 1903,
"preview": "---\ntitle: Auto-init\ndescription: Learn how Terragrunt makes it so that you don't have to explicitly call `init` when us"
},
{
"path": "docs/src/content/docs/03-features/01-units/08-runtime-control.mdx",
"chars": 9113,
"preview": "---\ntitle: Feature Flags, Errors and Excludes\ndescription: Learn how Terragrunt allows for runtime control using feature"
},
{
"path": "docs/src/content/docs/03-features/01-units/09-engine.mdx",
"chars": 4966,
"preview": "---\ntitle: IaC Engines\ndescription: Learn how to dynamically control OpenTofu/Terraform runs using IaC engines.\nslug: fe"
},
{
"path": "docs/src/content/docs/03-features/01-units/index.mdx",
"chars": 17560,
"preview": "---\ntitle: Units\ndescription: Learn how Terragrunt units result in atomic deployments and immutable infrastructure.\nslug"
},
{
"path": "docs/src/content/docs/03-features/02-stacks/02-implicit.mdx",
"chars": 3105,
"preview": "---\ntitle: Implicit Stacks\ndescription: Create stacks by organizing units in a directory structure.\nslug: features/stack"
},
{
"path": "docs/src/content/docs/03-features/02-stacks/03-explicit.mdx",
"chars": 11990,
"preview": "---\ntitle: Explicit Stacks\ndescription: Define stacks using terragrunt.stack.hcl files for reusable patterns.\nslug: feat"
},
{
"path": "docs/src/content/docs/03-features/02-stacks/04-stack-operations.mdx",
"chars": 19207,
"preview": "---\ntitle: Stack Operations\ndescription: Work with dependencies, visualize the DAG, control parallelism, and manage stac"
},
{
"path": "docs/src/content/docs/03-features/02-stacks/06-run-queue.mdx",
"chars": 9734,
"preview": "---\ntitle: Run Queue\ndescription: Learn how Terragrunt orchestrates multiple concurrent OpenTofu/Terraform runs.\nslug: f"
},
{
"path": "docs/src/content/docs/03-features/02-stacks/07-run-report.mdx",
"chars": 7273,
"preview": "---\ntitle: Run Report\ndescription: Learn how Terragrunt provides detailed reports of runs, and at-a-glance summaries of "
},
{
"path": "docs/src/content/docs/03-features/02-stacks/index.mdx",
"chars": 1901,
"preview": "---\ntitle: Stacks\ndescription: Learn how to work with multiple units at once using implicit and explicit stacks.\nslug: f"
},
{
"path": "docs/src/content/docs/03-features/06-catalog/02-tui.mdx",
"chars": 2622,
"preview": "---\ntitle: Catalog TUI\ndescription: Browse and search your module catalog with Terragrunt's interactive terminal UI.\nslu"
},
{
"path": "docs/src/content/docs/03-features/06-catalog/03-scaffold.mdx",
"chars": 8287,
"preview": "---\ntitle: Scaffold\ndescription: Learn how to scaffold Terragrunt units.\nslug: features/catalog/scaffold\nsidebar:\n orde"
},
{
"path": "docs/src/content/docs/03-features/06-catalog/index.mdx",
"chars": 2707,
"preview": "---\ntitle: Catalog\ndescription: Learn how to search, browse, and scaffold modules with Terragrunt's catalog ecosystem.\ns"
},
{
"path": "docs/src/content/docs/03-features/07-caching/02-provider-cache-server.mdx",
"chars": 11800,
"preview": "---\ntitle: Provider Cache Server\ndescription: Learn how to use the Terragrunt provider cache server.\nslug: features/cach"
},
{
"path": "docs/src/content/docs/03-features/07-caching/03-auto-provider-cache-dir.mdx",
"chars": 3923,
"preview": "---\ntitle: Automatic Provider Cache Dir\ndescription: Learn how Terragrunt automatically configures OpenTofu's native pro"
},
{
"path": "docs/src/content/docs/03-features/07-caching/04-cas.mdx",
"chars": 6213,
"preview": "---\ntitle: Content Addressable Store (CAS)\ndescription: Learn how Terragrunt supports deduplication of content using a C"
},
{
"path": "docs/src/content/docs/03-features/07-caching/index.mdx",
"chars": 671,
"preview": "---\ntitle: Caching\ndescription: Learn how Terragrunt optimizes performance through provider caching and content deduplic"
},
{
"path": "docs/src/content/docs/03-features/08-filter/02-name.mdx",
"chars": 856,
"preview": "---\ntitle: Name Expressions\ndescription: Match units and stacks by their name\nslug: features/filter/name\nsidebar:\n orde"
},
{
"path": "docs/src/content/docs/03-features/08-filter/03-path.mdx",
"chars": 1541,
"preview": "---\ntitle: Path Expressions\ndescription: Match units and stacks by their file system path\nslug: features/filter/path\nsid"
},
{
"path": "docs/src/content/docs/03-features/08-filter/04-attributes.mdx",
"chars": 5508,
"preview": "---\ntitle: Attribute Expressions\ndescription: Match units and stacks by their configuration attributes\nslug: features/fi"
},
{
"path": "docs/src/content/docs/03-features/08-filter/05-graph.mdx",
"chars": 5453,
"preview": "---\ntitle: Graph Expressions\ndescription: Filter units based on their dependency relationships using graph traversal ope"
},
{
"path": "docs/src/content/docs/03-features/08-filter/06-git.mdx",
"chars": 5830,
"preview": "---\ntitle: Git Expressions\ndescription: Filter units and stacks based on Git diffs using Git expressions\nslug: features/"
},
{
"path": "docs/src/content/docs/03-features/08-filter/07-combining.mdx",
"chars": 7870,
"preview": "---\ntitle: Combining Expressions\ndescription: Combine filter expressions using negation, intersection, and union operato"
},
{
"path": "docs/src/content/docs/03-features/08-filter/08-filters-file.mdx",
"chars": 1064,
"preview": "---\ntitle: Filters File\ndescription: Use a filters file to define reusable filter expressions for Terragrunt\nslug: featu"
},
{
"path": "docs/src/content/docs/03-features/08-filter/index.mdx",
"chars": 5863,
"preview": "---\ntitle: Overview\ndescription: Learn how to use the --filter flag to target specific infrastructure\nslug: features/fil"
},
{
"path": "docs/src/content/docs/04-reference/01-hcl/01-overview.mdx",
"chars": 10848,
"preview": "---\ntitle: Overview\ndescription: Learn how to configure Terragrunt\nslug: reference/hcl\nsidebar:\n order: 1\n---\n\nimport F"
},
{
"path": "docs/src/content/docs/04-reference/01-hcl/02-blocks.mdx",
"chars": 83348,
"preview": "---\ntitle: Blocks\ndescription: Learn about Terragrunt HCL configuration blocks\nslug: reference/hcl/blocks\nsidebar:\n ord"
},
{
"path": "docs/src/content/docs/04-reference/01-hcl/03-attributes.mdx",
"chars": 9142,
"preview": "---\ntitle: Attributes\ndescription: Learn about terragrunt hcl attributes\nslug: reference/hcl/attributes\nsidebar:\n order"
},
{
"path": "docs/src/content/docs/04-reference/01-hcl/04-functions.mdx",
"chars": 34361,
"preview": "---\ntitle: Functions\ndescription: Learn about the built-in functions available in Terragrunt.\nslug: reference/hcl/functi"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/01-overview.mdx",
"chars": 4412,
"preview": "---\ntitle: Overview\ndescription: Learn how the Terragrunt CLI works\nslug: reference/cli\nsidebar:\n order: 1\n---\n\nimport "
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/0-opentofu-shortcuts.md",
"chars": 444,
"preview": "---\ntitle: OpenTofu Shortcuts\ndescription: Interact with OpenTofu/Terraform backend infrastructure.\nslug: reference/cli/"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/0100-run.md",
"chars": 392,
"preview": "---\ntitle: run\ndescription: Run OpenTofu/Terraform commands.\nslug: reference/cli/commands/run\nsidebar:\n order: 100\n---\n"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/0200-exec.md",
"chars": 414,
"preview": "---\ntitle: exec\ndescription: Execute an arbitrary command, wrapped by Terragrunt.\nslug: reference/cli/commands/exec\nside"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/0500-catalog.md",
"chars": 452,
"preview": "---\ntitle: catalog\ndescription: Launch a Terminal User Interface (TUI) to browse and use OpenTofu/Terraform modules.\nslu"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/0600-scaffold.md",
"chars": 425,
"preview": "---\ntitle: scaffold\ndescription: Generate Terragrunt configuration files from a catalog.\nslug: reference/cli/commands/sc"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/0700-find.md",
"chars": 402,
"preview": "---\ntitle: find\ndescription: Find relevant Terragrunt configurations.\nslug: reference/cli/commands/find\nsidebar:\n order"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/0800-list.md",
"chars": 393,
"preview": "---\ntitle: list\ndescription: List Terragrunt configurations.\nslug: reference/cli/commands/list\nsidebar:\n order: 800\n---"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/1100-render.md",
"chars": 421,
"preview": "---\ntitle: render\ndescription: Render a simplified, but equivalent Terragrunt config.\nslug: reference/cli/commands/rende"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/backend/0300-bootstrap.md",
"chars": 436,
"preview": "---\ntitle: bootstrap\ndescription: Interact with OpenTofu/Terraform backend infrastructure.\nslug: reference/cli/commands/"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/backend/0301-migrate.md",
"chars": 438,
"preview": "---\ntitle: migrate\ndescription: Migrate OpenTofu/Terraform state from one location to another.\nslug: reference/cli/comma"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/backend/0302-delete.md",
"chars": 406,
"preview": "---\ntitle: delete\ndescription: Delete OpenTofu/Terraform state.\nslug: reference/cli/commands/backend/delete\nsidebar:\n o"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/dag/1000-graph.md",
"chars": 424,
"preview": "---\ntitle: graph\ndescription: Graph the Directed Acyclic Graph (DAG) in DOT language.\nslug: reference/cli/commands/dag/g"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/hcl/0900-fmt.md",
"chars": 467,
"preview": "---\ntitle: fmt\ndescription: Recursively find HashiCorp Configuration Language (HCL) files and rewrite them into a canoni"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/hcl/0901-validate.md",
"chars": 454,
"preview": "---\ntitle: validate\ndescription: Recursively find HashiCorp Configuration Language (HCL) files and validate them.\nslug: "
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/info/1200-print.md",
"chars": 422,
"preview": "---\ntitle: print\ndescription: Print out a short description of Terragrunt context.\nslug: reference/cli/commands/info/pri"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/stack/0400-generate.md",
"chars": 457,
"preview": "---\ntitle: generate\ndescription: Generate a stack of units based on configurations in a terragrunt.stack.hcl file.\nslug:"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/stack/0401-run.md",
"chars": 444,
"preview": "---\ntitle: run\ndescription: Run a command against a stack of units defined in a terragrunt.stack.hcl file.\nslug: referen"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/stack/0402-output.md",
"chars": 463,
"preview": "---\ntitle: output\ndescription: Retrieve outputs from units defined in a terragrunt.stack.hcl file as an aggregated outpu"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/02-commands/stack/0403-clean.md",
"chars": 456,
"preview": "---\ntitle: clean\ndescription: Remove the auto-generated `.terragrunt-stack` directories created by `stack` commands.\nslu"
},
{
"path": "docs/src/content/docs/04-reference/02-cli/98-global-flags.mdx",
"chars": 978,
"preview": "---\ntitle: Global Flags\ndescription: Global flags for the Terragrunt CLI.\nslug: reference/cli/global-flags\nsidebar:\n or"
}
]
// ... and 3872 more files (download for full content)
About this extraction
This page contains the full source code of the gruntwork-io/terragrunt GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 4072 files (7.3 MB), approximately 2.2M tokens, and a symbol index with 7085 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.