Drupal Recipe Development Guide
Complete guide for developing and managing Drupal recipes for the LLM Platform.
Table of Contents
Overview
Drupal recipes provide a standardized way to install and configure Drupal sites with predefined sets of modules, configuration, and content. The LLM Platform uses recipes to deploy consistent AI-powered environments.
Key Concepts
- Recipe: A YAML-based blueprint for site setup
- Sub-Recipe: Modular recipe components that can be composed
- Recipe Onboarding: Module for managing recipe deployment
- Validation: Automated checks for recipe integrity
Recipe Structure
Basic Recipe
recipe_name/
├── recipe.yml # Main recipe definition
├── README.md # Documentation
├── config/ # Configuration files
│ ├── install/ # Config to import on install
│ └── update/ # Config updates
├── content/ # Default content
│ └── node/
├── modules/ # Custom modules for this recipe
├── subrecipes/ # Modular sub-recipes
│ ├── core/
│ ├── api/
│ └── security/
└── tests/ # Recipe tests
└── RecipeTest.php
Recipe Definition (recipe.yml)
name: 'Recipe Name'
description: 'Clear description of what this recipe provides'
type: 'Site'
version: '1.0.0'
# Module dependencies
install:
- drupal:system
- drupal:user
- drupal:node
- ai:ai
- ai_agents:ai_agents
- mcp_registry:mcp_registry
- recipe_onboarding:recipe_onboarding
# Configuration to apply
config:
import:
# Core system config
system.site:
name: 'LLM Platform'
mail: 'admin@example.com'
slogan: 'AI-Powered Enterprise Platform'
# Module-specific config
ai.settings:
default_provider: 'openai'
cache_enabled: true
actions:
# Set module config
ai.provider.openai.settings:
model: 'gpt-4'
temperature: 0.7
# Content to create
content:
node:
- type: page
title: 'Welcome'
body:
value: '<p>Welcome to the LLM Platform</p>'
format: 'full_html'
# Roles and permissions
roles:
ai_user:
label: 'AI User'
permissions:
- 'access ai interface'
- 'execute ai workflows'
# Sub-recipes to apply
recipes:
- './subrecipes/core'
- './subrecipes/security'
- './subrecipes/api'
Development Workflow
1. Recipe Location
Source Location (edit here):
/Users/flux423/Sites/LLM/all_drupal_custom/recipes/recipe_name/
Deployment Location:
/Users/flux423/Sites/LLM/llm-platform/recipes/recipe_name/
2. Create New Recipe
# Manual creation
mkdir -p /Users/flux423/Sites/LLM/all_drupal_custom/recipes/my_recipe
cd /Users/flux423/Sites/LLM/all_drupal_custom/recipes/my_recipe
# Create recipe.yml
cat > recipe.yml << 'EOF'
name: 'My Recipe'
description: 'Recipe description'
type: 'Site'
version: '1.0.0'
install: []
EOF
# Create README
cat > README.md << 'EOF'
# My Recipe
Description of recipe functionality.
EOF
3. Apply Recipe
# Apply recipe to site
drush recipe recipes/my_recipe
# Apply with specific options
drush recipe recipes/my_recipe --no-cache --verbose
4. Validation
# Validate recipe structure
drush recipe:validate recipes/my_recipe
# Via recipe_onboarding module
drush recipe-onboarding:validate recipes/my_recipe
Sub-Recipes
Sub-recipes provide modular components that can be composed into larger recipes.
Sub-Recipe Structure
subrecipes/
├── core/
│ ├── recipe.yml
│ └── config/
├── security/
│ ├── recipe.yml
│ └── config/
└── api/
├── recipe.yml
└── config/
Core Sub-Recipe Example
# subrecipes/core/recipe.yml
name: 'LLM Core Foundation'
description: 'Core LLM platform modules and configuration'
type: 'Configuration'
version: '1.0.0'
install:
- drupal:system
- drupal:user
- drupal:node
- drupal:field
- drupal:serialization
- drupal:rest
- drupal:jsonapi
config:
import:
system.performance:
cache:
page:
max_age: 3600
css:
preprocess: true
js:
preprocess: true
Security Sub-Recipe Example
# subrecipes/security/recipe.yml
name: 'LLM Security Framework'
description: 'Security hardening and compliance'
type: 'Configuration'
version: '1.0.0'
install:
- security_review:security_review
- seckit:seckit
- password_policy:password_policy
- autologout:autologout
- tfa:tfa
config:
import:
seckit.settings:
seckit_xss:
csp:
checkbox: true
policy: "default-src 'self'"
seckit_csrf:
origin: true
password_policy.policy.admin:
label: 'Admin Password Policy'
password_length: 12
character_types: 3
API Management Sub-Recipe
# subrecipes/api/recipe.yml
name: 'API Management'
description: 'REST, GraphQL, and API tooling'
type: 'Configuration'
version: '1.0.0'
install:
- drupal:rest
- drupal:jsonapi
- drupal:serialization
- graphql:graphql
- graphql_compose:graphql_compose
- openapi_ui:openapi_ui
- openapi_ui_redoc:openapi_ui_redoc
- simple_oauth:simple_oauth
- api_normalizer:api_normalizer
config:
import:
rest.settings:
bc_entity_resource_permissions: false
link_domain: ~
Validation
Recipe Onboarding Module
The recipe_onboarding module provides comprehensive validation:
# Install recipe_onboarding
drush en recipe_onboarding -y
# Validate recipe
drush recipe-onboarding:validate recipes/my_recipe
# List available recipes
drush recipe-onboarding:list
# Get recipe info
drush recipe-onboarding:info recipes/my_recipe
Validation Checks
- Syntax: YAML is valid
- Structure: Required fields present
- Dependencies: Modules exist and are available
- Config: Configuration schemas are valid
- Content: Content types and fields exist
- Sub-Recipes: Referenced sub-recipes exist
Manual Validation
# Check YAML syntax
php -r "yaml_parse_file('recipe.yml');"
# Verify modules exist
drush pm:list --type=module | grep module_name
# Test config import
drush config:import --partial --source=recipes/my_recipe/config/install
Deployment
1. Recipe Testing
# Test on fresh install
lando rebuild -y
drush si minimal -y
drush recipe recipes/my_recipe
drush uli
# Verify installation
drush pm:list --type=module --status=enabled
drush config:status
2. Production Deployment
# Export recipe to production
rsync -av recipes/my_recipe/ production:/var/www/html/recipes/my_recipe/
# Apply on production
ssh production "cd /var/www/html && drush recipe recipes/my_recipe"
3. CI/CD Integration
# .gitlab-ci.yml
test-recipe:
stage: test
script:
- composer install
- drush si minimal -y
- drush recipe recipes/my_recipe
- drush status
Examples
LLM Platform Recipe
The main platform recipe with sub-recipes:
# recipes/llm_platform/recipe.yml
name: 'LLM Platform'
description: 'Complete LLM Platform installation with AI agents, workflows, and APIs'
type: 'Site'
version: '1.0.0'
# Sub-recipes provide modular components
recipes:
- './subrecipes/llm_core_foundation'
- './subrecipes/llm_security_framework'
- './subrecipes/llm_model_integration'
- './subrecipes/api_management'
- './subrecipes/ecosystem_orchestration'
- './subrecipes/llm_user_workflows'
- './subrecipes/llm_langflow_integration'
# Main recipe modules
install:
- ai_agentic_workflows:ai_agentic_workflows
- ai_agents_orchestra:ai_agents_orchestra
- mcp_registry:mcp_registry
- code_executor:code_executor
- gov_compliance:gov_compliance
config:
import:
system.site:
name: 'LLM Platform'
mail: 'admin@llm.local'
slogan: 'Enterprise AI Platform'
roles:
llm_admin:
label: 'LLM Administrator'
permissions:
- 'administer llm platform'
- 'manage ai agents'
- 'configure mcp registry'
Secure Drupal Recipe
Security-focused recipe:
# recipes/secure_drupal/recipe.yml
name: 'Secure Drupal'
description: 'Hardened Drupal with security best practices'
type: 'Site'
version: '1.0.0'
install:
- security_review:security_review
- seckit:seckit
- password_policy:password_policy
- tfa:tfa
- autologout:autologout
- login_security:login_security
- paranoia:paranoia
config:
import:
seckit.settings:
seckit_xss:
csp:
checkbox: true
seckit_various:
from_origin: true
referrer_policy: true
password_policy.policy.default:
label: 'Default Password Policy'
password_length: 14
character_types: 4
autologout.settings:
timeout: 900
max_timeout: 1800
Recipe Management Commands
Drush Commands
# List all recipes
drush recipe:list
# Apply recipe
drush recipe recipes/my_recipe
# Validate recipe
drush recipe:validate recipes/my_recipe
# Export current config as recipe
drush recipe:export --name=my_recipe --destination=recipes/
# Show recipe info
drush recipe:info recipes/my_recipe
# Rollback recipe (if supported)
drush recipe:rollback recipes/my_recipe
Recipe Onboarding Commands
# Enable recipe onboarding
drush en recipe_onboarding -y
# List recipes
drush recipe-onboarding:list
# Deploy recipe with sub-recipe support
drush recipe-onboarding:deploy recipes/llm_platform
# Validate complex recipe
drush recipe-onboarding:validate recipes/llm_platform --strict
# Show recipe tree
drush recipe-onboarding:tree recipes/llm_platform
Best Practices
1. Modular Design
Use sub-recipes for reusable components:
recipes/
├── llm_platform/ # Main platform recipe
│ ├── recipe.yml
│ └── subrecipes/
│ ├── core/ # Core functionality
│ ├── security/ # Security hardening
│ ├── api/ # API management
│ └── ai/ # AI integration
└── secure_drupal/ # Security-focused recipe
└── recipe.yml
2. Version Control
Track recipe changes in git:
cd recipes/my_recipe
git add recipe.yml config/ README.md
git commit -m "feat: add AI provider configuration"
3. Documentation
Include comprehensive README:
# Recipe Name
## Purpose
What this recipe provides
## Requirements
- Drupal ^10.3 || ^11
- PHP 8.1+
- Required modules
## Installation
drush recipe recipes/my_recipe
## Configuration
Post-installation steps
## Troubleshooting
Common issues and solutions
4. Testing
Test recipes thoroughly:
# Test on fresh install
lando rebuild -y
drush si minimal -y
drush recipe recipes/my_recipe
# Verify functionality
drush pm:list --status=enabled
drush config:status
drush watchdog:show
Troubleshooting
Common Issues
Missing Dependencies
# Error: Module 'example' not found
# Fix: Add to composer.json and install
composer require drupal/example
Config Import Errors
# Error: Unknown configuration schema
# Fix: Clear cache and retry
drush cr
drush recipe recipes/my_recipe
Sub-Recipe Not Found
# Error: Sub-recipe './subrecipes/core' does not exist
# Fix: Verify path is relative to recipe.yml
recipes:
- './subrecipes/core' # Relative path