Runbook: Creating & Deploying a New Customer
Audience: Platform deployers & on-call engineers
Scope: Captures the baseline customer setup that feeds our Terraform pipelines in GitHub Actions.
1) Purpose
This runbook standardizes how to capture baseline customer details and update Cosmos DB so that infrastructure automation (Terraform via GitHub Actions) can safely provision environments.
2) Prerequisites
-
Azure access to the Rhapsody SaaS Platform tenant and the Management subscription.
-
RBAC: Reader on subscription + Data Contributor on the Cosmos DB account that hosts the customer-secret-configs database/collection.
-
Secrets handling: Use a secure channel (Key Vault, 1Password, or approved secret path). Never paste secrets into Slack/Email.
-
Context: Confirm whether the customer will be Edge (dedicated) or Multi‑tenant (RaaS or M42).
3) High‑Level Workflow
-
Decide tenancy model: Edge vs Multi‑tenant (RaaS/M42).
-
Update Cosmos DB:
-
Edge: Create a new item in the
customer-secret-configscontainer. -
Multi‑tenant: Update the tenant item (e.g.,
m42orraas) by adding a new entry undercustomers[].
-
-
Validate: Run basic queries and check required fields.
-
Commit customer metadata to source-of-truth (if applicable) and notify stakeholders.
4) Detailed Step 1 — Gather Baseline & Update Cosmos DB
4.1 Determine the tenancy model
-
Edge: Customer has dedicated infra boundaries and their own item in Cosmos DB.
-
Multi‑tenant (RaaS/M42): Customer is hosted within a shared tenant; configuration is nested under that tenant’s item.
Tip: If unsure, confirm with Product/CS and check the SOW. The tenancy model affects firewall CIDRs, subscription mapping, and naming conventions.
4.2 If the customer is Edge
Goal: Create a new item in the customer-secret-configs container with all mandatory fields for automation.
Where: Azure Portal → Rhapsody SaaS Platform (tenant) → Management subscription → Azure Cosmos DB account → Data Explorer → Database/Container: customer-secret-configs → Items → New Item.
Minimal field set (illustrative; adapt to schema):
{
"id": "<customer-code>",
"client_id": "<app-sp-client-id>",
"client_secret": "<secret>",
"tenant_id": "<aad-tenant-guid>",
"connectivity_id": "<connectivity-guid>",
"customer_codes": {
"mgmt": "<code>",
"rhapsody": "<code>"
},
"firewall_address": "<public-ip>",
"dns_servers": ["<ip>", "<ip>"] ,
"cidrs": {
"mgmt": "<CIDR>",
"rhapsody": "<CIDR>"
},
"storage_name": "<storage-account>",
"rg_name": "<resource-group>",
"subscriptions": {
"mgmt": "<subscription-guid>",
"rhapsody": "<subscription-guid>"
},
"environments": ["dev", "test", "prod"],
"platform": "edge",
"region": "<azure-region>",
"time_zone": "<IANA tz>"
}
Validation check: After saving, query
SELECT * FROM c WHERE c.id = "<customer-code>"and verify required properties are present and non‑empty.Gotchas:
Ensure
idis unique.Keep naming consistent with Terraform variables (customer code, rg/storage names).
Store secrets in approved secret store; only references should live in Git.
4.3 If the customer is Multi‑tenant (RaaS or M42)
Goal: Update the existing tenant item (e.g., m42 or raas) and append the new customer under customers[].
Where: Same Cosmos DB path as above → locate item m42 or raas → Update.
Typical structure (illustrative; align to live schema):
{
"id": "m42",
"platform": "m42",
"rhapsody_cidrs": ["<cidr>", "<cidr>"],
"upwind": {
"upwind_suffix": "<suffix>",
"upwind_scanner_id": "<guid>",
"upwind_client_id": "<id>"
},
"customers": [
{
"id": "<customer-code>",
"customer_codes": {"mgmt": "<code>", "ccad": "<code>"},
"firewall_address": "<public-ip>",
"dns_servers": ["<ip>"] ,
"cidrs": {"mgmt": "<CIDR>", "rhapsody": "<CIDR>"},
"subscription_id": "<subscription-guid>"
}
]
}
Validation check: Ensure the new object appears under
customers[]and run:
SELECT VALUE c.customers FROM c WHERE c.id = "m42"(orraas) to spot the new entry and verify required keys.Gotchas:
Do not overwrite other customers; append to the array.
Keep tenant‑level fields (CIDRs, Upwind, etc.) untouched unless change is intended and approved.
Confirm the
subscription_idmatches the hosting subscription used by automation.
4.4 Required data checklist (capture before you begin)
-
Customer code(s) (mgmt + rhapsody/ccad as applicable)
-
AADC tenant id and SP/app credentials (referenced securely)
-
Firewall IP and DNS servers
-
CIDRs for mgmt and workload segments
-
Resource group / storage account names
-
Subscriptions per environment
-
Target platform (edge | raas | m42), region , time zone
-
Environment list:
dev,test,prod(confirm if all apply)
4.5 Post‑entry validation
-
Save/Update item.
-
Run a test read via Data Explorer or CLI (Cosmos SQL).
-
If available, run the dry‑run GitHub Actions workflow for Terraform plan to confirm variable ingestion (no secrets shown in logs).
5) Next Steps (after Step 1)
-
Move onto step 2 - https://rhapsodywiki.atlassian.net/wiki/x/JgBgvgQ .
-
Set up monitoring & alerts for the new customer resources.
-
Notify Customer Success / Support with the customer code, tenancy model, and expected timeline.
-
Update any source‑of‑truth docs (customer registry, onboarding tracker).
6) Security & Compliance Notes
-
Obfuscate secrets in screenshots and PRs.
-
Prefer Key Vault or secret manager for credential storage; only store identifiers in Cosmos DB where feasible.
-
Review access grants post‑deployment; remove any temporary elevation.
7) Troubleshooting
-
Write conflict (precondition failed): Re‑fetch item ETag and retry update.
-
Permission denied: Confirm Data Contributor on the Cosmos account; re‑login
az loginif using CLI. -
Terraform missing variables: Compare Cosmos schema vs module expectations; check JSON property names and casing.
End of Step 1. Provide the next steps and I’ll extend this runbook accordingly.