Installation Add the bundle to your Laravel project via Composer:
composer require dealroadshow/keda-bundle
Register the bundle in config/bundles.php:
return [
// ...
DealRoadshow\KedaBundle\KedaBundle::class,
];
First Use Case: Define a KEDA ScaledObject
Create a PHP class to define a KEDA ScaledObject (e.g., app/Keda/RedisScaler.php):
use DealRoadshow\KedaBundle\KedaBundle;
use K8sBundle\K8sBundle;
use K8sBundle\Yaml\Yaml;
class RedisScaler extends KedaBundle
{
public function getYaml(): string
{
return Yaml::dump([
'apiVersion' => 'keda.sh/v1alpha1',
'kind' => 'ScaledObject',
'metadata' => [
'name' => 'redis-scaler',
],
'spec' => [
'scaleTargetRef' => [
'name' => 'redis-deployment',
],
'triggers' => [
[
'type' => 'redis',
'metadata' => [
'address' => 'redis-master',
'port' => '6379',
],
],
],
],
]);
}
}
Apply the CRD
Use the k8s-bundle CLI to apply the YAML:
php artisan k8s:apply --bundle=RedisScaler
Define Resources as PHP Classes
Extend KedaBundle and implement getYaml() to define KEDA resources (e.g., ScaledObject, TriggerAuthentication).
Example: app/Keda/PostgresScaler.php
class PostgresScaler extends KedaBundle
{
public function getYaml(): string
{
return Yaml::dump([
'apiVersion' => 'keda.sh/v1alpha1',
'kind' => 'ScaledObject',
'metadata' => [
'name' => 'postgres-scaler',
],
'spec' => [
'scaleTargetRef' => [
'name' => 'postgres-deployment',
],
'triggers' => [
[
'type' => 'postgres',
'metadata' => [
'host' => 'postgres-service',
'port' => '5432',
'database' => 'app-db',
'query' => 'SELECT COUNT(*) FROM orders',
],
],
],
],
]);
}
}
Dynamic Configuration via Artisan Commands Use Laravel’s Artisan commands to parameterize KEDA resources:
// app/Console/Commands/DeployKedaScaler.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use DealRoadshow\KedaBundle\KedaBundle;
class DeployKedaScaler extends Command
{
protected $signature = 'keda:deploy {name} {--target=} {--min=0} {--max=100}';
protected $description = 'Deploy a KEDA ScaledObject dynamically';
public function handle()
{
$yaml = Yaml::dump([
'apiVersion' => 'keda.sh/v1alpha1',
'kind' => 'ScaledObject',
'metadata' => ['name' => $this->argument('name')],
'spec' => [
'scaleTargetRef' => ['name' => $this->option('target')],
'minReplicaCount' => (int) $this->option('min'),
'maxReplicaCount' => (int) $this->option('max'),
'triggers' => [...],
],
]);
// Save to a temporary bundle class or file
file_put_contents(
storage_path("app/keda/{$this->argument('name')}.php"),
"<?php namespace App\Keda; use DealRoadshow\KedaBundle\KedaBundle; class {$this->argument('name')} extends KedaBundle { public function getYaml() { return '$yaml'; } }"
);
$this->call('k8s:apply', ['--bundle' => $this->argument('name')]);
}
}
Integration with Laravel Services Use KEDA triggers to scale based on Laravel events or queues:
ScaledObject triggered by a queue (e.g., rabbitmq or aws-sqs):
'triggers' => [
[
'type' => 'aws-sqs',
'metadata' => [
'queueURL' => env('AWS_SQS_QUEUE_URL'),
'queueLength' => '10',
],
],
],
cronjob trigger to scale based on Laravel scheduled tasks:
'triggers' => [
[
'type' => 'cronjob',
'metadata' => [
'cronExpression' => '0 * * * *', // Every minute
'timeZone' => 'UTC',
],
],
],
Reusable Templates
Create base classes for common KEDA resources (e.g., app/Keda/BaseScaledObject.php):
abstract class BaseScaledObject extends KedaBundle
{
protected $defaultSpec = [
'scaleTargetRef' => ['name' => ''],
'minReplicaCount' => 0,
'maxReplicaCount' => 100,
'triggers' => [],
];
public function getYaml(): string
{
return Yaml::dump([
'apiVersion' => 'keda.sh/v1alpha1',
'kind' => 'ScaledObject',
'metadata' => ['name' => $this->getName()],
'spec' => $this->getSpec(),
]);
}
abstract protected function getName(): string;
abstract protected function getSpec(): array;
}
KEDA CRD Validation
kubectl get scaledobject <name> -o yaml to debug validation errors.Namespace Conflicts
default, specify it in metadata:
'metadata' => [
'name' => 'redis-scaler',
'namespace' => 'production',
],
k8s-bundle is configured to target the correct namespace.Dependency on k8s-bundle
k8s-bundle for YAML serialization and Kubernetes integration.k8s-bundle updated and verify compatibility with your Laravel/Kubernetes versions.Trigger Authentication
aws-sqs, azure-queue) require authentication.triggerAuthentication in your ScaledObject:
'spec' => [
'triggerAuthentication' => [
'secretTargetRef' => [
'name' => 'aws-credentials',
'key' => 'credentials',
],
],
'triggers' => [...],
],
Dry Runs
Use k8s:apply --dry-run to preview changes before applying:
php artisan k8s:apply --bundle=RedisScaler --dry-run
Logs and Events Check KEDA logs for scaling events:
kubectl logs -l app.kubernetes.io/instance=keda-operator
Describe Resources Inspect live resources to debug issues:
kubectl describe scaledobject redis-scaler
Environment-Specific Configs
Use Laravel’s .env to parameterize KEDA resources:
'metadata' => [
'name' => env('KEDA_SCALER_NAME', 'default-scaler'),
],
'spec' => [
'triggers' => [
[
'metadata' => [
'address' => env('REDIS_HOST'),
],
],
],
],
Leverage Laravel Migrations Sync KEDA resources with Laravel migrations:
How can I help you explore Laravel packages today?