Installing sites from existing config in Drupal 8

The problem

If you are using the core configuration management system in Drupal 8, you might have noticed that out of the box there's no way to re-install Drupal after you've initially installed it and exported configuration according to best practices. The use case is well-described in this Drupal issue, and I've previously posted an in-depth explanation of the errors it typically generates.

To briefly summarize the problem, a good development and CI workflow is to install the site (i.e. drush si) and then import any custom configuration for your project (drush cim). However, this will typically fail with errors such as "The import failed due for [sic] the following reasons: Entities exist of type (whatever). These entities need to be deleted before importing." The root of this problem is that Drupal core and contributed modules import a bunch of default configuration (not your custom config) at install time, and when you later run your own import of your custom configuration, it has to blow away and recreate a lot of this configuration.

Best-case scenario, this imposes a performance hit: why import a bunch of config that Drupal just has to delete later, right? Worst-case, it causes errors like the above for reasons explained in the linked posts.

I've recently been testing a fairly simple workaround for this problem.

The fix

The only limitations of this fix are that you should be using a custom profile (although with some CI hacking you could make it work with contrib profiles), and you must not have hook_install implemented by your profile.

Start by applying this core patch to install profiles from existing config.

The effect of this patch is to completely bypass Drupal's default config import process during site installs, and instead only import configuration directly from the config/sync directory of your install profile.

Assuming you want to store configuration in a common vcs directory such as /config/default at your repo root, then all you have to do is create a symlink from /docroot/profiles/custom/foo/config/sync to /config/default, or wherever you store your site-wide config.

Alternatives

One alternative to this approach is to use the Configuration Installer profile as documented by Lightning. The downside to using Config Installer is that you cannot choose which profile to use when installing Drupal, which is especially a problem for large platform builds, such as on Acquia Cloud Site Factory.