Migrate D6 to D8 building a custom migration

To be able to run custom Drupal-to-Drupal migrations in Drupal 8, you will need the following:

  • Drupal 8.1 (or greater) installed
  • A database backup from your Drupal 6 or 7 site, and optionally, your files directory from your Drupal 6 or 7 site
  • A database backup of your freshly installed Drupal 8.1

Enable the following modules in your Drupal 8.1 site:

Put legacy database credentials in settings.php

$databases['default']['default'] = array (
  'database' => 'capetrials_d8',
  'username' => '********',
  'password' => '********',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
$databases['legacy']['default'] = array (
  'database' => 'capetrials_db1',
  'username' => '********',
  'password' => '********',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',

The legacy database key is important - this is what the migration_upgrade process looks for when generating the migration.

Generate a migration

Now to generate a migration. In your Drupal 8.x root directory run:

drush migrate-upgrade --configure-only \
  --legacy-root=/var/www/d6source/capetrials/files \

If you didn’t create an entry in your settings.php you can pass your database credentials for your Drupal 6 or 7 site, and optionally, the path to the files directory like so:

drush migrate-upgrade --configure-only --legacy-db-url=mysql://dbuser:dbpass@localhost/dbname --legacy-root=/path/to/sites/default/files

This command will generate migration configuration entities in the active configuration store, using migration plugins in Drupal core. Check out the tutorial, Configuration Data Storage, to learn more about the configuration system in Drupal 8.

Create a custom migration module

To create a custom module for migration, in your Drupal 8.x site using Drupal Console, do this:

drupal generate:module --uri=capetrials.co.za

// Welcome to the Drupal module generator

Enter the new module name:
> custom_migration

Enter the module machine name [custom_migration]:

Enter the module Path [/modules/custom]:

Enter module description [My Awesome Module]:
> A custom Drupal-to-Drupal migration

Enter package name [Custom]:

Enter Drupal Core version [8.x]:

Do you want to generate a .module file (yes/no) [no]:
> no

Define module as feature (yes/no) [no]:
> no

Do you want to add a composer.json file to your module (yes/no) [yes]:
> yes

Would you like to add module dependencies (yes/no) [no]:
> yes

 Module dependencies separated by commas (i.e. context, panels):
> migrate_drupal, migrate_plus

Do you confirm generation? (yes/no) [yes]:
> yes

Generated or updated files
Site path: /Users/willwh/Sites/drupal
1 - modules/custom/custom_migration/custom_migration.info.yml
2 - modules/custom/custom_migration/composer.json

Export site configuration

Create the directory custom_migration/config/install, which is where you will store the custom migration.

mkdir -p /var/www/drupal-8/modules/custom/custom_migration/config/install

drush config-export --destination=/tmp/migrate

Next, we need to copy the migration configuration generated by drush migrate-upgrade --configure-only to our custom_migrate/config/install.

These files will be at /tmp/migrate and begin with migrate_plus.

Warning! Make sure you do not copy the default configuration group that is defined by migrate plus, i.e. migrate_plus.migration_group.default.yml.

Use the following command, and replace the last argument with the correct path to your custom module’s config/install location:

cp /tmp/migrate/migrate_plus.migration.* /tmp/migrate/migrate_plus.migration_group.migrate_*.yml \

Edit your module’s migrations

Remove any of the migrations you don’t need, along with any dependencies on them. You can also now edit the migrations contained in the custom_migration module to your liking.

For example, if you don’t want to migrate blocks from your previous site, you would delete the following files at custom_migration/config/install :

  • migrate_plus.migration.upgrade_block_content_body_field.yml
  • migrate_plus.migration.upgrade_block_content_type.yml
  • migrate_plus.migration.upgrade_d6_block.yml
  • migrate_plus.migration.upgrade_d6_custom_block.yml

Customize migrations with process plugins

Migrations may also be customized with process plugins.

Let’s say you’re migrating from a Drupal 7 site. If you wanted to map a node type from a previous Drupal version to a different node type in Drupal 8, you could accomplish this with the default_value process plugin.

For example, given this migration template:

  • migrate_plus.migration.upgrade_d7_node_blog_post.yml

In the process: section of the migration, take note of the following:

  type: type
  name: name
  description: description

Instead of mapping the node type in Drupal 7 to one of the same name in Drupal 8, which, in my example would import the blog_post content from Drupal 7, to a content type of blog_post in Drupal 8, we can use the default_value plugin, and specify a node type of a different name.

In the process: key, change the values for plugin to default_value and value to the machine name of your desired node type.

    plugin: default_value
    value: desired_node_type
  name: name
  description: description
  help: help
  title_label: title_label
  preview_mode: constants/preview
  display_submitted: display_submitted
  new_revision: options/revision
  create_body: create_body
  create_body_label: body_label

Run the customized migration

To run your migration, you must import your clean backup of Drupal 8.1, enable the required modules above, and your new custom_migration module.

You can check that you have everything set up correctly by running drush migrate-status. You should see a list of all of the migrations you have defined in your module.

A portion of my custom migration status looks like this:

Group: default                                  Status  Total  Imported  Unprocessed  Last imported
 upgrade_block_content_type                      Idle    1      0         1
 upgrade_d7_dblog_settings                       Idle    0      0         0
 upgrade_d7_image_settings                       Idle    0      0         0
 upgrade_d7_node_settings                        Idle    1      0         1
 upgrade_d7_search_settings                      Idle    1      0         1
 upgrade_d7_url_alias                            Idle    4953   0         4953
 upgrade_d7_user_flood                           Idle    0      0         0
 upgrade_d7_user_mail                            Idle    1      0         1
 upgrade_menu_settings                           Idle    0      0         0
 upgrade_search_page                             Idle    1      0         1
 upgrade_taxonomy_settings                       Idle    0      0         0
 upgrade_text_settings                           Idle    0      0         0

To execute your migration, run the following:

drush migrate-import --all

Add Custom Drush Migration Configs

In the modules config/install directory, add you migration_plus.migrate* custom migrations, so that they get installed in the new site when the module is enabled.


Fix 'filter_null' Error

After migration, go to admin/config/content/formats/manage/full_html and click save.  This will fix a broken migrated site with filter_null errors.

Fix Taxonomy Terms Missing From Nodes

Migrate the d6_term_node:n for all the available n.

Fix CKUtils Lightbox Images Display

Copy the files in "oldsite/sites/capetrials.co.za/files/ckutils" to ../files/ckutils in the D8 site, setting global read access.