Service Brokers
What is a Service Broker?
Service broker is API server that implements Open Service Broker specification. It translates CF requests into service-specific operations.
cf create-service
↓
Cloud Controller
↓
Service Broker API (HTTP)
↓
Service Infrastructure
↓
Instance created, credentials returned
Service Broker Operations
Provision (Create Instance)
POST /v2/service_instances/{instance_id}
Body: {
"service_id": "...",
"plan_id": "...",
"organization_guid": "...",
"space_guid": "..."
}
Response: 201
{
"dashboard_url": "...",
"operation": "provision_in_progress"
}
Bind (Connect App to Instance)
PUT /v2/service_instances/{instance_id}/service_bindings/{binding_id}
Body: {
"service_id": "...",
"plan_id": "...",
"app_guid": "..."
}
Response: 201
{
"credentials": {
"uri": "postgresql://user:pass@host/dbname",
"username": "user",
"password": "pass",
"hostname": "host",
"port": 5432,
"database": "dbname"
}
}
Unbind (Disconnect App)
DELETE /v2/service_instances/{instance_id}/service_bindings/{binding_id}
Response: 200
Deprovision (Delete Instance)
DELETE /v2/service_instances/{instance_id}
Response: 200
Building a Simple Broker
Node.js example:
```javascript const express = require('express'); const app = express();
const instances = {}; // In-memory storage
app.use(express.json());
// Brokers typically require basic auth const auth = (req, res, next) => { const [user, pass] = Buffer.from( req.headers.authorization.slice(6) ).toString().split(':');
if (user === 'admin' && pass === 'secret') { next(); } else { res.status(401).json({ error: 'Unauthorized' }); } };
// Provision app.put('/v2/service_instances/:id', auth, (req, res) => { const { id } = req.params;
// Create actual service
const credentials = {
uri: postgresql://user:pass@localhost:5432/${id},
username: 'user',
password: 'pass',
database: id
};
instances[id] = credentials;
res.status(201).json({
dashboard_url: https://broker.example.com/instances/${id},
operation: 'provision'
});
});
// Bind app.put('/v2/service_instances/:instanceId/service_bindings/:bindingId', auth, (req, res) => { const { instanceId, bindingId } = req.params;
if (!instances[instanceId]) { return res.status(404).json({ error: 'Instance not found' }); }
res.status(201).json({ credentials: instances[instanceId] }); });
// Unbind app.delete('/v2/service_instances/:instanceId/service_bindings/:bindingId', auth, (req, res) => { res.status(200).json({}); });
// Deprovision app.delete('/v2/service_instances/:id', auth, (req, res) => { delete instances[req.params.id]; res.status(200).json({}); });
app.listen(3000); ```
Registering Service Broker
```bash
Register broker with CF
cf create-service-broker my-broker \ admin secret \ https://broker.example.com
Enable public access
cf enable-service-access my-service -b my-broker
Check marketplace
cf marketplace service plans description my-service free My Custom Service ```
Marketplace Metadata
Service broker advertises capabilities:
GET /v2/catalog
Response:
{
"services": [{
"id": "service-1",
"name": "my-database",
"description": "My Custom Database",
"plans": [{
"id": "plan-1",
"name": "free",
"description": "Free plan"
}, {
"id": "plan-2",
"name": "paid",
"description": "Paid plan"
}]
}]
}
Built-In Brokers
PCF typically includes brokers for:
- PostgreSQL
- MySQL
- Redis
- RabbitMQ
- MongoDB (with extensions)
Best Practices
- Idempotence: Same request twice should be safe
- Cleanup: Delete all resources on deprovision
- Credentials: Generate unique credentials per binding
- Documentation: Document broker behavior
- Logging: Log all requests
- Security: Require authentication, use HTTPS
- Error Handling: Return standard HTTP codes
Advanced: Async Operations
For long-running operations:
```javascript // Return 202 Accepted with operation ID res.status(202).json({ operation: "provisioning-database", state: "in progress" });
// Cloud Controller polls for completion GET /v2/service_instances/{id}/last_operation?operation=... Response: { "state": "in progress", // or "succeeded" or "failed" "description": "Creating database..." } ```
For hands-on service usage: Lab 3: Service Binding.