Skip to main content

Module Development

New pt-arche-* modules are created using pt-arche-child-module-template — a skeleton repository paired with a Copilot coding agent that handles the entire creation workflow end-to-end.

The Arche Module Agent

The Arche Module Agent is a GitHub Copilot coding agent that creates new pt-arche-* repositories without requiring any local setup. It validates your identity, collects the module details, opens a PR on pt-logos to register the repo, and scaffolds all files once the repo exists.

Use the Arche Module Agent in osinfra-io/pt-arche-child-module-template to create a new module.

👋 Hi! I'm the Arche Module Agent. I help create new pt-arche-* OpenTofu child module repositories — I'll scaffold all the files, wire up the GitHub Actions workflows, and open a PR on pt-logos to register the new repo.

Give me just a moment while I look you up…

✓ Identity validated · @arche-dev · arche-dev@osinfra.io

What GCP or Kubernetes resource will this module manage?

Cloud Spanner databases

Based on that, I'd suggest naming the repository pt-arche-google-cloud-spanner. Does that work?

✓ No naming conflicts found in pt-logos or GitHub

How about this description? Feel free to revise it:

OpenTofu module that manages Google Cloud Spanner instances and databases.

Looks good. No sub-modules needed. Default feature flags are fine.

Here's what I'll do:

  • 📋 Open a PR on pt-logos to register pt-arche-google-cloud-spanner under the pt-arche team
  • 📁 Once you confirm the repo exists, push all scaffolded files — helpers.tofu, main.tofu, variables.tofu, outputs.tofu, tests, workflows, and more

helpers.tofu pre-pinned to current pt-arche-core-helpers SHA

Shall I open the PR?

How to invoke it

Clone the template repo and run the Copilot CLI from within it — then type /agent and select Arche Module Agent from the menu:

git clone https://github.com/osinfra-io/pt-arche-child-module-template
cd pt-arche-child-module-template
gh copilot
GitHub MCP — configuration required

The agent opens pull requests and pushes files using the GitHub MCP server. It must be enabled with write toolsets — read-only MCP will allow the agent to inspect state but it will not be able to create branches, push commits, or open pull requests.

The GitHub MCP server must be configured with a fine-grained Personal Access Token scoped to the osinfra-io organization with the following permissions:

PermissionAccess
ContentsRead and write
Pull requestsRead and write
WorkflowsRead and write

Fine-grained PATs must be created through the GitHub web UI at github.com/settings/personal-access-tokens/new.

What it does

  1. Validates your identity — confirms your GitHub username maps to an @osinfra.io email and that you are a member of the osinfra-io organization

  2. Collects module details — asks for the GCP or Kubernetes resource the module will manage, suggests a repository name following the pt-arche-{provider}-{resource} convention, and confirms a description

  3. Asks about sub-modules — if the module needs a regional/ or zonal/ subdirectory structure, it notes this and points to pt-arche-google-kubernetes-engine as a reference (sub-module scaffolding is manual)

  4. Configures feature flags — presents the three Logos configuration flags with sensible defaults

    FlagDefaultPurpose
    enable_datadog_webhooktrueSends repo events to Datadog
    enable_datadog_secretsfalseAdds DD_API_KEY/DD_APP_KEY as repo secrets
    enable_google_wif_service_accountfalseOIDC Workload Identity Federation for GCP deploys
  5. Shows a preview — lists exactly what will be created before doing anything; loops back on request

  6. Opens a PR on pt-logos — repositories are created by Logos via OpenTofu, never directly via the GitHub API; the agent opens the registration PR and waits for you to confirm the repo exists

  7. Scaffolds the module files — once you confirm the repo was created, pushes all skeleton files in a single commit with MODULE_* placeholders substituted

What gets scaffolded

Every new module starts with this complete file structure:

helpers.tofu # pt-arche-core-helpers pinned to current SHA
locals.tofu
main.tofu
outputs.tofu
providers.tofu
variables.tofu
README.md
SECURITY.md
.gitignore
.pre-commit-config.yaml
static-analysis.datadog.yml
tests/
default.tftest.hcl
fixtures/default/
main.tofu
variables.tofu
.github/
copilot-instructions.md
dependabot.yml
release.yml
workflows/
add-to-projects.yml
dependabot.yml
release.yml
test.yml

The helpers.tofu in the skeleton is pre-pinned to the current pt-arche-core-helpers SHA so the new module starts with an up-to-date foundational dependency.

Repository naming convention

Infrastructure typePatternExample
GCP resourcept-arche-google-{resource}pt-arche-google-cloud-run
Kubernetes add-onpt-arche-kubernetes-{addon}pt-arche-kubernetes-cert-manager
Datadog integrationpt-arche-datadog-{service}pt-arche-datadog-google-integration

After creation

Once the scaffold is pushed:

  1. Add your resource code to main.tofu, locals.tofu, variables.tofu, and outputs.tofu
  2. Update tests/default.tftest.hcl with any mock_resource overrides for computed attributes
  3. Tag a v0.1.0 release once the initial code is merged — the release workflow generates notes and publishes automatically

Components

Arche modules follow a two-sided contract between module authors and consumers.

Authors tag releases with semver after merging to main. The release workflow generates notes and publishes automatically:

git tag v1.2.3 && git push origin v1.2.3

Consumers never reference semver tags or branch names as ref values — they always pin to the post-merge commit SHA on main with an inline version comment:

module "google_project" {
source = "github.com/osinfra-io/pt-arche-google-project?ref=<40-char-sha>" # v1.2.3
}

The SHA must come from after the squash merge lands on main, not from the PR branch tip. Branch SHAs are unstable and can be rewritten; main SHAs are permanent.

Core Invariant

Every module ref must point to a post-merge commit SHA on main — never a branch name or semver tag. This makes every deployment reproducible and auditable.