Magento 2 – [Error] Setup version for module ‘Namespace_Modulename’ is not specified

Empecé a desarrollar un módulo para Magento 2  de la siguiente manera.

Creé una entrada para mi módulo en el fichero app/etc/config.php de la siguiente manera

'Namespace_Modulename' => 1,

Luego creé el fichero de configuración module.xml en app/code/Namespace/Modulename/etc/module.xml

<?xml version="1.0"?>
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
 <module name="Namespace_Modulename" setup_version="2.0.1"/>
 </config>

Todo iba bien, hasta que un día actualicé Magento y dejó de funcionar mostrándome el siguiente error:

Error

Setup version for module 'Namespace_Modulename' is not specified
#0 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Module/DbVersionInfo.php(56): Magento\Framework\Module\DbVersionInfo->isModuleVersionEqual('Namespace_Modulename', false)
#1 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Module/DbVersionInfo.php(79): Magento\Framework\Module\DbVersionInfo->isSchemaUpToDate('Namespace_Modulename')
#2 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php(55): Magento\Framework\Module\DbVersionInfo->getDbVersionErrors()
#3 [internal function]: Magento\Framework\Module\Plugin\DbStatusValidator->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#4 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Interception/Chain/Chain.php(68): call_user_func_array(Array, Array)
#5 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\Framewo...', 'dispatch', Object(Magento\Framework\App\FrontController\Interceptor), Array, 'storeCookieVali...')
#6 /srv/www/local.magento2.com/app/code/Magento/Store/Model/Plugin/StoreCookie.php(78): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Request\Http))
#7 [internal function]: Magento\Store\Model\Plugin\StoreCookie->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#8 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Interception/Chain/Chain.php(68): call_user_func_array(Array, Array)
#9 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\Framewo...', 'dispatch', Object(Magento\Framework\App\FrontController\Interceptor), Array, 'front-controlle...')
#10 /srv/www/local.magento2.com/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php(55): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Request\Http))
#11 [internal function]: Magento\PageCache\Model\App\FrontController\VarnishPlugin->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#12 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Interception/Chain/Chain.php(68): call_user_func_array(Array, Array)
#13 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Interception/Interceptor.php(136): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\Framewo...', 'dispatch', Object(Magento\Framework\App\FrontController\Interceptor), Array, 'front-controlle...')
#14 /srv/www/local.magento2.com/app/code/Magento/PageCache/Model/App/FrontController/BuiltinPlugin.php(68): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#15 [internal function]: Magento\PageCache\Model\App\FrontController\BuiltinPlugin->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#16 /srv/www/local.magento2.com/lib/internal/Magento/Framework/Interception/Interceptor.php(141): call_user_func_array(Array, Array)
#17 /srv/www/local.magento2.com/var/generation/Magento/Framework/App/FrontController/Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, Array)
#18 /srv/www/local.magento2.com/lib/internal/Magento/Framework/App/Http.php(115): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#19 /srv/www/local.magento2.com/lib/internal/Magento/Framework/App/Bootstrap.php(258): Magento\Framework\App\Http->launch()
#20 /srv/www/local.magento2.com/index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#21 {main}

El caso es que a partir de Septiembre-Octubre de 2015 el equipo de Magento decidió incorporar un paso mas en la creación de un módulo.

Solución

Tienes que crear un fichero registration.php en el directorio de tu módulo con el siguiente contenido.

app/code/Namespace/Modulename/registration.php

<?php
use Magento\Framework\Component\ComponentRegistrar;
$name = implode('_', array_map(function($part) {
    return implode(array_map('ucfirst', explode('-', $part)));
}, array_slice(explode(DIRECTORY_SEPARATOR, __DIR__), -2, 2)));
ComponentRegistrar::register(ComponentRegistrar::MODULE, $name, __DIR__);

Ahora solo tendrás que ejecutar bin/magento setup:upgrade y ya tendrás tu modulo configurado.