Skip to content

Agent 1: Terraform infrastructure (infra/) #1

@TomProkop

Description

@TomProkop

Objective

Create all Terraform infrastructure-as-code files in the infra/ directory. This defines every Azure and Entra ID resource for the AgentBox platform.

Scope

Files to create (ALL in infra/ — do NOT touch any other directory):

  • infra/main.tf — Providers (azurerm ~4.0, azuread ~3.0, azapi ~2.0), azurerm backend with OIDC, resource groups (main + containers)
  • infra/variables.tf — environment, location, subscription_id, tenant_id, domain, github_org, github_repo, admin_group_members
  • infra/outputs.tf — portal_url, portal_fqdn, keyvault_uri, all client_ids, admins_group_id, containers_rg, dns_nameservers
  • infra/entra.tf — 4 Entra ID app registrations + service principals + role assignments:
    1. Portal App (Easy Auth, User.Read + Sites.Read.All delegated)
    2. API SP (Sites.FullControl.All application — for SharePoint grant/revoke)
    3. SharePoint Reader (Sites.Selected application)
    4. GitHub Actions (federated OIDC credentials for main + PR)
    5. "AgentBox Admins" security group
  • infra/keyvault.tf — Key Vault (RBAC, purge protection), SSH CA key (RSA 4096), SP Reader certificate (self-signed, 24mo), placeholder secrets for GitHub/ADO/Atlassian with lifecycle { ignore_changes = [value] }
  • infra/container-apps.tf — Container Apps Environment, Portal Container App (0.25 vCPU, 0.5 GiB, GHCR image, env vars for KV/ACI/domain), custom domain binding, role assignments (Contributor on containers RG, KV Secrets User, KV Crypto User)
  • infra/dns.tf — Azure DNS zone, wildcard CNAME → portal FQDN, root CNAME, TXT validation record
  • infra/bootstrap/state-storage.tf — One-time: RG + Storage Account + container for TF state
  • infra/environments/dev.tfvars — Dev values
  • infra/environments/prod.tfvars — Prod values

Key Design Decisions

  • Cloudflare handles TLS at the edge (free wildcard cert) — Azure DNS zone is for delegation, not cert management
  • ACI containers are NOT in Terraform — they're ephemeral, created/destroyed at runtime by the Portal API
  • Easy Auth configuration may need azapi_resource if azurerm doesn't support it natively
  • OIDC workload identity federation — GitHub Actions authenticates without stored secrets
  • Secrets are created as PLACEHOLDER and populated manually after external OAuth app registration

Conflict Prevention

This agent works ONLY in infra/. No other agent touches this directory.

Acceptance Criteria

  • All .tf files are syntactically valid HCL
  • terraform validate passes (if terraform CLI available)
  • All resources from the plan are covered
  • Variables have descriptions and sensible defaults
  • Outputs expose everything the portal needs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions