π₯οΈ WorkSpaces Decommission AnalysisΒΆ
WorkSpaces decommission is the FinOps equivalent of capacity planning β cross-validate idle WorkSpaces against connection history, detect cost optimization candidates via W1-W7 scoring, and validate accuracy to β₯99.5% before decommissioning decisions.
For CxO β what WorkSpaces decommission analysis tells you in 60 seconds
WorkSpaces decommission analysis identifies which user endpoints are candidates for termination. These 5 discovery commands extract idle-signal data into CSV files that feed your optimization roadmap and cost-savings projections. Why it matters to you: (1) Regulatory compliance β APRA CPS 230 Β§35 requires traceable cost allocation and resource optimization responses documented before quarter-end. (2) Financial accuracy β idle WorkSpaces are pure waste; these commands quantify the per-workspace monthly cost and terminal date to justify decommissioning timelines. (3) Optimization velocity β decommission-to-removal latency determines whether you capture $50K/month in savings or absorb them as sunk cost. Running this analysis monthly ensures your cost model reflects actual usage patterns and your remediation pipeline is active.
π Governance Posture SnapshotΒΆ
Board-meeting screenshot β 4 KPIs at a glance
| WorkSpaces KPI | Verdict trigger | Evidence file |
|---|---|---|
| Idle WorkSpaces % | π’ β€10% idle Β· π‘ 10-30% (remediation campaign) Β· π΄ >30% (cost governance failure) | tenants/b2b-energy/raw/workspaces/collect-${DATE}.csv |
| W1-W7 decommission scores | π’ β₯70 pts identifies candidate Β· π‘ 40-70 pts (MONITOR) Β· π΄ <40 pts but unchecked (discovery blind spot) | tenants/b2b-energy/raw/workspaces/analyze-${DATE}.json |
| Decommission savings YTD | π’ β₯$50K identified Β· π‘ $10-50K (remediation in flight) Β· π΄ $0 or unknown (discovery blind spot) | tenants/b2b-energy/raw/workspaces/report-${DATE}.md |
| Bundle compliance % | π’ β₯95% correct compute/memory tier Β· π‘ 85-95% (tagging audit needed) Β· π΄ <85% (rightsizing opportunity) | tenants/b2b-energy/raw/workspaces/collect-${DATE}.csv |
Why This MattersΒΆ
Capacity Planning Equivalent: Your Ops director optimizes staff headcount quarterly against actual demand. You must optimize WorkSpaces endpoints quarterly using the same rigor. Without dated, verified inventory exports and W1-W7 scoring, you have no audit proof for decommissioning decisions. These 5 data sources are your endpoint optimization ledger.
Optimization Signal: W1-W7 scoring signals are your most actionable FinOps signal β a WorkSpace never used (W1 β₯15 pts) is worth $45-$360/year in cost savings if decommissioned. These commands surface candidates within hours, not weeks later in a usage audit.
π οΈ Operational Paths β Generate the EvidenceΒΆ
| Category | Profile | Commands | Total Duration | Output |
|---|---|---|---|---|
| WorkSpaces decommission | $AWS_OPERATIONS_PROFILE + $AWS_BILLING_PROFILE |
5 list-* calls (loop below) | ~90s | 5 dated CSVs/JSON in tenants/b2b-energy/raw/workspaces/ |
# Run All β refresh all 5 WorkSpaces datasets
DATE=$(date +%Y-%m-%d)
OUT=tenants/b2b-energy/raw/workspaces
mkdir -p "$OUT"
for CMD in \
"accounts" \
"collect --all-profile $AWS_MANAGEMENT_PROFILE" \
"cost --billing-profile $AWS_BILLING_PROFILE" \
"analyze" \
"report"; do
NAME=$(echo "$CMD" | awk '{print $1}' | tr - _)
uv run runbooks workspaces $CMD \
--output "$OUT" \
--quiet
done
Run individual commands instead (for debugging one dataset)
# From project root
cd /Volumes/Working/projects/command-center
uv run runbooks workspaces accounts \
--management-profile $AWS_MANAGEMENT_PROFILE \
--output tenants/b2b-energy/raw/workspaces/
uv run runbooks workspaces collect \
--all-profile $AWS_MANAGEMENT_PROFILE \
--output tenants/b2b-energy/raw/workspaces/
uv run runbooks workspaces cost \
--billing-profile $AWS_BILLING_PROFILE \
--output tenants/b2b-energy/raw/workspaces/
uv run runbooks workspaces analyze \
--output tenants/b2b-energy/raw/workspaces/
uv run runbooks workspaces report \
--collect-csv tenants/b2b-energy/raw/workspaces/collect-$(date +%Y-%m-%d).csv \
--cost-csv tenants/b2b-energy/raw/workspaces/cost-$(date +%Y-%m-%d).csv \
--analyze-json tenants/b2b-energy/raw/workspaces/analyze-$(date +%Y-%m-%d).json \
--output tenants/b2b-energy/raw/workspaces/
Use the Claude WorkSpaces orchestrators for autonomous decommission analysis with ADLC governance:
Then in Claude session with $AWS_MANAGEMENT_PROFILE and $AWS_BILLING_PROFILE configured:
Each command handles pagination, retry logic, W1-W7 confidence scoring, and audit trail in tmp/command-center/coordination-logs/.
Why use Claude commands: Automatic multi-account iteration, retry on transient failures, W1-W7 scoring confidence validation (β₯99.5%), APRA CPS 230 audit trail capture.
For direct API validation or when runbooks CLI is unavailable, these sample commands verify core WorkSpaces data:
# List all WorkSpaces in an account
aws workspaces describe-workspaces \
--profile $AWS_PROFILE \
--query 'Workspaces[].{Id:WorkspaceId,Username:UserName,State:State,BundleId:BundleId,LastConnection:WorkspaceProperties.Protocols}' \
--output json
# WorkSpaces connection status (W1 signal: last_known_user_connection_timestamp)
aws workspaces describe-workspaces-connection-status \
--profile $AWS_PROFILE \
--output json
# Monthly WorkSpaces cost (Way 2 of 4-way validation)
aws ce get-cost-and-usage \
--time-period Start=$(date -d '1 month ago' +%Y-%m-01),End=$(date +%Y-%m-%d) \
--granularity MONTHLY \
--metrics "UnblendedCost" \
--filter "Dimensions={Key=SERVICE,Values=[Amazon WorkSpaces]}" \
--group-by Type=DIMENSION,Key=LINKED_ACCOUNT \
--profile $AWS_BILLING_PROFILE \
--output json
Reference: For all 5 commands, uv run runbooks workspaces <cmd> --help displays the underlying boto3 call and parameter documentation.
Expected Output β 5 Data Sources
Output location: tenants/b2b-energy/raw/workspaces/ Β· Date suffix: $(date +%Y-%m-%d)
Why these 5 datasets map to the CMDB: Every endpoint in your ServiceNow service map must trace back to a dated source-of-truth export β the CMDB/CSDM mapping column below shows which End-User Computing Service CI each field lands in.
Source: runbooks workspaces accounts Β· File: accounts-*.csv
| Field | Description | Example | CMDB/CSDM CI Mapping |
|---|---|---|---|
account_id |
AWS account ID | ${AWS_ACCOUNT_ID} |
cmdb_ci_cloud_service_account.account_id |
name |
AWS account name | prod-workspaces |
cmdb_ci_cloud_service_account.name |
status |
Account status | ACTIVE |
cmdb_ci_cloud_service_account.operational_status |
email |
Account root email | [email protected] |
cmdb_ci_cloud_service_account.u_root_email |
joined_timestamp |
When account joined org | 2024-09-12T14:33:18Z |
cmdb_ci_cloud_service_account.install_date |
Source: runbooks workspaces collect Β· File: collect-*.csv
| Field | Description | Example | CMDB/CSDM CI Mapping |
|---|---|---|---|
workspace_id |
WorkSpace resource ID | ws-0a1b2c3d4e5f6g7h8 |
cmdb_ci_workstation.resource_id |
username |
Directory user | jane.smith |
cmdb_ci_workstation.user_name |
state |
Workspace state | AVAILABLE / STOPPED |
cmdb_ci_workstation.operational_status |
compute_type |
Bundle compute tier | PERFORMANCE / STANDARD |
cmdb_ci_workstation.u_compute_type |
running_mode |
Always-On or Auto-Stop | ALWAYS_ON |
cmdb_ci_workstation.u_running_mode |
monthly_cost_usd |
Estimated monthly cost | 45.50 |
cmdb_ci_workstation.u_monthly_cost_estimate |
last_known_user_connection_timestamp |
Last connection date | 2026-05-15T09:22:45Z |
cmdb_ci_workstation.last_connection_date |
w1_score |
Connection recency (0-15) | 15 |
cmdb_ci_workstation.u_w1_idle_score |
w2_score |
State signal (0-10) | 10 |
cmdb_ci_workstation.u_w2_state_score |
Source: runbooks workspaces cost Β· File: cost-*.csv
| Field | Description | Example | CMDB/CSDM CI Mapping |
|---|---|---|---|
period_start |
Cost period start date | 2026-05-01 |
cmdb_cost_entry.period_start_date |
account_id |
AWS account | ${AWS_ACCOUNT_ID} |
cmdb_ci_cloud_service_account.account_id |
monthly_cost_usd |
Monthly total by account | 12345.67 |
cmdb_cost_entry.total_unblended_cost |
Source: runbooks workspaces analyze Β· File: analyze-*.json
| Field | Description | Range | CMDB/CSDM CI Mapping |
|---|---|---|---|
workspace_id |
WorkSpace resource ID | N/A | cmdb_ci_workstation.resource_id |
w1_score |
Connection recency: never connected β 15 pts | 0β15 | cmdb_ci_workstation.u_w1_idle_score |
w2_score |
State signal: STOPPED β 10 pts | 0β10 | cmdb_ci_workstation.u_w2_state_score |
w3_score |
Idle ALWAYS_ON cost signal | 0β10 | cmdb_ci_workstation.u_w3_cost_signal_score |
w4_score |
CloudTrail inactivity (reserved) | 0β15 | cmdb_ci_workstation.u_w4_activity_score |
w5_score |
License underutilization (reserved) | 0β15 | cmdb_ci_workstation.u_w5_license_score |
w6_score |
Bundle right-sizing mismatch (reserved) | 0β10 | cmdb_ci_workstation.u_w6_bundle_score |
w7_score |
User lifecycle (terminated, departed) | 0β15 | cmdb_ci_workstation.u_w7_lifecycle_score |
total_score |
Sum W1βW7 (max 105 pts) | 0β105 | cmdb_ci_workstation.u_decommission_score |
recommendation |
DECOMMISSION (β₯70) / MONITOR (β₯40) / KEEP (<40) | N/A | cmdb_ci_workstation.u_remediation_recommendation |
Source: runbooks workspaces report Β· File: workspaces-report-*.md
Markdown report with: - Executive summary (total count, decommission candidates, estimated savings) - Top 10 decommission candidates table - Estimated annual savings projection - Data sources (collect, cost, analyze files used)
π§ How This Data Becomes the CMDBΒΆ
Downstream flow β raw WorkSpaces data β CSDM endpoint hierarchy β ServiceNow CMDB
This page's 5 exports are the first step in a 4-stage pipeline that lands in your endpoint-tracking CMDB:
flowchart LR
A["raw/workspaces/*.csv<br/>(accounts, collect, cost)"] -->|V1 ingest| B["tenants/b2b-energy/inputs/<br/>workspaces_inventory.csv"]
B -->|V4 transform| C["_base/transforms/snow/<br/>cmdb_ci_workstation.j2"]
C -->|CSDM publish| D["(ServiceNow CMDB<br/>cmdb_ci_workstation table)"]
The flow explained: - V1 (ingest): Raw CSVs are validated and deduplicated into unified endpoint inventory. - V4 (transform): The Jinja2 template transforms WorkSpaces data into ServiceNow CMDB endpoint records (who uses what, when, under which cost center). - CSDM publish: Reconciliation script imports endpoint records into your ServiceNow instance for capacity planning + cost chargeback.
Data lineage authority: CC-ADR-014 (4-way cross-validation; V4 native-API is ground truth). Regulatory requirement: APRA CPS 230 Β§35 mandates quarterly decommissioning evidence before financial close; these 5 exports ARE that evidence.
π§ SRE DetailΒΆ
Prerequisites & Environment Variables
Before running the discovery commands, ensure your SSO session is active and you have WorkSpaces API access configured:
aws sts get-caller-identity --profile $AWS_OPERATIONS_PROFILE
# Expected output: Account ID, UserId, ARN of operations account
Required environment variables:
| Variable | Value | Purpose |
|---|---|---|
AWS_MANAGEMENT_PROFILE |
Your AWS management profile (required for accounts) | Organizations API to discover all accounts |
AWS_OPERATIONS_PROFILE |
Your AWS operations profile (for collect multi-account) | Default profile for per-account WorkSpaces inventory |
AWS_BILLING_PROFILE |
Your AWS billing profile (required for cost) | All Cost Explorer API calls must run against billing account |
AWS_DEFAULT_REGION |
AWS region (e.g., us-east-1) |
WorkSpaces API region (WorkSpaces are regional) |
TENANT |
b2b-energy (default for output directory routing) |
Output CSV files route to tenants/b2b-energy/raw/workspaces/ |
Important notes: - Cost Explorer API access is restricted to the billing account β no cross-account substitution. - WorkSpaces are region-specific; run collect per region or use multi-account mode for org-wide inventory. - W1-W7 scoring requires collection data before analyze step (populate-then-score pattern). - This is a READONLY operation; no WorkSpace terminations occur.
Common Issues & Troubleshooting
AccessDenied on Cost Explorer API
- Verify profile is scoped to AWS billing account β this API is only available in the billing account
- Check: aws sts get-caller-identity --profile $AWS_BILLING_PROFILE β Account ID should be your billing account
- Grant user Cost Explorer read-only permissions (AWSBillingReadOnlyAccess IAM policy)
Empty CSV (0 WorkSpaces)
- No WorkSpaces in that account/region (OK β valid state)
- Account is not enabled for WorkSpaces (OK β valid state; check Supported in Account)
- Wrong profile used (verify aws workspaces describe-workspaces --profile $AWS_PROFILE returns non-empty)
W1-W7 scores all zero
- Workspace has connection history (W1 only triggers on never-connected)
- Check CSV load in analyze step; if collect didn't include last_known_user_connection_timestamp, populate manually
Related commands (advanced WorkSpaces scenarios)
For WorkSpaces optimization beyond decommissioning, these commands extend the toolkit:
# Workspace bundle right-sizing analysis
uv run runbooks workspaces analyze \
--collect-csv tenants/b2b-energy/raw/workspaces/collect-*.csv
# 4-way cross-validation (API vs Cost Explorer vs baseline)
uv run runbooks workspaces validate \
--way1-csv tenants/b2b-energy/raw/workspaces/collect-*.csv \
--way2-csv tenants/b2b-energy/raw/workspaces/cost-*.csv \
--way3-json tenants/b2b-energy/raw/workspaces/analyze-*.json
These commands are optional for the monthly decommission analysis but highly recommended for roadmap planning (right-sizing can save 10-20% on compute).
Last Updated: 2026-05-21 | Scope: READONLY AWS WorkSpaces + Cost Explorer APIs only β no mutations | Companion: finops/cost-analysis.md for broader compute optimization.
For questions on WorkSpaces decommissioning timelines, bundle right-sizing, or CMDB integration, see CC-ADR-014 and the Command-Center FinOps documentation.