:PROPERTIES:
:ID:       9bf19a8b-5581-4be8-9892-913c51df0128
:END:
#+DATE: 2026-04-10
#+filetags: :ess:esp:microlise:manifest:
#+STARTUP: showall
#+title: ESP — The Manifest

* What Is the Manifest?
:PROPERTIES:
:RELATED: [[id:a6c345df-8db9-4538-b87e-0e72e2414905][ESP Deployment Pipeline — Index]] 
:STATUS:   Design not yet finalised
:END:

The manifest is a *configuration file* that describes a specific customer environment. The deployment scripts read the manifest to understand *what* to deploy, *where*, and *how*.

There will be one manifest per customer/environment combination, for example:
- ~ROMAC_DEV.json~ (or ~.yaml~, ~.psd1~ — format TBC)
- ~ROMAC_PROD.json~
- ~ACMECORP_DEV.json~

* Why the Manifest Matters

Without a manifest, the scripts would have no way of knowing:
- Which server(s) to connect to
- Which apps this customer actually uses
- What credentials to use
- What version is being deployed
- What environment-specific configuration to apply

It is the *single source of truth* for a deployment. Tier 1 loads it, validates it, and passes it to Tier 2. Tier 2 extracts values from it and passes those to Tier 3.

* Design Status

The manifest *structure has not yet been fully designed*. This is an open work item. See [[id:82c3d447-d6d3-498e-9f66-aee60c752462][ESP — Open Questions & TBC Items]] for a list of design questions to resolve.

What follows is a *proposed structure* based on what the scripts will need.

* Proposed Manifest Structure

#+BEGIN_SRC json
{
  "customer": "ROMAC",
  "environment": "DEV",
  "version": "3.2.1",

  "servers": {
    "appServer": "ROMAC-DEV-APP01",
    "dbServer":  "ROMAC-DEV-DB01",
    "citrixServer": "ROMAC-DEV-CTX01"
  },

  "database": {
    "name": "EspBroker",
    "dacpacReady": false
  },

  "windowsServices": {
    "DLService":       { "enabled": true,  "installPath": "C:\\ESP\\DLService" },
    "EmailService":    { "enabled": true,  "installPath": "C:\\ESP\\EmailService" },
    "ExPlService":     { "enabled": false },
    "MISService":      { "enabled": true,  "installPath": "C:\\ESP\\MISService" },
    "OutboundService": { "enabled": true,  "installPath": "C:\\ESP\\OutboundService" },
    "ULService":       { "enabled": false }
  },

  "citrixApps": {
    "VPlanner":      { "enabled": true,  "installPath": "C:\\ESP\\VPlanner" },
    "VPlannerAdmin": { "enabled": true,  "installPath": "C:\\ESP\\VPlannerAdmin" },
    "ImportApp":     { "enabled": false }
  },

  "citrix": {
    "notificationMinutes": 15,
    "sessionKillGracePeriodMinutes": 5
  }
}
#+END_SRC

* Key Fields to Define

| Field                       | Purpose                                                     |
|-----------------------------+-------------------------------------------------------------|
| ~customer~                  | Identifies the customer                                     |
| ~environment~               | Identifies the environment (DEV/TEST/PROD)                  |
| ~version~                   | Version of ESP being deployed                               |
| ~servers.*~                 | Hostnames/IPs of servers to connect to                      |
| ~database.dacpacReady~      | Flag to indicate if DB is in a state for dacpac deployment  |
| ~windowsServices.*.enabled~ | Whether this customer uses this service                     |
| ~citrixApps.*.enabled~      | Whether this customer uses this Citrix app                  |
| ~citrix.*~                  | Citrix-specific config (notification timing, grace periods) |

* Manifest Validation (VALIDATE Stage)

The VALIDATE stage (see [[id:cd3cd02f-c9b3-4455-8ce5-b2a5aa458fed][ESP — Deployment Stages]]) loads the manifest and checks it is well-formed before any deployment activity. Things to validate:

- All required fields are present
- Server names are resolvable/pingable
- ~version~ matches available build artifacts
- ~dacpacReady~ flag prevents DB deployment if false
- No conflicting settings (e.g. test and prod on same server without flag)

* Manifest Location and Storage

Where manifests should live is TBC, but candidates include:
- A dedicated folder in the AzDO repo (versioned with the scripts)
- A separate config repo
- An external config store (Azure App Configuration, Key Vault, etc.)

Sensitive values (passwords, connection strings) should *never* be in the manifest file in plaintext — they should reference a secret store.

* Per-Customer App Lists

Because not all customers use all apps, the manifest is the mechanism that drives per-customer deployment. Tier 2 scripts iterate over enabled apps:

#+BEGIN_SRC powershell
foreach ($service in $manifest.WindowsServices.GetEnumerator()) {
    if ($service.Value.Enabled) {
        Stop-WindowsService -ServiceName $service.Key `
                            -ServerName  $manifest.Servers.AppServer
    }
}
#+END_SRC

* Environments on the Same Server

The handover document flags that some customers may have TEST and PROD on the same physical server. The manifest must account for this — likely via distinct install paths per environment and explicit environment tagging to prevent accidental cross-environment deployment.
