Cross-repo dependencies
A stack can depend on a stack in another repository, and a stack can use a module from another repository. Stackorder records both kinds of edge, so the graph and the UI span repositories. What it cannot do is order a single run across repositories: each run applies the stacks of one repository.
Declaring a cross-repo dependency
Qualify the stack key with the repository, as owner/repo//key, in the dependent stack's .stackorder.yaml:
# acme/infra: stacks/prod/vpc/.stackorder.yaml
depends_on:
- acme/network-infra//stacks/prod/tgwRequirements:
- Both repositories are covered by the same App installation.
- The upstream stack's key is its repository-relative path, with
:instancewhen the upstream directory has instances, as inacme/network-infra//infra/tgw:production. Name the instance explicitly: the scanner cannot see another repository's instances, so a bare path is not resolved to the instance of the same name as it is within a repository. Adepends_onentry may use a template, such asacme/network-infra//infra/tgw:{{ .Instance }}.
The server stores the edge and marks the upstream stack external in the dependent repository's graph.
What happens when the upstream stack applies
depends_on edges to other repositories are stored but cannot order a single-repository run. Instead:
- When an upstream stack applies, the server lists its external dependents on the run. The run's resolution response carries them in
external. - With
propagate.cross_repo: planin the upstream repository's default-branchstackorder.yaml, the server also starts a plan-only run in each downstream repository once the upstream apply finishes, for the dependent stacks of the stacks that applied. The run has triggerpush, is for the head of the downstream default branch, carries a warning naming the upstream run, and is dispatched through the downstream repository'sstackorder-run.ymlwithmode: plan, under the environmentdefault. There is one such run per upstream run and downstream repository.
Drift caused by the upstream change then shows up within minutes, rather than at the next scheduled drift check.
# stackorder.yaml of the repository whose stacks others depend on
propagate:
cross_repo: plan # off | planThe default is off: external dependents are listed on the run, and nothing is dispatched.
A cross-repo plan run never applies. Applying the downstream stack is a change in its own repository, through its own pull request and apply gate.
Modules from other repositories
A module block with a git:: or github.com/ source creates a uses_module edge to a git module whose identity includes the ref:
module "vpc" {
source = "git::https://github.com/acme/modules.git//vpc?ref=v1.2.0"
}Git-pinned modules never make a consumer "changed" in a pull request. A change in the module repository does not change consumers until they bump ref.
When the module repository has the App installed and pushes a semver tag, the server records the version. The module page in the UI then lists every consumer stack, the ref it pins, and how many releases it is behind. Bumping is left to Renovate or Dependabot.
Viewing the cross-repo graph
- The repository graph, in the UI and from
GET /v1/repos/{owner}/{repo}/graph, includes upstream stacks from other repositories, markedexternal: true. GET /v1/stacks/{id}lists a stack'sdepends_onanddependents.GET /v1/modules/{id}lists a module's versions and consumers across repositories.
See the API reference.