Build the CHP Desired-State & Configuration Management System
Lesson 093 introduced reconciliation:
DESIRED STATE
vs
ACTUAL STATE
↓
MATCH / DRIFT / UNKNOWN / CONFLICT
The next question is:
Where does CHP get the Desired State?
The answer should not be a collection of manually edited values scattered across scripts.
Instead, CHP needs a proper Configuration Management System.
1. Desired-State Architecture
The configuration hierarchy should be:
CHP PLATFORM DEFAULTS
│
▼
HOSTING PLAN
│
▼
SITE PROFILE
│
▼
SITE OVERRIDES
│
▼
DESIRED STATE
│
▼
RECONCILIATION
For example:
Platform:
PHP 8.3
Business Hosting Plan:
PHP 8.3
example.com:
PHP 8.4 override
FINAL DESIRED:
PHP 8.4
2. Why Hierarchy?
Suppose you host:
120 websites
You don’t want to configure PHP, backups, SSL, and health monitoring individually 120 times.
Instead:
Business Plan
│
├── site 1
├── site 2
├── site 3
└── site 4
All sites inherit the common configuration.
3. Configuration Layers
Use five conceptual layers:
1. PLATFORM
2. PLAN
3. SITE PROFILE
4. SITE OVERRIDE
5. GENERATED DESIRED STATE
The final desired state is calculated from these layers.
4. Platform Defaults
These are global defaults.
Example:
{
"php_version": "8.3",
"ssl_enabled": true,
"backup_enabled": true,
"health_monitoring": true
}
These apply unless something more specific overrides them.
5. Hosting Plan
Example plans:
STARTER
BUSINESS
PROFESSIONAL
MULTI_DOMAIN
Each plan can define:
PHP policy
storage
backup frequency
health monitoring
SSL
resource limits
6. Example Business Plan
{
"storage_gb": 5,
"php_version": "8.3",
"ssl_enabled": true,
"backup_enabled": true,
"backup_frequency": "daily",
"health_monitoring": true
}
7. Site Profile
A site profile contains configuration common to a class of websites.
For example:
WORDPRESS_STANDARD
WORDPRESS_MANAGED
PHP_CUSTOM
STATIC_SITE
A WordPress profile might define:
{
"application": "wordpress",
"health_monitoring": true,
"wordpress_core_monitoring": true
}
8. Site Override
A specific customer may require:
PHP 8.4
even though the hosting plan uses:
PHP 8.3
The site override becomes:
{
"php_version": "8.4"
}
9. Final Desired State
CHP combines everything:
PLATFORM
↓
PLAN
↓
PROFILE
↓
SITE OVERRIDE
↓
FINAL DESIRED STATE
Example:
Platform PHP:
8.3
Plan PHP:
8.3
Profile:
8.3
Site Override:
8.4
----------------
Desired:
8.4
10. Configuration Precedence
The rule should be deterministic:
SITE OVERRIDE
>
SITE PROFILE
>
HOSTING PLAN
>
PLATFORM DEFAULT
The most specific valid configuration wins.
11. Never Use Random Precedence
Avoid situations where:
plan.sh
site.sh
repair.sh
hosting-create.sh
each decides independently which value wins.
There should be one configuration resolver.
12. Configuration Resolver
Create:
sudo nano /etc/cresignsys/lib/config-resolver.sh
Main function:
resolve_site_config
Input:
site_id
Output:
final desired state
13. Resolver Example
Conceptually:
resolve_site_config 7
returns:
{
"php_version": "8.4",
"ssl_enabled": true,
"backup_enabled": true,
"backup_frequency": "daily",
"health_monitoring": true
}
This becomes the authoritative desired state.
14. Configuration Database
Create a plan table if you don’t already have one:
CREATE TABLE hosting_plans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
configuration TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
15. Site Profile Table
CREATE TABLE site_profiles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
configuration TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
16. Assign Plan to Site
Your sites table should contain something like:
plan_id
Example:
example.com
↓
Business Plan
17. Assign Profile
Also:
profile_id
Example:
example.com
↓
Business Plan
↓
WORDPRESS_STANDARD
18. Site Overrides
Create:
CREATE TABLE site_config_overrides (
id INTEGER PRIMARY KEY AUTOINCREMENT,
site_id INTEGER NOT NULL,
config_key TEXT NOT NULL,
config_value TEXT,
management_mode TEXT NOT NULL DEFAULT 'MANAGED',
actor_id INTEGER,
reason TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (site_id)
REFERENCES sites(id)
ON DELETE CASCADE
);
19. Example Overrides
site:
example.com
php_version:
8.4
backup_frequency:
hourly
health_monitoring:
true
20. Configuration Keys
Use standardized keys.
For example:
application.type
php.version
php.fpm_pool
web.document_root
ssl.enabled
ssl.auto_renew
backup.enabled
backup.frequency
backup.retention
health.enabled
health.interval
dns.managed
wordpress.management_mode
wordpress.core_policy
21. Avoid Free-Form Key Names
Don’t allow:
php
PHP
phpVersion
php_version
php-ver
to represent the same thing.
Use one canonical naming scheme.
22. Configuration Schema
CHP should define which keys are valid.
For example:
php.version
type:
STRING
allowed:
8.2
8.3
8.4
Another:
backup.enabled
type:
BOOLEAN
Another:
backup.retention_days
type:
INTEGER
minimum:
1
23. Why Validation Matters
Without validation someone could configure:
php.version = "banana"
The desired-state engine would accept invalid data.
Configuration must be validated before becoming active desired state.
24. Configuration Schema Table
Create:
CREATE TABLE config_schema (
id INTEGER PRIMARY KEY AUTOINCREMENT,
config_key TEXT NOT NULL UNIQUE,
value_type TEXT NOT NULL,
schema_definition TEXT,
description TEXT,
created_at TEXT NOT NULL
);
25. Example Schema
{
"config_key": "php.version",
"value_type": "string",
"allowed_values": [
"8.2",
"8.3",
"8.4"
]
}
26. Configuration Management Modes
Each configuration field should have a management mode.
Use:
MANAGED
CUSTOMER_MANAGED
READ_ONLY
LOCKED
27. MANAGED
CHP owns the configuration.
Example:
Nginx virtual host
If it drifts:
DRIFT
can generate a repair plan.
28. CUSTOMER_MANAGED
The customer owns the configuration.
Example:
WordPress plugins
CHP can observe it but shouldn’t automatically change it.
29. READ_ONLY
CHP can inspect but cannot modify.
Example:
external DNS
CHP may report:
DNS:
DRIFT
but cannot fix it because DNS isn’t managed by CHP.
30. LOCKED
A locked configuration cannot be overridden by ordinary users.
Example:
security policy
Platform administrators may control it.
31. Configuration Scope
A setting should also have a scope:
PLATFORM
PLAN
PROFILE
SITE
Example:
PHP default:
PLATFORM
PHP plan:
PLAN
PHP override:
SITE
32. Immutable Platform Defaults
Some values should not be changed at the site level.
Example:
allowed PHP versions
The platform can define:
8.2
8.3
8.4
A site cannot request:
7.4
if CHP has removed support for it.
33. Allowed Configuration
This gives us two concepts:
DESIRED VALUE
and:
ALLOWED VALUE
Desired state must always remain inside the allowed configuration space.
34. Example
Platform:
Allowed PHP:
8.3
8.4
Site requests:
PHP:
8.2
Result:
INVALID CONFIGURATION
Not:
DRIFT
because the desired state itself is invalid.
35. Configuration Lifecycle
A configuration change should follow:
REQUEST
↓
VALIDATE
↓
CALCULATE DESIRED STATE
↓
COMPARE
↓
PLAN
↓
APPROVE
↓
APPLY
↓
VERIFY
36. Configuration Status
A site configuration can have:
VALID
INVALID
PENDING
APPLIED
DRIFTED
But keep this separate from reconciliation status.
37. Configuration Version
Every final desired state should have:
config_version
Example:
example.com
configuration version:
17
38. Why Versioning Matters
Suppose an administrator requests:
PHP 8.4
and then another change:
PHP 8.3
before the first repair finishes.
Versioning lets CHP identify stale plans.
39. Configuration Revision
Use a revision record:
revision:
17
parent:
16
created by:
admin
reason:
Upgrade PHP
status:
ACTIVE
40. Configuration Revisions Table
CREATE TABLE config_revisions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
site_id INTEGER NOT NULL,
revision_number INTEGER NOT NULL,
configuration TEXT NOT NULL,
actor_id INTEGER,
reason TEXT,
status TEXT NOT NULL,
created_at TEXT NOT NULL,
FOREIGN KEY (site_id)
REFERENCES sites(id)
ON DELETE CASCADE,
UNIQUE(site_id, revision_number)
);
41. Revision Status
Use:
DRAFT
ACTIVE
SUPERSEDED
CANCELLED
Only one revision should normally be:
ACTIVE
for a site.
42. Example History
Revision 14
PHP 8.2
SUPERSEDED
Revision 15
PHP 8.3
SUPERSEDED
Revision 16
PHP 8.4
ACTIVE
43. Configuration Diff
When creating a new revision:
OLD:
PHP 8.3
NEW:
PHP 8.4
The system should automatically produce:
{
"php.version": {
"old": "8.3",
"new": "8.4"
}
}
44. Audit This Change
Changing desired configuration is security-sensitive.
Emit:
CONFIGURATION_CHANGED
Metadata:
{
"key": "php.version",
"old": "8.3",
"new": "8.4",
"revision": 16
}
45. Configuration Source
Every configuration value should ideally have a source.
Example:
php.version:
8.4
source:
SITE_OVERRIDE
Another:
backup.enabled:
true
source:
HOSTING_PLAN
46. Effective Configuration
The resolved output should contain:
{
"php.version": {
"value": "8.4",
"source": "SITE_OVERRIDE",
"management": "MANAGED"
},
"backup.enabled": {
"value": true,
"source": "HOSTING_PLAN",
"management": "MANAGED"
}
}
This is extremely useful when debugging.
47. Configuration Explanation
The CLI should support:
hosting-config explain example.com php.version
Output:
PHP Version
===========
Platform:
8.3
Plan:
8.3
Profile:
8.3
Site Override:
8.4
Effective Value:
8.4
Source:
SITE_OVERRIDE
Management:
MANAGED
48. This Solves a Common Problem
Without an explanation system, an administrator might ask:
Why is this site using PHP 8.4 when the plan says 8.3?
CHP can answer immediately:
Site override:
8.4
49. Configuration Command
Create:
sudo nano /usr/local/bin/hosting-config
Commands:
hosting-config show example.com
hosting-config explain example.com php.version
hosting-config validate example.com
hosting-config diff example.com
hosting-config history example.com
50. hosting-config show
Example:
CresignSys Configuration
========================
Site:
example.com
Plan:
Business
Profile:
WordPress Standard
PHP:
8.4
SSL:
Enabled
Backup:
Daily
Health Monitoring:
Enabled
WordPress Management:
Customer Managed
Configuration Revision:
16
51. hosting-config diff
This compares:
desired
vs
actual
Example:
PHP:
Desired 8.4
Actual 8.3
DRIFT
SSL:
Desired enabled
Actual enabled
MATCH
Backup:
Desired daily
Actual daily
MATCH
52. hosting-config validate
Before a desired state becomes active:
schema validation
+
platform compatibility
+
plan limits
+
site constraints
must pass.
53. Plan Limits
Suppose:
Business Plan:
5 GB
A site override requesting:
20 GB
should not automatically be accepted.
Possible result:
PLAN_LIMIT_EXCEEDED
The customer may need to upgrade.
54. Configuration Policy
Example:
{
"storage_gb": {
"max": 5
},
"backup_retention_days": {
"max": 30
}
}
This allows plan-specific restrictions.
55. Inheritance
Example:
Platform:
backup enabled = true
Plan:
backup frequency = daily
Profile:
backup retention = 14 days
Site:
backup frequency = hourly
Effective state:
backup enabled:
true
source PLATFORM
frequency:
hourly
source SITE
retention:
14 days
source PROFILE
56. Override Only What Is Needed
Don’t duplicate the entire plan into every site.
Bad:
{
"storage": 5,
"php": "8.3",
"ssl": true,
"backup": true,
"backup_frequency": "daily",
"health": true,
"php_override": "8.4"
}
Better:
{
"php.version": "8.4"
}
Everything else is inherited.
57. Prevent Override Explosion
A site could otherwise accumulate:
100 overrides
This becomes difficult to understand.
Use a policy:
Site overrides should be intentional exceptions, not a second configuration system.
58. Override Review
The dashboard should show:
Site Overrides:
3
For example:
PHP version:
8.4
Backup frequency:
hourly
Health interval:
30 sec
This makes exceptions visible.
59. Locked Fields
Suppose the platform requires:
SSL:
enabled
The customer should not be able to override:
ssl.enabled = false
because the field is:
LOCKED
60. Configuration Capability Matrix
Eventually CHP can determine:
PLATFORM PLAN SITE
PHP VERSION ✓ ✓ ✓
SSL ✓ ✓ -
BACKUP ✓ ✓ ✓
DNS ✓ - -
WORDPRESS PLUGINS ✓ - ✓
This defines where each setting can be controlled.
61. Configuration Templates
Instead of manually constructing plans, use templates.
Example:
wordpress-standard.json
wordpress-managed.json
static-site.json
php-custom.json
A template can define:
defaults
allowed values
management modes
62. Template Example
{
"name": "WORDPRESS_STANDARD",
"configuration": {
"application.type": "wordpress",
"health.enabled": true,
"backup.enabled": true,
"wordpress.management_mode": "CUSTOMER_MANAGED"
}
}
63. Managed WordPress Template
{
"name": "WORDPRESS_MANAGED",
"configuration": {
"application.type": "wordpress",
"health.enabled": true,
"backup.enabled": true,
"wordpress.management_mode": "MANAGED",
"wordpress.core_monitoring": true
}
}
64. Template Versioning
Templates should also be versioned.
Example:
WORDPRESS_STANDARD v1
WORDPRESS_STANDARD v2
A template update should not silently alter every production website without a controlled rollout.
65. Plan Changes
Suppose Business Plan changes:
PHP 8.3
to:
PHP 8.4
Should all sites immediately change?
No.
The desired state resolver should identify affected sites and generate a controlled transition.
66. Plan Migration
Use:
PLAN UPDATE
↓
AFFECTED SITES
↓
RECONCILIATION
↓
MIGRATION PLANS
This is safer than modifying production immediately.
67. Configuration Rollout
For large hosting environments:
120 sites
could be migrated:
10 sites
↓
monitor
↓
25 sites
↓
monitor
↓
50 sites
↓
120 sites
This is a future feature, but the configuration architecture should allow it.
68. Configuration Lock
Before a repair:
CONFIGURATION LOCK
can prevent another process from changing the same configuration simultaneously.
For example:
PHP upgrade
and:
PHP downgrade
should not run concurrently.
69. Lock Scope
Use locks at multiple levels:
SITE LOCK
CONFIGURATION DOMAIN LOCK
JOB LOCK
Example:
example.com
PHP
LOCKED
while PHP repair is running.
70. Avoid Global Locks
Don’t lock the entire CHP platform because one site is being repaired.
Bad:
example.com PHP repair
↓
ALL SITES LOCKED
Use narrow locks instead.
71. Configuration State Machine
A site configuration can move through:
ACTIVE
↓
CHANGE_REQUESTED
↓
VALIDATED
↓
PENDING_APPROVAL
↓
APPROVED
↓
APPLYING
↓
VERIFYING
↓
ACTIVE
If something fails:
APPLYING
↓
FAILED
↓
ROLLBACK
72. Desired State Should Reflect Reality Carefully
After a successful repair:
actual:
PHP 8.4
and:
desired:
PHP 8.4
now match.
But don’t simply set desired state to whatever actual state happens to be.
The desired state changes because an authorized configuration change occurred.
73. Manual Changes
Suppose an administrator manually changes:
PHP 8.3 → 8.4
outside CHP.
Reconciliation detects:
DRIFT
If the administrator then explicitly accepts the change, CHP can create:
CONFIGURATION_ACCEPTED
and update desired state.
This is called:
adopt actual state
74. Adopt Actual State
Command:
hosting-config adopt example.com php.version
Potential output:
Current desired:
8.3
Actual:
8.4
Accept actual value as desired?
YES
This should require appropriate authorization.
75. Never Automatically Adopt Everything
Otherwise:
desired:
PHP 8.3
attacker changes:
PHP 7.4
CHP:
"Actual must be desired!"
That would destroy the purpose of reconciliation.
Adoption must be explicit.
76. Configuration Security
Changes to:
PHP
Nginx
SSL
DNS
database
backup
should generate audit records.
At minimum:
actor
old value
new value
reason
revision
timestamp
77. Configuration API
Eventually:
GET /api/sites/{site}/config
and:
POST /api/sites/{site}/config/changes
But the API should submit a configuration change request, not directly modify production.
78. Change Request
The API should produce:
CHANGE REQUEST
↓
VALIDATE
↓
PLAN
↓
APPROVAL
↓
EXECUTION
This keeps the control plane safe.
79. Configuration Explanation Is Essential
Every final configuration value should be explainable:
What is the value?
Where did it come from?
Why is it this value?
Who can change it?
Is it managed?
What revision introduced it?
For example:
PHP:
8.4
Source:
Site Override
Management:
Managed
Revision:
16
Changed by:
Administrator
Reason:
Application compatibility
80. Final Configuration Model
The final desired configuration should look conceptually like:
{
"site": "example.com",
"revision": 16,
"configuration": {
"application": {
"type": "wordpress"
},
"web": {
"server": "nginx",
"document_root": "/storage/websites/example.com/public"
},
"php": {
"version": "8.4"
},
"ssl": {
"enabled": true,
"auto_renew": true
},
"backup": {
"enabled": true,
"frequency": "daily",
"retention_days": 14
},
"health": {
"enabled": true,
"interval_seconds": 60
},
"wordpress": {
"management_mode": "CUSTOMER_MANAGED"
}
}
}
This becomes the single desired-state document for the site.
81. Complete Configuration Flow
PLATFORM DEFAULT
│
▼
HOSTING PLAN
│
▼
SITE PROFILE
│
▼
SITE OVERRIDES
│
▼
VALIDATION
│
▼
CONFIG REVISION
│
▼
EFFECTIVE DESIRED STATE
│
▼
RECONCILIATION
│
▼
ACTUAL STATE
82. CHP Architecture After Lesson 094
The major components now connect:
CHP
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
CONFIGURATION OBSERVATION OPERATIONS
│ │ │
▼ ▼ ▼
DESIRED STATE HEALTH JOB QUEUE
│ │ │
└──────────┬───────┘ │
▼ ▼
RECONCILIATION WORKERS
│
▼
DRIFT
│
▼
PLAN
│
▼
APPROVAL
│
▼
BACKUP
│
▼
APPLY
│
▼
VERIFY
│
▼
RECONCILE
83. Lesson 094 — Core Principle
The Desired-State System should answer:
WHAT should this site look like?
The Reconciliation Engine answers:
IS it actually like that?
The Repair Engine will answer:
HOW can we safely make it like that?
And the Approval System answers:
ARE we authorized to do it?
So the complete CHP control model becomes:
DESIRED
↓
OBSERVE
↓
COMPARE
↓
DRIFT
↓
PLAN
↓
AUTHORIZE
↓
APPROVE
↓
BACKUP
↓
APPLY
↓
VERIFY
↓
RECONCILE
Next Lesson — 095
Build the CHP Repair Plan Engine
Now that CHP has:
Desired State
Actual State
Reconciliation
Drift Detection
Configuration Ownership
Configuration Versioning
we can finally construct the Repair Plan Engine.
It will transform:
DRIFT
into a structured, reviewable plan:
DRIFT
↓
REPAIR PLAN
↓
PRECONDITIONS
↓
IMPACT ANALYSIS
↓
BACKUP REQUIREMENT
↓
ORDERED OPERATIONS
↓
VERIFICATION
↓
ROLLBACK STRATEGY
For example:
Detected:
PHP desired = 8.4
PHP actual = 8.3
CHP should generate:
PLAN-00017
1. Verify PHP 8.4 is installed
2. Verify compatible PHP-FPM service
3. Create configuration backup
4. Update site PHP-FPM mapping
5. Validate Nginx configuration
6. Reload Nginx
7. Restart/reload PHP-FPM if required
8. Run health checks
9. Reconcile configuration
10. Mark plan successful
It will also handle:
PLAN_STALE
DEPENDENCY_FAILURE
CONFLICT
ROLLBACK_REQUIRED
VERIFICATION_FAILED
and establish the rule that a repair plan describes what CHP intends to do; it does not itself authorize or execute the change.
Leave a Reply