← Documentation Home

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 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

  1. Syntax: YAML is valid
  2. Structure: Required fields present
  3. Dependencies: Modules exist and are available
  4. Config: Configuration schemas are valid
  5. Content: Content types and fields exist
  6. 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

Resources

See Also