- Drop existing indexes on DeploymentJobTargets and DeploymentJobSteps - Alter Status column to nvarchar(450) in DeploymentJobTargets, DeploymentJobSteps, and DeploymentJobs - Add new columns: Finished, OutputMetadataJson, Started to DeploymentJobTargets; ErrorMessage, Finished, OutputMetadataJson, Started to DeploymentJobSteps; CorrelationId, HeartbeatAt, Priority, RowVersion, ScheduledAt, WorkerName to DeploymentJobs - Create new indexes for improved query performance - Add constraints to ensure OutputMetadataJson is valid JSON - Record migration in __EFMigrationsHistory
598 lines
16 KiB
Markdown
598 lines
16 KiB
Markdown
# SelfService Portal Process
|
|
|
|
## Purpose
|
|
|
|
This document describes the current end-to-end process as understood for the SelfService Portal.
|
|
It is intentionally written as a business and platform flow, not as a low-level API reference.
|
|
|
|
The goal is to make visible how catalog data, reusable templates, deployment composition, queue jobs, and worker execution fit together.
|
|
|
|
## Big Picture
|
|
|
|
The portal is intended to become a generic configuration composition platform.
|
|
It should support on-premises workloads such as Active Directory, SQL Server, SharePoint, and Exchange, and also cloud workloads such as Teams, Azure, Microsoft 365, and Azure resources.
|
|
|
|
The important idea is:
|
|
|
|
```text
|
|
Reusable catalog data + immutable template versions + deployment-specific choices
|
|
-> composed deployment document
|
|
-> queue job
|
|
-> worker renders and executes
|
|
```
|
|
|
|
The database should know generic concepts such as environments, domains, targets, services, templates, template versions, deployment groups, queue jobs, and artifacts.
|
|
Workload-specific details, for example SharePoint farm accounts or Teams policies, belong inside versioned template documents.
|
|
|
|
## Roles Of The Applications
|
|
|
|
### Microsoft.SelfService.Portal.Core.API
|
|
|
|
The API owns the central data model and exposes it to the GUI and worker.
|
|
|
|
Responsibilities:
|
|
|
|
- Store catalog data such as environments, domains, services, targets, templates, and template versions.
|
|
- Store deployment composition data such as selected template versions, parameter overrides, and target assignments.
|
|
- Validate JSON documents before storing them.
|
|
- Create deployment queue jobs.
|
|
- Expose queue job status, steps, target progress, errors, and metadata.
|
|
|
|
### Microsoft.SelfService.Portal.Web
|
|
|
|
The web frontend is the user-facing surface.
|
|
|
|
Responsibilities:
|
|
|
|
- Let users browse catalog data.
|
|
- Let users create and edit deployment groups.
|
|
- Let users select template versions, targets, parameters, and later preview effective configuration data.
|
|
- Submit deployment requests into the API queue.
|
|
- Show queue job state and execution progress.
|
|
|
|
The current GUI is intentionally rudimentary. The later target is a richer interactive deployment builder.
|
|
|
|
### Microsoft.SelfService.Portal.Core.Worker
|
|
|
|
The worker processes queued deployment jobs.
|
|
|
|
Responsibilities:
|
|
|
|
- Claim jobs safely from the queue.
|
|
- Load deployment composition from the API database.
|
|
- Render the deployment composition into an artifact.
|
|
- Support different renderers, currently DSC v2 PowerShell data files and DSC v3 JSON.
|
|
- Later execute or hand off the rendered artifacts.
|
|
- Persist target and step output metadata.
|
|
|
|
## Catalog Process
|
|
|
|
### 1. Environments Are Defined
|
|
|
|
An environment is a logical deployment context, for example:
|
|
|
|
```text
|
|
Prod A
|
|
Test A
|
|
QA B
|
|
Prod B
|
|
Test B
|
|
```
|
|
|
|
An environment describes where something belongs and what stage it represents.
|
|
|
|
Examples of environment metadata:
|
|
|
|
- Stage: Test, QA, Production
|
|
- Hosting type: OnPrem, Azure, M365, Hybrid
|
|
- Provider type
|
|
- Tenant or subscription reference
|
|
|
|
### 2. Domains Are Defined Once And Linked
|
|
|
|
A domain is reusable catalog and configuration data.
|
|
It can be linked to multiple environments.
|
|
|
|
Example:
|
|
|
|
```text
|
|
Central-Management Domain
|
|
-> Test A
|
|
-> QA A
|
|
-> Prod A
|
|
```
|
|
|
|
The intent is that a domain configuration is not duplicated for every environment.
|
|
Instead, a domain baseline can be maintained once, then linked or promoted into the environments that should consume it.
|
|
|
|
Target process:
|
|
|
|
```text
|
|
Change Central-Management domain baseline
|
|
-> validate in Test
|
|
-> promote or reuse for Prod
|
|
```
|
|
|
|
Not desired:
|
|
|
|
```text
|
|
Maintain Central-Management Test separately
|
|
Maintain Central-Management Prod separately
|
|
Repeat every change manually
|
|
```
|
|
|
|
### 3. Services Describe Workload Families
|
|
|
|
A service represents a workload type, not a single deployment.
|
|
|
|
Examples:
|
|
|
|
- Active Directory
|
|
- SQL Server
|
|
- SharePoint
|
|
- Exchange
|
|
- Teams
|
|
- Azure Network
|
|
- Microsoft 365 Policies
|
|
|
|
Templates are categorized below services so users can find suitable building blocks.
|
|
|
|
### 4. Targets Are Generic
|
|
|
|
Targets are everything a deployment can act on.
|
|
They are not limited to virtual machines.
|
|
|
|
Examples:
|
|
|
|
- VirtualMachine
|
|
- Tenant
|
|
- Subscription
|
|
- ResourceGroup
|
|
- User
|
|
- Group
|
|
- Site
|
|
- PolicyScope
|
|
|
|
For on-premises workloads, targets are often servers.
|
|
For cloud workloads, targets may be tenants, subscriptions, groups, sites, or policy scopes.
|
|
|
|
## Template Process
|
|
|
|
### 1. A Template Is A Catalog Entry
|
|
|
|
A template is the stable entry shown in the portal.
|
|
It has metadata such as name, category, service, and description.
|
|
|
|
The template itself should not be the mutable source of deployment content in the long term.
|
|
It is the catalog shell.
|
|
|
|
### 2. TemplateVersions Are Immutable Building Blocks
|
|
|
|
The actual configuration document lives in `TemplateVersion.JsonData`.
|
|
|
|
Each template version contains a JSON document with this general shape:
|
|
|
|
```json
|
|
{
|
|
"schemaVersion": "1.0",
|
|
"templateType": "Service",
|
|
"parameters": {},
|
|
"variables": {},
|
|
"resources": {}
|
|
}
|
|
```
|
|
|
|
The template version is the thing that should be selected in a deployment.
|
|
This makes deployments reproducible, because they point to an immutable version instead of a mutable template document.
|
|
|
|
### 3. Template Documents Stay Generic
|
|
|
|
Template documents can describe many workloads.
|
|
|
|
Examples:
|
|
|
|
- Environment defaults
|
|
- Domain defaults
|
|
- Landscape values
|
|
- Service definitions
|
|
- Stage-specific settings
|
|
- Target or role specific blocks
|
|
|
|
The document can contain parameters, variables, and resources.
|
|
The merge and resolve modules can later combine those pieces into effective configuration data.
|
|
|
|
## Deployment Design Process
|
|
|
|
### 1. User Creates A DeploymentGroup
|
|
|
|
A deployment group represents a deployable unit or one part of a larger environment rollout.
|
|
|
|
Example environment rollout:
|
|
|
|
```text
|
|
Deployment Group: Contoso Test Environment
|
|
|
|
Deployment AD
|
|
Targets: 2 domain controller servers
|
|
Templates: Active Directory baseline, environment defaults, stage defaults
|
|
|
|
Deployment SQL
|
|
Targets: 1 SQL server
|
|
Templates: SQL baseline, environment defaults, stage defaults
|
|
|
|
Deployment SharePoint
|
|
Targets: 6 SharePoint servers
|
|
Templates: SharePoint baseline, environment defaults, landscape, stage defaults
|
|
```
|
|
|
|
Current implementation still uses `DeploymentGroup`/`DeploymentBatch` naming in places.
|
|
Conceptually this is the deployment design container.
|
|
|
|
### 2. User Selects Template Versions
|
|
|
|
The deployment group gets one or more `DeploymentTemplateSelections`.
|
|
|
|
Example:
|
|
|
|
```text
|
|
SortOrder 10: Environment Default 1.0
|
|
SortOrder 20: Environment Contoso Test 1.0
|
|
SortOrder 30: Service SharePoint 1.0
|
|
SortOrder 40: Stage Install 1.0
|
|
```
|
|
|
|
The order matters because the selected template versions are composed in order.
|
|
Later selections can extend or override earlier selections, unless a parameter or resource block is sealed.
|
|
|
|
Current state:
|
|
|
|
- The API can store multiple template selections.
|
|
- The GUI can create an initial selection from a selected template version.
|
|
- The details page can add more selections manually.
|
|
|
|
### 3. User Assigns Targets
|
|
|
|
The deployment group gets `DeploymentTargetAssignments`.
|
|
|
|
For server-based workloads, each target assignment usually points to a server.
|
|
|
|
Example:
|
|
|
|
```text
|
|
Target: CT-SHP-01
|
|
RoleKey: WebFrontEnd
|
|
NodeDataJson: { "nodeName": "CT-SHP-01" }
|
|
|
|
Target: CT-SHP-02
|
|
RoleKey: Application
|
|
NodeDataJson: { "nodeName": "CT-SHP-02" }
|
|
```
|
|
|
|
For cloud workloads, the target may be a tenant, policy scope, group, or site instead of a server.
|
|
|
|
Current state:
|
|
|
|
- The API stores target assignments.
|
|
- The GUI create flow turns selected targets into target assignments.
|
|
- Queue requests can use target assignments if explicit target IDs are not sent again.
|
|
|
|
### 4. User Adds Parameter Values
|
|
|
|
The deployment group can store `DeploymentParameterValues`.
|
|
|
|
Parameter values can be global or scoped to a specific template selection.
|
|
|
|
Examples:
|
|
|
|
```text
|
|
Global:
|
|
DatabasePrefix = Contoso_Test
|
|
|
|
Scoped to SharePoint selection:
|
|
FarmAccount = secret reference
|
|
```
|
|
|
|
The intention is that the GUI later shows user-facing parameter forms based on selected template versions.
|
|
The user edits parameter values, and the portal can preview the effective resolved result.
|
|
|
|
Current state:
|
|
|
|
- API stores parameter values.
|
|
- Values are JSON validated.
|
|
- Secret references can be marked.
|
|
- Rich parameter editor and preview are still pending.
|
|
|
|
## Deployment Request Process
|
|
|
|
### 1. User Starts A Deployment
|
|
|
|
When the user starts a deployment, the web frontend calls the API deployment request endpoint.
|
|
|
|
The request currently contains:
|
|
|
|
```text
|
|
DeploymentGroupId
|
|
TargetIds optional
|
|
JsonData optional deployment override
|
|
```
|
|
|
|
If `TargetIds` are omitted, the API can derive targets from the deployment group's target assignments.
|
|
|
|
Target direction:
|
|
|
|
```text
|
|
DeploymentGroup composition should be the source of truth.
|
|
The start request should eventually only reference the DeploymentGroup and optional runtime overrides.
|
|
```
|
|
|
|
### 2. API Validates The Request
|
|
|
|
The API validates:
|
|
|
|
- The deployment group exists.
|
|
- Target IDs exist or target assignments are present.
|
|
- Runtime JSON override is valid JSON.
|
|
- A deployment rule can be resolved from the deployment group or selected template metadata.
|
|
|
|
### 3. API Creates Or Updates Legacy DeploymentExecutions
|
|
|
|
Current compatibility behavior:
|
|
|
|
- The API still creates or updates `DeploymentExecutions`.
|
|
- These records are useful for existing UI views and migration compatibility.
|
|
|
|
Target direction:
|
|
|
|
- `DeploymentExecutions` should become either a read-only compatibility view or be replaced by queue job target/artifact state.
|
|
- The deployment composition and queue job should become the primary execution model.
|
|
|
|
### 4. API Creates A QueueJob
|
|
|
|
The API creates a `QueueJob`.
|
|
|
|
The queue job contains:
|
|
|
|
- Job type
|
|
- Status
|
|
- Correlation ID
|
|
- Priority
|
|
- Schedule and lock metadata
|
|
- Payload JSON
|
|
- Rule snapshot JSON
|
|
- Queue job targets
|
|
- Queue job steps
|
|
|
|
The payload includes the deployment group, selected template versions, target assignments, target IDs, runtime JSON, and metadata.
|
|
|
|
## Queue Process
|
|
|
|
### 1. Worker Claims A Job
|
|
|
|
The worker looks for pending jobs.
|
|
|
|
It claims a job atomically by setting:
|
|
|
|
```text
|
|
Status = Running
|
|
Attempts += 1
|
|
LockedBy
|
|
LockedUntil
|
|
HeartbeatAt
|
|
WorkerName
|
|
```
|
|
|
|
This prevents two workers from processing the same job at the same time.
|
|
|
|
### 2. Worker Processes Steps
|
|
|
|
Queue jobs can contain steps.
|
|
|
|
Examples:
|
|
|
|
- Approval
|
|
- Provision
|
|
- Validate
|
|
- Custom future step types
|
|
|
|
Approval steps can pause the job until a user approves or rejects them through the API.
|
|
|
|
### 3. Worker Processes Queue Targets
|
|
|
|
For each queue target, the worker loads the deployment composition:
|
|
|
|
```text
|
|
DeploymentGroup
|
|
TemplateSelections
|
|
ParameterValues
|
|
TargetAssignments
|
|
Target
|
|
Environment and Domain context
|
|
```
|
|
|
|
The worker then renders artifacts for that target.
|
|
|
|
Current renderers:
|
|
|
|
- PowerShell DSC v2 data file renderer
|
|
- DSC v3 JSON renderer
|
|
|
|
### 4. Worker Writes Output Metadata
|
|
|
|
The worker writes target and step metadata back to the queue records.
|
|
|
|
Examples:
|
|
|
|
- Artifact paths
|
|
- Renderer name
|
|
- Finished timestamps
|
|
- Errors
|
|
|
|
## Composition And Rendering Process
|
|
|
|
### 1. Load Selected Template Versions
|
|
|
|
The worker loads all template selections in sort order.
|
|
|
|
Example:
|
|
|
|
```text
|
|
Environment Default
|
|
Environment Contoso Test
|
|
Landscape Test
|
|
Service SharePoint
|
|
Stage Install
|
|
```
|
|
|
|
### 2. Compose Documents
|
|
|
|
The selected template JSON documents are merged into one effective deployment document.
|
|
|
|
Conceptually:
|
|
|
|
```text
|
|
Parameters
|
|
Variables
|
|
Resources
|
|
Targets / AllNodes
|
|
Metadata
|
|
```
|
|
|
|
Current worker state:
|
|
|
|
- It can load the composition.
|
|
- It can render ordered PowerShell data files and JSON artifacts.
|
|
|
|
Target direction:
|
|
|
|
- DSC v2 renderer should call the existing `Merge-DSCConfigurationData` and `Resolve-DSCConfigurationData` modules.
|
|
- DSC v3 renderer can consume or emit JSON directly.
|
|
|
|
### 3. Resolve Parameters, Variables, And Secrets
|
|
|
|
The resolve module is responsible for resolving expressions and secrets.
|
|
|
|
Examples:
|
|
|
|
```text
|
|
[parameters('DatabasePrefix')]
|
|
[variables('ConfigDbName')]
|
|
[concat(parameters('DatabasePrefix'), '_Config')]
|
|
```
|
|
|
|
For previews, secrets should be skipped or replaced with dummy values.
|
|
For real deployments, secrets are resolved through the configured credential provider.
|
|
|
|
## Preview Process
|
|
|
|
This is not fully implemented yet, but the intended flow is:
|
|
|
|
```text
|
|
User edits deployment composition
|
|
-> clicks Preview
|
|
-> API builds effective deployment composition
|
|
-> API or worker-style service merges selected template versions
|
|
-> Resolve runs with SkipSecrets
|
|
-> GUI shows effective parameters, variables, resources, and target data
|
|
```
|
|
|
|
The preview should help users see what will actually be deployed before a queue job is created.
|
|
|
|
This belongs mostly to Step 8 and Step 8a.
|
|
|
|
## Promotion Process
|
|
|
|
This is not fully implemented yet.
|
|
|
|
Target idea:
|
|
|
|
```text
|
|
Change shared domain or service baseline
|
|
-> create new template version
|
|
-> test in Test environment
|
|
-> promote the same immutable version to QA or Prod deployment groups
|
|
```
|
|
|
|
Promotion should not mean copying large JSON blocks repeatedly.
|
|
It should mean reusing or advancing selected template versions in deployment groups.
|
|
|
|
## Current Implemented State
|
|
|
|
Implemented:
|
|
|
|
- Generic targets exist.
|
|
- Template versions exist and are versioned with hashes.
|
|
- Deployment groups can store template selections.
|
|
- Deployment groups can store parameter values.
|
|
- Deployment groups can store target assignments.
|
|
- Queue jobs have claim/lock/heartbeat metadata.
|
|
- Queue job targets and steps can persist output metadata.
|
|
- Worker can load deployment composition.
|
|
- Worker can render DSC v2-style PowerShell data files and DSC v3-style JSON artifacts.
|
|
- Web can create a rudimentary deployment group using a selected template version and selected targets.
|
|
|
|
Partially implemented:
|
|
|
|
- Legacy `DeploymentGroup.TemplateId` and `DeploymentExecution.JSONData` are still present for compatibility.
|
|
- API still mixes repository and direct `DataContext` logic in some controllers.
|
|
- Queue payloads include composition data, but the API contract is not yet fully cleaned up.
|
|
|
|
Pending:
|
|
|
|
- Dedicated deployment composition service.
|
|
- Transactional deployment group creation.
|
|
- Rich validation results instead of generic `false` / `500`.
|
|
- Preview endpoint based on merge and resolve.
|
|
- Sealed parameter and resource block visibility in API/GUI.
|
|
- Promotion flow.
|
|
- Final cleanup of legacy template JSON and deployment execution fields.
|
|
|
|
## Expected Future Clean Flow
|
|
|
|
The desired future flow should look like this:
|
|
|
|
```text
|
|
1. Admin maintains catalog:
|
|
Environments, Domains, Services, Targets
|
|
|
|
2. Admin maintains templates:
|
|
Template -> TemplateVersion -> Published immutable version
|
|
|
|
3. User creates deployment group:
|
|
Select environment/context
|
|
Select template versions
|
|
Assign targets
|
|
Set parameter values
|
|
|
|
4. User previews:
|
|
Merge selected template versions
|
|
Resolve parameters and variables
|
|
Resolve secrets as dummy values
|
|
Show effective output
|
|
|
|
5. User starts deployment:
|
|
API creates QueueJob
|
|
Worker claims QueueJob
|
|
Worker renders artifacts
|
|
Worker executes or hands off
|
|
API reports status and metadata
|
|
|
|
6. User promotes:
|
|
Reuse tested template versions in the next environment
|
|
Avoid copying environment-specific JSON manually
|
|
```
|
|
|
|
## Main Understanding To Validate
|
|
|
|
The core understanding is:
|
|
|
|
```text
|
|
Templates describe reusable building blocks.
|
|
TemplateVersions make those building blocks immutable.
|
|
DeploymentGroups select and order those building blocks.
|
|
ParameterValues and TargetAssignments make the deployment concrete.
|
|
QueueJobs turn the deployment design into execution.
|
|
Workers render and execute without knowing SharePoint-specific database tables.
|
|
```
|
|
|
|
If this is correct, the next API work should focus on making this process stricter and more explicit, not on adding more legacy shortcuts.
|