Welcome to the land of Features Configuration Management, aka FCM! It is not only about Features, and not about Configuration Management (as introduced in Drupal version 8). Instead, it is a special case of Software Configuration Management, aka SCM. Mostly because Features can be considered as a code generator, whereas that generated code needs to be migrated through multiple environments. Read on for more details.
1 - Pros and cons of using Features
Advantages of using Features
- Automate the deployment of changes applied to a Drupal development site to one or more target Drupal (pre-) production sites (instead of manual deployment).
- Facilitates sharing (shipping) of ongoing Drupal development between Drupal developers / site builders (eg to make some View(s) created by a views expert available to a Drupal Themer working in another development site to theme that view).
- Great integration with both GIT and Drush for shipping a copy of the code generated by Features (on the development site) to selected target (pre-) production sites.
Disadvantages of using Features
- Avoiding Feature Conflicts and/or managing Feature Dependencies can be challenging!
- It's not easy to start using Features on an existing (production) site.
- Install/enable of the Features module is easy (just a module), but to learn to use Features correctly is a major challenge.
2 - Techniques for features packaging
Using Features it is up to your own imagination how to package (compose) the content of a feature. Here are some techniques that can be used for it.
A single super feature
This is a pretty simple packaging technique: everything is packaged together in a single feature (some call it the "God" feature ...). Seems easy, pretty forward, etc. But this technique also leads to "conflicts" (as explained below) more or less right away ...
A good usecase for this appears to be when creating a "Drupal distribution", where all users of it are assumed to use the same set of modules, configuration, etc. If however such distribution consists of multiple website functionalities (to not use the word "features" ...), it seems more appropriate to split such features in multiple features, as explained below.
Based on website functionality
This packaging technique creates a separated feature for each functionality of a website, such as:
- Feature A = implement a "*Gallery".
- Feature B = implementg a "*Blog".
- Feature C = implement a "*Event Calendar".
Based on Drupal admin sections
This packaging technique creates separated features for each of the (major) admin sections of a Drupal website that is used to create the site, such as:
- All required modules are contained in feature A,
- All base field definitions are contained in feature B,
- All content types are contained in feature C,
- All permissions are contained in feature D,
- All roles are contained in feature E,
- All variables are contained in feature F,
- All (custom) Views are contained in feature G,
- All (custom) Rules are contained in feature H,
The above list is virtually unlimited: in the end you could even think of it as 1 feature for each Drupal admin menu option ... if you want to go that far.
IMO it is also the most recommended approach to package features.
3 - Reducing the probability of conflicts in Features and/or GIT
Do not reuse fields
Quite a few conflicts seem to be caused by reusing fields among multiple content types. E.g. in content type A you have a field with machine name
field_somefield, which is also used as field in content type B with the very same machine name
field_somefield but which as another field type and/or some other field setting(s) that are different.
By not reusing fields among content types, you avoid running in this issue. Have a look at an interesting naming convention for the machine name of your content types and fields as shown in table of Wrapping Information Architecture and Documentation, which is part of the articles about "Relativity Model for Drupal". For more details on that refer to my answer to "How do I model content (types) from a database-centric point of view?".
Split features depending on who works on what
If multiple people are working on a single site, the amount of conflicts can be reduced by organizing (= creating separate) features based on who is working on what. An illustration of this could be as in this example:
- Views goes in feature A,
- Rules goes in feature B,
- Charts goes in feature C,
- Anything about Theming goes in feature D,
4 - Recommended Drupal environments
Everything above should help to somehow facilitate the usage of Features. However, to ensure that things will work as expected (designed), you also need to have an appropriate set of environments (logically related Drupal websites) for basically these reasons:
- merge functionality provided by multiple features.
- predict and resolve conflicts.
- end-user testing of all merged features that are certified to not have any conflicts.
In the ideal world, these logically related Drupal websites should be configured, and used, like so:
- Personal Dev Site - each website developer has a separated dev site. When some part of the development is ready to be shared with somebody else, an appropriate feature is created, which is shipped to the staging environment.
- Sandbox Site - this is a Drupal environment which only contains Drupal core, used to unit test the completeness of a single feature. Should a feature, accidentally, have some unexpected dependencies (eg some module the feature depends on, which is not enabled in the Sandbox), then this is where that dependency will become clear.
- Staging Site - here is where one or more features (created in a dev site) are delivered to. It could be just some hotfix for some production problem, or it could be where all development for a new release of the website is consolidated. If any conflicts between multiple features do exist, then this is the environment where they will first show up ... and need to be resolved somehow.
- QA Site - after the Staging environment is considered stable, it's time to move on with the relevant features and make them available also at some higher level where they can be used for QA testing, acceptance testing, volume testing, etc. At this level you should be extremely careful in allowing any additional changes (if any). Because any such change may invalidate all prior testing efforts already completed in this environment.
- Shadow Production Site - To prepare the activation in real production, you might want to first further promote the relevant features to an environment that is considered a copy (shadow) of your real production environment. If at this point during the migration process anything still breaks, then that is a red flag to revert some of your prior steps. Get it fixed, and try again, until all parties involved approve the changes.
- Production Site(s) - If you completed all prior steps, then this step should be self explaining, and pretty easy. Depending on your needs, this could be a single site, or something equivalent to Drupal's Multi-sites whereas all the sites involved are running the very same versions of all features.
- Baseline Site - In my experience, there are not many (if any at all) Drupal implementations where this type of site is used (also). It is simply a copy of the Production Site(s), but available to the Drupal developers, testers, etc that can be used to verify what the production sites look like, or to perform user training, etc. And any time a new development cycle is started, the components of a site that will be impacted (need to be changed) should be "copied somehow" using this Baseline Site as input, with as target a Personal Development Site.
Obviously, the above inventory of types of Drupal sites is like the ideal world. Depending on the size of your development team, and / or the available budgets to create and maintain them, not all of them may be used (or affordable). This inventory is modelled after best practises in the area of SCM, used in mostly all huge/global corporations (banks, airlines, etc).
5 - Related modules
The Strongarm module allows for exporting variables (of modules which store their settings in variables) with the Features module.
The Node export module allows users to export nodes and then import it into another Drupal installation.
The Role Export module allows roles to have machine_names and generates a unique role id (rid) based off of the machine_name. Roles can be exported with Features and get the exact same rid if imported on other sites.
The Features Banish module allows for completely excluding individual features components from the features UI and features exports. Here is a quote about it from its project page:
This module is useful when there are features components that you want to make sure NEVER get exported. If you are using features for site building or deployment then you've probably ran into the issue of someone accidentally exporting timestamp variables like cron_last or update_last_check. You may also want to banish permissions for developer modules so they don't get caught up with the rest of the site permissions you want to export. Banished items will not show up in your feature module OR ANY OTHER FEATURES MODULE, so use with caution. For a central list of features that should never be exported, see https://www.drupal.org/node/2400531
The Bean module makes your blocks exportable. Here is a quote about it from its project page:
Think of a Bean as a method to provide new types (compared to node this would be a content type) which then provides an add content interface to create as many blocks as you require (see screenshot below). The bean content can then be placed around the site just like any other block.
This module also works great in combination with the UUID and UUID Features Integration modules. This module only started as of D7, but it has been included with Drupal 8 core already. The video tutorial Drupal Bean module tutorial - using Bean Admin UI provides a great introduction to really understand the power of this module, and the kind of things you can do with it (by only using site building techniques, no custom coding involved).
The Habitat module makes most sense in a Features-based workflow. Here is a quote about it from its project page:
In a multi-environment setup (e.g. prod, test, dev, local) there are some modules that you'd like to always be enabled or disabled on certain environments. Each time you sync a database down though you have to re-enable/disable the same modules. Worse, you get lazy and keep development modules enabled on production.
Habitat provides settings to enable or disable certain modules on each environment (habitat). Just set a variable with e.g. $conf['habitat'] = 'local'; in your settings.php file (the actual variable to use there is configurable for your current workflow). The disabling/enabling modules is done on hook_init.
6 - Recommended resources:
7 - Possible alternatives to using Features
If you're not able, or willing (yet), to use Features, then you may want to check to what extend the approaches/modules below may provide some type of alternative.
These are the commonly known facilities (to avoid the word features ...) available via the admin UI, for modules such as Rules, Views, etc (incomplete list!).
Some people consider the Bundle copy module as a possible alternative. It has export/import support for:
- Node types.
- Field API fields.
- Field groups.