Multiple environments and roots
One Action invocation builds one Terraform root with one ordered set of var files. Staging and production planned from the same root with different tfvars are two builds. So are two separate roots. Each gets its own diagram and its own pull request comment.
Use a matrix
Section titled “Use a matrix”Steps in a job run one after another, so two environments as two steps means two full init + plan + scan cycles, back to back. Legs of a matrix are separate jobs and run at the same time.
jobs: diagram: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - environment: staging varFile: environments/staging.tfvars - environment: production varFile: environments/production.tfvars steps: - uses: actions/checkout@v7 - uses: hashicorp/setup-terraform@v4 with: terraform_wrapper: false - uses: actions/setup-go@v7 with: go-version: stable # … cloud credentials … - uses: Tekchbila-Studios/infragram-action@v1 with: working-directory: infrastructure environment: ${{ matrix.environment }} var-files: | environments/common.tfvars ${{ matrix.varFile }}For separate roots, put the directory in the matrix too:
matrix: include: - environment: network directory: stacks/network - environment: platform directory: stacks/platform# …with: working-directory: ${{ matrix.directory }} environment: ${{ matrix.environment }}environment is required here
Section titled “environment is required here”A newer build replaces an older one on the same pull request, but only within the same environment. Two builds that both leave environment unset count as the same build, so the second replaces the first and the pull request ends up with one diagram instead of two.
Environment names can be up to 40 characters: letters, digits, spaces, ., _ and -, starting with a letter or digit. Any other value is ignored, and the build counts as the unnamed default environment.
fail-fast: false
Section titled “fail-fast: false”Without it, a plan that fails in one environment cancels the other legs, including ones that were about to produce a diagram.
Concurrency
Section titled “Concurrency”Keep concurrency at the workflow level:
concurrency: group: infragram-${{ github.event.pull_request.number }} cancel-in-progress: trueIf you move it onto the job, every matrix leg lands in the same group, and cancel-in-progress makes the legs cancel each other. A job-level group has to include the matrix value in its name, for example infragram-${{ github.event.pull_request.number }}-${{ matrix.environment }}.
Concurrent build limit
Section titled “Concurrent build limit”Matrix legs post their bundles within seconds of each other and can hit your account’s concurrent build limit. This is expected. The Action waits and retries for up to five minutes and logs this notice:
This account already has the maximum number of builds rendering. Retrying in 30s.It doesn’t drop the build. By that point the plan and the scan are done, and failing over a few seconds of contention would waste them.
Var files and overrides
Section titled “Var files and overrides”var-files is read in order, and later files override earlier ones. Paths are relative to working-directory, because that is where Terraform runs. Don’t list terraform.tfvars or *.auto.tfvars, which Terraform loads on its own.
To override individual variables, use vars, one key=value per line:
vars: | region=eu-west-1 cluster_name=platform blueValues are read line by line, so spaces need no quoting.
Roots that can’t be planned
Section titled “Roots that can’t be planned”Terraform refuses to plan a configuration whose count or for_each depends on a value known only after apply, such as an IPAM-allocated CIDR or the ID of a resource that doesn’t exist yet. There is no plan to diagram, and retrying can’t produce one.
The Action treats this one case as a warning and exits successfully, so one such root doesn’t turn a whole matrix red. Any other plan error still fails the step. See Troubleshooting.