adding content
This commit is contained in:
269
Career Concepts/20260410122116-ess_scripts.org
Normal file
269
Career Concepts/20260410122116-ess_scripts.org
Normal file
@@ -0,0 +1,269 @@
|
||||
:PROPERTIES:
|
||||
:ID: bf63b6c5-f32f-462e-82ad-8d4a15f7ba48
|
||||
:END:
|
||||
#+DATE: 2026-04-10
|
||||
#+filetags: :powershell:scripts:ess:esp:microlise:
|
||||
#+STARTUP: showall
|
||||
#+title: ESP — PowerShell Script Architecture
|
||||
|
||||
* Overview
|
||||
:PROPERTIES:
|
||||
:RELATED: [[id:a6c345df-8db9-4538-b87e-0e72e2414905][ESP Deployment Pipeline — Index]]
|
||||
:END:
|
||||
|
||||
The deployment scripts are structured in *three tiers*, loosely analogous to a presentation/domain/data layered architecture in software. This separation exists to:
|
||||
|
||||
- Keep ESP-specific knowledge isolated to higher tiers
|
||||
- Allow Tier 3 functions to be tested in isolation
|
||||
- Allow the scripts to run independently of AzDO
|
||||
- Make incremental automation easier (replace manual prompts one function at a time)
|
||||
|
||||
* Entry Point — How to Call the Scripts
|
||||
|
||||
#+BEGIN_SRC powershell
|
||||
Invoke-Deployment.ps1 -Customer ROMAC -Environment DEV -Stages PREDEPLOY,DEPLOY,POSTDEPLOY
|
||||
#+END_SRC
|
||||
|
||||
You can pass any combination of stages. For example, to only validate:
|
||||
|
||||
#+BEGIN_SRC powershell
|
||||
Invoke-Deployment.ps1 -Customer ROMAC -Environment DEV -Stages VALIDATE
|
||||
#+END_SRC
|
||||
|
||||
* Tier 1 — Entry Point (Presentation Layer)
|
||||
|
||||
** Responsibility
|
||||
- The *single entry point* to the whole deployment system
|
||||
- Loads and validates the manifest (see [[id:9bf19a8b-5581-4be8-9892-913c51df0128][ESP — The Manifest]])
|
||||
- Loads all required PowerShell modules (Tier 2, Tier 3, helpers)
|
||||
- Calls the appropriate Tier 2 functions for the requested stages
|
||||
- Passes the manifest object through to Tier 2
|
||||
|
||||
** Key Characteristics
|
||||
- One script: ~Invoke-Deployment.ps1~
|
||||
- Does NOT contain deployment logic itself
|
||||
- Acts as a wiring layer only
|
||||
|
||||
** Pseudocode
|
||||
#+BEGIN_SRC powershell
|
||||
param(
|
||||
[string]$Customer,
|
||||
[string]$Environment,
|
||||
[string[]]$Stages
|
||||
)
|
||||
|
||||
$manifest = Load-Manifest -Customer $Customer -Environment $Environment
|
||||
Assert-ManifestValid -Manifest $manifest
|
||||
|
||||
Import-Module ./Tier2/PreDeployment.psm1
|
||||
Import-Module ./Tier2/Deployment.psm1
|
||||
Import-Module ./Tier2/PostDeployment.psm1
|
||||
Import-Module ./Helpers/Logging.psm1
|
||||
|
||||
foreach ($stage in $Stages) {
|
||||
switch ($stage) {
|
||||
"PREDEPLOY" { Invoke-PreDeployment -Manifest $manifest }
|
||||
"DEPLOY" { Invoke-Deployment -Manifest $manifest }
|
||||
"POSTDEPLOY" { Invoke-PostDeployment -Manifest $manifest }
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
* Tier 2 — Orchestration Layer (Domain Layer)
|
||||
|
||||
** Responsibility
|
||||
- One script per deployment stage (e.g. ~PreDeployment.psm1~, ~Deployment.psm1~)
|
||||
- Contains the *logic and sequencing* of what needs to happen
|
||||
- Decides *which* Tier 3 functions to call and in what order
|
||||
- Reacts to return values from Tier 3 (e.g. if a function fails, abort or retry)
|
||||
|
||||
** Key Constraints
|
||||
- *Does NOT* pass the manifest to Tier 3 — all required data is extracted and passed as explicit parameters
|
||||
- *Does NOT* directly perform any action itself — delegates entirely to Tier 3
|
||||
- *Does* have knowledge of ESP and what a deployment involves
|
||||
|
||||
** Why "Does Not Pass Manifest to Tier 3"?
|
||||
Tier 3 functions are designed to be generic and reusable. If they accepted a manifest object, they'd need to know about its structure — breaking isolation. Instead, Tier 2 extracts what Tier 3 needs:
|
||||
|
||||
#+BEGIN_SRC powershell
|
||||
# BAD — passes the whole manifest (couples Tier 3 to manifest structure)
|
||||
Stop-WindowsService -Manifest $manifest
|
||||
|
||||
# GOOD — extracts what's needed and passes explicitly
|
||||
Stop-WindowsService -ServiceName $manifest.Services.DLService.Name `
|
||||
-ServerName $manifest.Servers.AppServer
|
||||
#+END_SRC
|
||||
|
||||
** Scripts in This Tier
|
||||
| Script | Stage it covers |
|
||||
|-----------------------+---------------------|
|
||||
| ~Validation.psm1~ | VALIDATE stage |
|
||||
| ~Prerequisites.psm1~ | PREREQUISITES stage |
|
||||
| ~PreDeployment.psm1~ | PREDEPLOY stage |
|
||||
| ~Deployment.psm1~ | DEPLOY stage |
|
||||
| ~PostDeployment.psm1~ | POSTDEPLOY stage |
|
||||
|
||||
* Tier 3 — Functional Layer (Workers)
|
||||
|
||||
** Responsibility
|
||||
- Small, *single-purpose* functions
|
||||
- No knowledge of ESP, the manifest, or deployment context
|
||||
- Accept all required data as *explicit parameters*
|
||||
- Can be tested in isolation with mock data
|
||||
|
||||
** Key Characteristics
|
||||
- Examples: ~Stop-WindowsService~, ~Invoke-SqlScript~, ~Copy-Files~, ~Get-RemoteSession~, ~Send-CitrixNotification~
|
||||
- Initially implemented as *manual prompt wrappers* — the function prints instructions to a human and waits for confirmation
|
||||
- Will be replaced with real automation incrementally
|
||||
|
||||
** The Manual Prompt Pattern (Current State)
|
||||
#+BEGIN_SRC powershell
|
||||
function Stop-WindowsService {
|
||||
param([string]$ServiceName, [string]$ServerName)
|
||||
|
||||
# Current implementation — prompts a human
|
||||
$response = Invoke-ManualPrompt -Message "Please stop service '$ServiceName' on '$ServerName', then press Enter."
|
||||
return $response
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** Target Implementation (Automated)
|
||||
#+BEGIN_SRC powershell
|
||||
function Stop-WindowsService {
|
||||
param([string]$ServiceName, [string]$ServerName)
|
||||
|
||||
$session = Get-RemoteSession -ServerName $ServerName
|
||||
Invoke-Command -Session $session -ScriptBlock {
|
||||
Stop-Service -Name $using:ServiceName -Force
|
||||
(Get-Service -Name $using:ServiceName).WaitForStatus('Stopped', '00:01:00')
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** Exceptions — Functions That Cannot Be Manual Prompts
|
||||
A small number of Tier 3 functions *must* be implemented for real from the start because they return data the scripts need to function:
|
||||
|
||||
| Function | Why it can't be a manual prompt |
|
||||
|---------------------+-------------------------------------------------------|
|
||||
| ~Load-Manifest~ | Returns the manifest object — must actually read file |
|
||||
| ~Get-RemoteSession~ | Returns a PS session — must actually connect |
|
||||
| ~Read-File~ | Returns file contents — must actually read |
|
||||
|
||||
* Helper Modules
|
||||
|
||||
In addition to the three tiers, *general-purpose helper modules* exist that can be called from anywhere (Tier 1, 2, or 3):
|
||||
|
||||
| Module | Purpose |
|
||||
|----------------+--------------------------------------------|
|
||||
| ~Logging.psm1~ | Write structured log output |
|
||||
| ~Prompt.psm1~ | The manual prompt mechanism used by Tier 3 |
|
||||
| | |
|
||||
|
||||
Helpers follow the same rule as Tier 3: *the manifest is never passed to them*.
|
||||
|
||||
* Testing Strategy
|
||||
|
||||
Because Tier 3 functions are isolated, they can be unit tested without any connection to a real ESP environment:
|
||||
|
||||
#+BEGIN_SRC powershell
|
||||
# Example Pester test for Stop-WindowsService
|
||||
Describe "Stop-WindowsService" {
|
||||
It "calls Invoke-Command with correct service name" {
|
||||
Mock Invoke-Command {}
|
||||
Mock Get-RemoteSession { return [PSCustomObject]@{ Session = "MockSession" } }
|
||||
|
||||
Stop-WindowsService -ServiceName "DLService" -ServerName "SERVER01"
|
||||
|
||||
Assert-MockCalled Invoke-Command -Times 1
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
* Incremental Automation Plan
|
||||
|
||||
The architecture is designed so that automation can be added *one function at a time*, without restructuring anything:
|
||||
|
||||
1. Deploy with all Tier 3 functions as manual prompts (guided checklist)
|
||||
2. Identify the lowest-risk, simplest functions to automate first
|
||||
3. Replace manual prompts with real implementations one by one
|
||||
4. Each replacement can be independently tested before deployment
|
||||
|
||||
Suggested automation order (rough):
|
||||
1. ~Stop-WindowsService~ / ~Start-WindowsService~ — well-understood, low risk
|
||||
2. ~Copy-Files~ — straightforward file operations
|
||||
3. ~Invoke-SqlScript~ — once databases are in dacpac-ready state
|
||||
4. Citrix-related functions — last, most complex
|
||||
|
||||
* Architecture Diagram (Text)
|
||||
|
||||
#+BEGIN_SRC
|
||||
AzDO Pipeline (YAML)
|
||||
│
|
||||
└─► Invoke-Deployment.ps1 [TIER 1]
|
||||
│ Loads manifest
|
||||
│ Loads all modules
|
||||
│
|
||||
├─► PreDeployment.psm1 [TIER 2]
|
||||
│ ├─► Copy-Files [TIER 3]
|
||||
│ └─► ...
|
||||
│
|
||||
├─► Deployment.psm1 [TIER 2]
|
||||
│ ├─► Stop-WindowsService [TIER 3]
|
||||
│ ├─► Invoke-SqlScript [TIER 3]
|
||||
│ ├─► Start-WindowsService [TIER 3]
|
||||
│ └─► ...
|
||||
│
|
||||
└─► PostDeployment.psm1 [TIER 2]
|
||||
├─► Get-ServiceStatus [TIER 3]
|
||||
└─► ...
|
||||
|
||||
[Helpers: Logging, Prompt — available at any tier]
|
||||
#+END_SRC
|
||||
|
||||
** Mermaid Diagram (Text)
|
||||
#+BEGIN_SRC mermaid
|
||||
graph TD
|
||||
|
||||
%% Tier 1
|
||||
subgraph "Tier 1 - Entry Point"
|
||||
A[Invoke-Deployment.ps1]
|
||||
end
|
||||
|
||||
%% Tier 2
|
||||
subgraph "Tier 2 - Deployment Phases"
|
||||
B[PreDeployment.psm1]
|
||||
C[Deployment.psm1]
|
||||
D[PostDeployment.psm1]
|
||||
end
|
||||
|
||||
%% Tier 3
|
||||
subgraph "Tier 3 - Actions"
|
||||
E[Copy-Files]
|
||||
F[Stop-WindowsService]
|
||||
G[Invoke-SqlScript]
|
||||
H[Start-WindowsService]
|
||||
I[Get-ServiceStatus]
|
||||
end
|
||||
|
||||
%% Helpers
|
||||
subgraph "Helpers (All Tiers)"
|
||||
J[Logging Helper]
|
||||
K[Prompt Helper]
|
||||
end
|
||||
|
||||
%% Relationships
|
||||
A --> B
|
||||
A --> C
|
||||
A --> D
|
||||
|
||||
B --> E
|
||||
|
||||
C --> F
|
||||
C --> G
|
||||
C --> H
|
||||
|
||||
D --> I
|
||||
|
||||
A --> J
|
||||
A --> K
|
||||
#+END_SRC
|
||||
Reference in New Issue
Block a user