External Modules¶
Understand how Cultivator handles external Terraform modules sourced from private and public repositories.
Overview¶
Cultivator does not download or manage external Terraform modules directly. Instead, Terragrunt handles all module sourcing, and Cultivator orchestrates Terragrunt's execution.
This design keeps Cultivator simple and focused on orchestration while leveraging Terragrunt's robust module handling.
How Module Sourcing Works¶
- Cultivator discovers
terragrunt.hclfiles under the root directory (Terragrunt stacks) - Terragrunt parses module sources from
terragrunt.hcl - Terragrunt downloads external modules (using
terraform get) - Terragrunt initializes the working directory
- Cultivator executes
terragrunt plan/apply/destroy
Module Source Types¶
Terragrunt supports module sources from:
Public Registry¶
GitHub (Public)¶
GitHub (Private)¶
Custom Git Repository¶
HTTP Source¶
Local Path¶
Authentication for Private Modules¶
Terragrunt uses Git credentials to fetch private modules. Configure in your CI environment:
GitHub (HTTPS + Personal Access Token)¶
# In GitHub Actions secrets
git config --global url."https://ghp_xxxxx:x-oauth-basic@github.com/".insteadOf "https://github.com/"
Or use SSH:
# In GitHub Actions via actions/checkout with SSH key
- uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.SSH_KEY }}
GitLab (Terraform Registry)¶
# Set CI_JOB_TOKEN in .gitlab-ci.yml
git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/".insteadOf "https://gitlab.com/"
AWS CodeArtifact¶
# Retrieve credentials and configure git
aws codeartifact login --tool git --domain your-domain --repository your-repo --region us-east-1
Cultivator's Role¶
Cultivator coordinates execution but doesn't manage module versioning or caching:
Cultivator (orchestration)
|
Terragrunt (module sourcing, state management)
|
Terraform/OpenTofu (module execution, state backend)
|
External Module (downloaded and executed)
When you run:
Cultivator:
- Discovers
terragrunt.hclfiles (stacks) - Respects dependency graph
- For each stack, calls
terragrunt plan - Terragrunt handles module downloads and initialization
Caching and Performance¶
Terragrunt caches downloaded modules in .terragrunt-cache/ by default.
Terragrunt manages cache invalidation automatically. To clear the cache manually, remove the .terragrunt-cache/ directories:
Dependency Resolution¶
If stack A depends on stack B (via dependency blocks), Cultivator ensures B runs and completes before A:
# Module A
dependency "base" {
config_path = "../base"
}
inputs = {
vpc_id = dependency.base.outputs.vpc_id
}
Cultivator parses this graph and executes stacks in the correct order.
Troubleshooting Module Issues¶
Module Not Found¶
Solutions:
- Verify the repository URL is correct
- Check network connectivity from CI runner
- Verify Git credentials are configured
- Ensure the ref/tag exists
Version Constraint Errors¶
Solutions:
- Update Terraform to latest
- Check version constraint syntax
- Verify the module provides the requested version
Permission Denied¶
Solutions (GitHub Actions):
- uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Trust GitHub's SSH key
run: |
mkdir -p ~/.ssh
ssh-keyscan github.com >> ~/.ssh/known_hosts
Solutions (GitLab CI):
before_script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | base64 -d | ssh-add -
- ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
Best Practices¶
1. Version All External Modules¶
Always use exact versions (e.g., ?ref=v1.2.3).
2. Separate Module Repository from Infrastructure Repo¶
- Keep modules in a dedicated Git repository
- Tag releases explicitly
- Update module versions deliberately
3. Use Dependency Blocks for Cross-Module Data¶
Use dependency blocks instead of hardcoding outputs or using data blocks across modules.
4. Cache .terragrunt-cache/ in CI¶
Use CI caching mechanisms to speed up module downloads.
5. Document Module Requirements¶
List external dependencies, minimum versions, and required credentials in your module README.
See Design for Cultivator's overall architecture and Configuration for runtime options.