Cloud 4.01

Service Configuration

Creating and configuring system services (MySQL, Redis, Elasticsearch, RabbitMQ) with the critical _merge flag.

Exam Critical: Understanding how to configure services (MySQL, Redis, Elasticsearch, RabbitMQ) is essential for the AD0-E717 exam! Know the _merge flag, environment configuration options, and Pro vs Starter differences.

Service Configuration

mindmap root((Service Config)) Basic Syntax type servicename version disk minimum 256MB Relationships Map to access points app.yaml connections Merge Flag merge true preserve merge false overwrite MySQL Multiple databases Custom endpoints User privileges Redis Runtime extension Relationship config Tunnel access Elasticsearch Plugin configuration Version selection RabbitMQ Cloud provided External queue option Pro Limitation Integration only Support ticket Staging Prod

Service Configuration Overview

Two-Step Process

Step 1: Enable in services.yaml

Define service type, version, and disk space

Step 2: Map in app.yaml

Create relationships to make services accessible

Pro Cloud Limitation

services.yaml and relationship changes in app.yaml only affect Integration environment on Pro accounts!

To change services in Pro Staging or Production, you must file a support ticket. This does NOT apply to Starter hosting.

Basic Service Syntax

services.yaml Configuration

elasticsearch:
    type: elasticsearch:6.5
    disk: 1024

Configuration Elements

  • Service name: Identifier (e.g., elasticsearch, rabbitmq)
  • type: Service name with required version (servicename:version)
  • disk: Disk allotment in megabytes (minimum 256MB)

Minimum Disk Space

If you don't specify enough disk space (minimum 256MB), you'll get strange errors:

  • MySQL: "MySQL server has gone away" (not helpful!)
  • Other services: Various cryptic failures

Mapping Services with Relationships

app.yaml Relationships

After configuring services in services.yaml, map them to useable "access points" in .magento.app.yaml:

relationships:
    database: "mysql:mysql"
    redis: "redis:redis"
    elasticsearch: "elasticsearch:elasticsearch"
    rabbitmq: "rabbitmq:rabbitmq"

Relationship Format

relationship_name: "service_name:endpoint"

  • relationship_name: How your application references it
  • service_name: Name from services.yaml
  • endpoint: Service endpoint (usually matches service type)

The _merge Flag (Critical)

Understanding _merge Behavior

_merge Setting Behavior
_merge: true Values are merged with app/etc/env.php
_merge not set (default) Section in app/etc/env.php is overwritten

Example: The Wrong Way (Without _merge)

.magento.env.yaml

stage:
    deploy:
        DATABASE_CONFIGURATION:
            username: 'my_user'

Result in app/etc/env.php (BROKEN)

'db' => array (
    'connection' => array (
        'default' => array (
            'username' => 'my_user'
            // Missing: host, dbname, password!
        )
    ),
),

Problem

Magento cannot connect to database - missing host, dbname, and password!

Example: The Right Way (With _merge)

.magento.env.yaml

stage:
    deploy:
        DATABASE_CONFIGURATION:
            username: 'my_user'
            _merge: true

Result in app/etc/env.php (CORRECT)

'db' => array (
    'connection' => array (
        'default' => array (
            'username' => 'my_user',    // Changed
            'host' => 'database.internal', // Preserved
            'dbname' => 'main',           // Preserved
            'password' => '',             // Preserved
        )
    ),
),

Solution

All configuration details are preserved and merged with your custom values!

Common Use Cases for _merge

  • External database connection: Add external DB while preserving defaults
  • Elasticsearch configuration: Specify custom connection details
  • Table prefix: Add table_prefix without losing other config
  • Any *_CONFIGURATION option: Safely extend configuration

Best Practice

Always use _merge: true when using *_CONFIGURATION variables unless you explicitly want to replace the entire section.

MySQL Configuration

Basic MySQL Setup

# .magento/services.yaml
mysql:
    type: mysql:10.4
    disk: 2048
# .magento.app.yaml
relationships:
    database: "mysql:mysql"

Multiple MySQL Databases

Cloud can have multiple databases by specifying unique endpoints (users):

# .magento/services.yaml
mysql:
    type: mysql:10.4
    disk: 2048
    configuration:
        schemas:
            - main
            - analytics
        endpoints:
            mysql:
                default_schema: main
                privileges:
                    main: admin
                    analytics: admin
            readonly:
                default_schema: main
                privileges:
                    main: ro
                    analytics: ro
# .magento.app.yaml
relationships:
    database: "mysql:mysql"
    database_readonly: "mysql:readonly"

What This Creates

  • mysql endpoint: Full admin privileges on both schemas
  • readonly endpoint: Read-only (SELECT) on both schemas

Default Endpoint Behavior

By default, the endpoint is mysql. However, with default configuration, you can use any value or leave it empty for the username.

Redis Configuration

Prerequisites

To use Redis, ensure you configure:

  1. runtime/extensions/redis in .magento.app.yaml
  2. relationships/redis in .magento.app.yaml

Basic Redis Setup

# .magento/services.yaml
redis:
    type: redis:6.0
    disk: 256
# .magento.app.yaml
runtime:
    extensions:
        - redis
        - xsl
        - imagick

relationships:
    redis: "redis:redis"

Accessing Redis Locally

Use SSH tunneling to connect from your local machine:

magento-cloud tunnel:open

Then connect with redis-cli:

redis-cli -h 127.0.0.1 -p [PORT_FROM_TUNNEL]

Elasticsearch Configuration

Basic Elasticsearch Setup

# .magento/services.yaml
elasticsearch:
    type: elasticsearch:7.7
    disk: 1024
# .magento.app.yaml
relationships:
    elasticsearch: "elasticsearch:elasticsearch"

Configuring Elasticsearch Plugins

You can configure Elasticsearch plugins in services.yaml:

# .magento/services.yaml
elasticsearch:
    type: elasticsearch:7.7
    disk: 1024
    configuration:
        plugins:
            - analysis-icu
            - analysis-phonetic

Configuration Path

.magento/services.yaml → elasticsearch/configuration/plugins

RabbitMQ Configuration

Option 1: Cloud-Provided RabbitMQ

# .magento/services.yaml
rabbitmq:
    type: rabbitmq:3.8
    disk: 512
# .magento.app.yaml
relationships:
    rabbitmq: "rabbitmq:rabbitmq"

Option 2: External Queue (via Environment Variable)

Use QUEUE_CONFIGURATION environment variable to specify an external queue:

# .magento.env.yaml
stage:
    deploy:
        QUEUE_CONFIGURATION:
            amqp:
                host: 'external-rabbitmq.example.com'
                port: 5672
                user: 'guest'
                password: 'guest'
                virtualhost: '/'
            _merge: true

Choice

You can either allow Commerce Cloud to provide RabbitMQ, or use an external queue service.

Environment Configuration Variables

Available *_CONFIGURATION Options

Variable Purpose
DATABASE_CONFIGURATION Customize database connection
QUEUE_CONFIGURATION Configure message queue (RabbitMQ)
CACHE_CONFIGURATION Configure cache backend (Redis)
SESSION_CONFIGURATION Configure session storage (Redis)
SEARCH_CONFIGURATION Configure search engine (Elasticsearch)

Remember _merge!

Always include _merge: true with *_CONFIGURATION variables to preserve existing configuration.

Practical Experience Tasks

Hands-On Practice

  1. Configure two MySQL users: One with all privileges, another with SELECT-only access
  2. Set up Redis tunneling: Use magento-cloud tunnel:open and connect with redis-cli
  3. Add Elasticsearch plugin: Configure analysis-icu plugin
  4. Test _merge flag: Add custom DATABASE_CONFIGURATION with and without _merge to see the difference

Best Practices

Do's
  • Always use _merge: true with *_CONFIGURATION
  • Specify minimum 256MB disk for services
  • Include redis extension in runtime/extensions
  • Test in Integration before Staging/Production
  • Use tunnel:open for local service access
  • Document custom configurations
  • File support ticket for Pro Staging/Production
Don'ts
  • Don't use *_CONFIGURATION without _merge
  • Don't specify less than 256MB disk
  • Don't forget redis runtime extension
  • Don't expect services.yaml to work in Pro Staging/Prod
  • Don't skip relationship mapping
  • Don't use incompatible service versions
  • Don't forget to test configuration changes

Exam Tips

Key Points to Remember

  • Basic syntax: type: servicename:version, disk: size_in_mb
  • Minimum disk: 256MB (errors if less)
  • Two-step process: Configure in services.yaml, map in app.yaml relationships
  • Pro limitation: services.yaml only affects Integration (need support ticket for Staging/Production)
  • Starter: No such limitation, works in all environments
  • _merge: true: Merges with app/etc/env.php (CRITICAL!)
  • _merge not set: Overwrites entire section (usually breaks things)
  • MySQL endpoints: Can configure multiple users with different privileges
  • MySQL default endpoint: mysql (can use any value with default config)
  • Redis requirements: runtime/extensions/redis AND relationships/redis
  • Redis access: Use magento-cloud tunnel:open, then redis-cli
  • Elasticsearch plugins: Configure at elasticsearch/configuration/plugins
  • RabbitMQ options: Cloud-provided OR external via QUEUE_CONFIGURATION
  • *_CONFIGURATION variables: DATABASE, QUEUE, CACHE, SESSION, SEARCH
  • Always use: _merge: true with *_CONFIGURATION variables