Start a conversation

Chef recipe compatibility: Stack v7 vs Stack v8

<supportagent>This is the customer-facing version. Support should refer to the source engineering document:  https://github.com/trilogy-group/ey-all/blob/main/docs/kb-chef-recipes-v7-vs-v8.md</supportagent>

This article is for Engine Yard Cloud customers who maintain their own custom Chef recipes and are moving from Stack v7 (Ubuntu 20.04) to Stack v8 (Ubuntu 24.04).

Who needs this article

The Engine Yard managed cookbooks are updated for Stack v8 by Engine Yard. You only need this article if you maintain your own custom Chef recipes that run alongside the managed stack. It lists the recipe-level differences between Ubuntu 20.04 (v7) and Ubuntu 24.04 (v8) — the concrete things a custom recipe written for v7 will encounter on v8. If your custom recipes do not touch a given subsystem, you can skip that section.

1. Operating system and system services

SSH is socket-activated; manage it as ssh.service, not sshd

On Ubuntu 24.04, the OpenSSH server systemd unit is ssh.service, and OpenSSH is socket-activated by default (ssh.socket starts ssh.service on the first inbound connection). The Noble unit still declares Alias=sshd.service, so sshd.service is not gone — but under socket activation, managing SSH by the sshd name (or issuing systemctl restart sshd) does not behave the way a v7 recipe expects, and can leave the socket unit and the service unit out of sync. Manage SSH by its canonical ssh / ssh.service name instead:

# Unreliable on v8 (Noble): sshd is only an alias, and SSH is socket-activated
systemctl restart sshd

# Correct on v8
systemctl restart ssh

Action: update any custom recipe (or service resource) that manages SSH to use ssh / ssh.service, not sshd / sshd.service, and account for socket activation (ssh.socket) rather than assuming a long-running sshd daemon.

IMDSv2 is required (instance metadata)

The v8 base images default the instance metadata service to IMDSv2 required (HttpTokens=required). Legacy IMDSv1 requests — a plain GET to http://169.254.169.254/... with no token — return HTTP 401 on v8. Any custom recipe that reads EC2 instance metadata must use the IMDSv2 token handshake: first PUT to obtain a session token, then send that token on the metadata GET.

# v8: obtain a session token, then use it
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id

Action: update any custom recipe that queries instance metadata to perform the IMDSv2 token handshake, keep an IMDSv1 fallback for older environments, and fail closed if metadata cannot be read.

2. MySQL (8.0 to 8.4)

Stack v8 offers MySQL 8.4. Beyond the authentication-plugin change covered in the migration guide, MySQL 8.4 turns several previously deprecated replication statements into hard syntax errors. Custom recipes that manage replication, backups, or that issue replication SQL must be updated.

Replication SQL renamed (the MASTER/SLAVE keywords are gone)

Removed on 8.4 (v7 spelling) Use on 8.4 (v8 spelling)
CHANGE MASTER TO ... CHANGE REPLICATION SOURCE TO ...
START SLAVE / STOP SLAVE START REPLICA / STOP REPLICA
SHOW SLAVE STATUS SHOW REPLICA STATUS
MASTER_LOG_FILE / MASTER_LOG_POS SOURCE_LOG_FILE / SOURCE_LOG_POS

A recipe that renders any of the left-hand statements will produce a SQL syntax error on 8.4. This is the change most likely to break custom replication or disaster-recovery recipes.

If your recipes parse SHOW REPLICA STATUS output, note that 8.4 also renamed the output fields: Slave_IO_RunningReplica_IO_Running, Slave_SQL_RunningReplica_SQL_Running, Seconds_Behind_MasterSeconds_Behind_Source, and Relay_Master_Log_FileRelay_Source_Log_File.

innobackupex removed → use xtrabackup

The innobackupex wrapper was removed in Percona XtraBackup 8.x. On v8 (which uses Percona XtraBackup 8.4, matching the server major), call xtrabackup directly:

# v7
innobackupex --apply-log --use-memory=1G /db/mysql/8.0/data/

# v8 (XtraBackup 8.4)
xtrabackup --prepare --use-memory=1G --target-dir=/db/mysql/8.4/data/

Note also that the XtraBackup major version must match the MySQL server major — XtraBackup 8.0 cannot back up an 8.4 server.

my.cnf variables: removed (fatal) vs deprecated (warn)

MySQL/Percona 8.4 treats two classes of stale configuration differently, and it matters for how urgently a custom recipe must be fixed. If a custom recipe writes a user.cnf (or otherwise injects MySQL config), review both classes.

Removed variables — MySQL 8.4 refuses to start. If the configuration references one of these, MySQL exits with a fatal "unknown variable" error at startup. Remove these before the first 8.4 boot:

  • default_authentication_plugin — removed; the auth default is now caching_sha2_password.
  • expire_logs_days — removed; use binlog_expire_logs_seconds instead.
  • query_cache_* (e.g. query_cache_size, query_cache_type) — the query cache was removed back in MySQL 8.0, so these are fatal for any recipe carried over from a 5.7 origin.

Deprecated variables — MySQL 8.4 starts, but warns. These still function on 8.4 and do not block startup; they emit a deprecation warning and are slated for removal in a later release. Update them at your convenience:

  • innodb_log_file_size, innodb_log_files_in_group — superseded by innodb_redo_log_capacity.
  • the slave_* family (e.g. slave_parallel_workers) — superseded by the replica_* equivalents.
  • log-slave-updates — superseded by log_replica_updates.

Only the removed variables above will actually prevent MySQL 8.4 from starting; updating the deprecated ones is good hygiene but not required to boot.

3. PostgreSQL (14 to 16)

Stack v8 offers PostgreSQL 16 (Engine Yard's managed v7 PostgreSQL was 14). Application data migrates cleanly across 14 to 16 via dump/restore; the recipe-level changes are in standby promotion and the backup functions.

promote_trigger_file removed → use pg_promote()

promote_trigger_file was removed in PostgreSQL 16. A postgresql.conf that sets it emits an unknown-parameter error, and any promotion logic that works by touching a trigger file no longer functions. Promote a standby with pg_promote() (or pg_ctl promote):

-- v8 (PG16): promote directly
SELECT pg_promote();

Action: remove any promote_trigger_file setting from custom PostgreSQL config, and replace trigger-file promotion logic with pg_promote().

Backup functions renamed (pg_start_backup/pg_stop_backup → pg_backup_start/pg_backup_stop)

PostgreSQL 15 renamed the low-level backup functions: pg_start_backup()pg_backup_start() and pg_stop_backup()pg_backup_stop(). The old names were removed, not aliased, so a custom recipe that still calls pg_start_backup() / pg_stop_backup() fails on PG16 with a "function does not exist" error. This affects v7 customers whose managed PostgreSQL was 14, because they move straight to 16 and never saw the intermediate rename.

-- v7 (PG14): old spelling, removed on 16
SELECT pg_start_backup('label');
SELECT pg_stop_backup();

-- v8 (PG16): current spelling
SELECT pg_backup_start('label');
SELECT pg_backup_stop();

Action: in any custom backup recipe, replace pg_start_backup/pg_stop_backup with pg_backup_start/pg_backup_stop. The rest of the PostgreSQL streaming-replication config in postgresql.conf (primary_conninfo, standby.signal) is valid on PG16 and needs no change.

4. Application server: Passenger 5 to 6

Passenger 5 is end-of-life and is removed on Stack v8. Environments that used Passenger 5 use Passenger 6 on v8. If a custom recipe or configuration references Passenger 5 explicitly (service names, config paths, or a pinned Passenger 5 package), update it to Passenger 6. Applications relying on Passenger-5-specific behavior should be validated on Passenger 6 on staging before moving production.

Summary checklist for custom recipes

  • SSH managed via ssh / ssh.service, not sshd.
  • Instance-metadata reads use the IMDSv2 token handshake (fail-closed, IMDSv1 fallback).
  • MySQL replication SQL uses REPLICATION SOURCE / REPLICA / SOURCE_LOG_*, not MASTER / SLAVE.
  • MySQL backups call xtrabackup (8.4), not innobackupex.
  • No removed my.cnf variables that block startup (default_authentication_plugin, expire_logs_days, query_cache_*); deprecated ones (innodb_log_file_size, slave_*, log-slave-updates) still boot but should be updated.
  • PostgreSQL promotion uses pg_promote(), not promote_trigger_file.
  • PostgreSQL backup calls use pg_backup_start/pg_backup_stop, not pg_start_backup/pg_stop_backup.
  • Passenger references updated from 5 to 6.

Related articles

Choose files or drag and drop files
Was this article helpful?
Yes
No
  1. Manuel da Silva

  2. Posted

Comments