

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Implementación de una aplicación Express Node Js. en Elastic Beanstalk
<a name="create_deploy_nodejs_express"></a>

En esta sección, se describe cómo se implementa una aplicación de muestra en Elastic Beanstalk con la interfaz de línea de comando de Elastic Beanstalk (CLI de EB), y cómo se la actualiza después para utilizar el marco de [Express](http://expressjs.com/). 

## Requisitos previos
<a name="create_deploy_nodejs_express.prerequisites"></a>

Este tutorial tiene siguientes los requisitos previos:
+ Los tiempos de ejecución de Node.js
+ El software de administración de paquetes de Node.js predeterminado, npm
+ El generador de línea de comandos Express
+ La interfaz de línea de comando de Elastic Beanstalk (CLI de EB)

Para obtener más detalles acerca de la instalación de los primeros tres componentes y la configuración de su entorno de desarrollo local, consulte [Configuración del entorno de desarrollo de Node.js para Elastic Beanstalk](nodejs-devenv.md). Para este tutorial, no necesitas instalar el AWS SDK para Node.js, que también se menciona en el tema al que se hace referencia.

Para obtener detalles sobre la instalación y configuración de la CLI de EB, consulte [Instalación de la CLI de EB con el script de configuración (recomendado)](eb-cli3.md#eb-cli3-install) y [Configuración de la CLI de EB](eb-cli3-configuration.md).

## Cree un entorno de Elastic Beanstalk
<a name="create_deploy_nodejs_express.eb_init-rds"></a>

**Su directorio de aplicaciones**  
Este tutorial usa un directorio llamado `nodejs-example-express-rds` para el paquete de origen de la aplicación. Cree el directorio `nodejs-example-express-rds` para este tutorial.

```
~$ mkdir nodejs-example-express-rds
```

**nota**  
Cada tutorial de este capítulo usa su propio directorio para el paquete de origen de la aplicación. El nombre del directorio coincide con el nombre de la aplicación de muestra utilizada en el tutorial.

Cambie su directorio de trabajo actual a `nodejs-example-express-rds`.

```
~$ cd nodejs-example-express-rds
```

Ahora configuremos un entorno de Elastic Beanstalk que ejecute la plataforma Node.js y la aplicación de muestra. Se usará la interfaz de línea de comandos de Elastic Beanstalk (CLI de EB)

**Para configurar un repositorio en la CLI de EB para la aplicación y crear un entorno de Elastic Beanstalk que ejecute la plataforma Node.js**

1. Cree un repositorio con el comando **[**eb init**](eb3-init.md)**.

   ```
   ~/nodejs-example-express-rds$ eb init --platform node.js --region <region>
   ```

   Este comando crea un archivo de configuración en una carpeta llamada `.elasticbeanstalk` que especifica los ajustes para crear los entornos de la aplicación y crea una aplicación de Elastic Beanstalk con el nombre de la carpeta actual.

1. Cree un entorno que ejecute una aplicación de muestra con el comando **[**eb create**](eb3-create.md)**.

   ```
   ~/nodejs-example-express-rds$ eb create --sample nodejs-example-express-rds
   ```

   Este comando crea un entorno con equilibrador de carga utilizando la configuración predeterminada de la plataforma de Node.js y los siguientes recursos:
   + **EC2 instancia**: una máquina virtual de Amazon Elastic Compute Cloud (Amazon EC2) configurada para ejecutar aplicaciones web en la plataforma que elijas.

     Cada plataforma ejecuta un conjunto específico de software, archivos de configuración y scripts compatibles con una determinada versión de lenguaje, marco de trabajo y contenedor web (o una combinación de estos). La mayoría de las plataformas utilizan Apache o nginx como un proxy inverso que se sitúa delante de la aplicación web, reenvía las solicitudes a esta, administra los recursos estáticos y genera registros de acceso y errores.
   + **Grupo de seguridad de instancias**: un grupo EC2 de seguridad de Amazon configurado para permitir el tráfico entrante en el puerto 80. Este recurso permite que el tráfico HTTP del balanceador de cargas llegue a la EC2 instancia que ejecuta tu aplicación web. De forma predeterminada, el tráfico no está permitido en otros puertos.
   + **Balanceador de carga**: equilibrador de carga de Elastic Load Balancing configurado para distribuir solicitudes a las instancias que se ejecutan en la aplicación. Los balanceadores de carga también permiten que las instancias no estén expuestas directamente a Internet.
   + **Grupo de seguridad del balanceador de carga**: un grupo EC2 de seguridad de Amazon configurado para permitir el tráfico entrante en el puerto 80. Este recurso permite que el tráfico HTTP procedente de Internet llegue al equilibrador de carga. De forma predeterminada, el tráfico no está permitido en otros puertos.
   + **Grupo de escalado automático**: grupo de escalado automático configurado para reemplazar una instancia si termina o deja de estar disponible.
   + **Bucket de Amazon S3**: ubicación de almacenamiento para el código fuente, los registros y otros artefactos que se crean al utilizar Elastic Beanstalk.
   + ** CloudWatch Alarmas de Amazon**: dos CloudWatch alarmas que monitorean la carga de las instancias de su entorno y que se activan si la carga es demasiado alta o demasiado baja. Cuando se activa una alarma, en respuesta, el grupo de escalado automático aumenta o reduce los recursos.
   + **CloudFormation pila**: Elastic CloudFormation Beanstalk se utiliza para lanzar los recursos de su entorno y propagar los cambios de configuración. Los recursos se definen en una plantilla que puede verse en la [consola de CloudFormation](https://console.aws.amazon.com/cloudformation).
   + **Nombre de dominio***: un nombre de dominio que se dirige a su aplicación web en el formulario. *subdomain* *region*.elasticbeanstalk.com*.
**Seguridad de dominios**  
Para aumentar la seguridad de las aplicaciones de Elastic Beanstalk, el dominio *elasticbeanstalk.com* está registrado en la [lista de sufijos públicos (PSL)](https://publicsuffix.org/).  
Para mayor seguridad, se recomienda que utilice cookies con un prefijo `__Host-` en caso de que necesite configurar cookies confidenciales en el nombre de dominio predeterminado de sus aplicaciones de Elastic Beanstalk. Esta práctica le ayuda a proteger su dominio de los intentos de falsificación de solicitudes entre sitios (CSRF). Para más información, consulte la página [Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes) en la red de desarrolladores de Mozilla.

1. Cuando se complete la creación del entorno, utilice el comando [**eb open**](eb3-open.md) para abrir la URL del entorno en el navegador predeterminado.

   ```
   ~/nodejs-example-express-rds$ eb open
   ```

Ahora ha creado un entorno de Elastic Beanstalk para Node.js con una aplicación de muestra. Puede actualizarlo con su propia aplicación. Luego, actualizamos la aplicación de muestra para que use el marco de Express.

## Actualización de la aplicación para que use Express
<a name="create_deploy_nodejs_express.update"></a>

Una vez que haya creado el entorno con una aplicación de muestra, puede actualizarlo con su propia aplicación. En este procedimiento, ejecutamos primero los comandos**express** y **npm install** para configurar el marco de Express en el directorio de la aplicación. Luego use la CLI de EB para actualizar su entorno Elastic Beanstalk con la aplicación actualizada.

**Si desea actualizar la aplicación para que use Express**

1. Ejecute el comando `express`. Esto genera `package.json`, `app.js` y unos directorios.

   ```
   ~/nodejs-example-express-rds$ express
   ```

   Cuando se le pregunte, escriba **y** si desea continuar.
**nota**  
Si el comando **express** no funciona, es posible que no haya instalado el generador de línea de comandos Express tal y como se describe en la sección *Requisitos previos* anterior. O bien, puede que sea necesario configurar la ruta del directorio de su máquina local para ejecutar el comando **express**. Consulte la sección *Requisitos previos* para conocer los pasos detallados sobre la configuración del entorno de desarrollo, de modo que pueda continuar con este tutorial. 

1. Configure las dependencias locales.

   ```
   ~/nodejs-example-express-rds$ npm install
   ```

1. (Opcional) Compruebe que el servidor de aplicaciones web se inicie.

   ```
   ~/nodejs-example-express-rds$ npm start
   ```

   Debería ver una salida similar a esta:

   ```
   > nodejs@0.0.0 start /home/local/user/node-express
   > node ./bin/www
   ```

   El servidor se ejecuta en el puerto 3000 de forma predeterminada. Para probarlo, ejecute `curl http://localhost:3000` en otro terminal o abra un navegador en el equipo local e ingrese el `http://localhost:3000` de la dirección URL.

   Presione **Ctrl\$1C** para detener el servidor.

1. Implemente los cambios en su entorno Elastic Beanstalk con el comando [**eb deploy**](eb3-deploy.md).

   ```
   ~/nodejs-example-express-rds$ eb deploy
   ```

1. Una vez que el entorno esté listo, actualice la dirección URL para verificar que ha funcionado. Debería aparecer una página web que diga **Welcome to Express**.

A continuación, vamos a actualizar la aplicación de Express para atender archivos estáticos y agregar una nueva página.

**Para configurar archivos estáticos y agregar una nueva página a la aplicación de Express**

1. Agregue un segundo archivo de configuración en la carpeta [`.ebextensions`](ebextensions.md) con el contenido siguiente:

   **`nodejs-example-express-rds/.ebextensions/staticfiles.config`**

   ```
   option_settings:
       aws:elasticbeanstalk:environment:proxy:staticfiles:
           /stylesheets: public/stylesheets
   ```

   Esta opción configura el servidor proxy que proporcione los archivos en la carpeta `public` de la ruta `/public` de la aplicación. Si los archivos se sirven de forma estática desde el servidor proxy, se reduce la carga en la aplicación. Para obtener más información, consulte [Archivos estáticos](create_deploy_nodejs.container.md#nodejs-platform-console-staticfiles) mencionada previamente en este capítulo.

1. (Opcional) Para confirmar que las asignaciones estáticas están configuradas correctamente, comente la configuración de asignación estática en `nodejs-example-express-rds/app.js`. Esto elimina la asignación de la aplicación de nodos.

   ```
   //  app.use(express.static(path.join(__dirname, 'public'))); 
   ```

   Las asignaciones de archivos estáticas del archivo `staticfiles.config` del paso anterior deberían seguir cargando la hoja de estilos correctamente, incluso después de comentar esta línea. Para comprobar que las asignaciones de archivos estáticas se cargan mediante la configuración de archivos estáticos del proxy, en lugar de mediante la aplicación exprés, elimine los valores siguientes`option_settings:`. Una vez que se haya eliminado de la configuración del archivo estático y de la aplicación de nodo, la hoja de estilos no se cargará.

   Recuerde restablecer el contenido de `nodejs-example-express-rds/app.js` y de `staticfiles.config` cuando haya terminado las pruebas.

1. Añada `nodejs-example-express-rds/routes/hike.js`. Escriba lo siguiente:

   ```
   exports.index = function(req, res) {
    res.render('hike', {title: 'My Hiking Log'});
   };
   
   exports.add_hike = function(req, res) {
   };
   ```

1. Actualice `nodejs-example-express-rds/app.js` para incluir tres nuevas líneas.

   En primer lugar, inserte la siguiente línea para agregar un objeto `require` para esta ruta:

   ```
   var hike = require('./routes/hike');
   ```

   El archivo debe ser similar al siguiente fragmento:

   ```
   var express = require('express');
   var path = require('path');
   var hike = require('./routes/hike');
   ```

   A continuación, agregue las dos líneas siguientes a `nodejs-example-express-rds/app.js` detrás de `var app = express();`.

   ```
   app.get('/hikes', hike.index);
   app.post('/add_hike', hike.add_hike);
   ```

   El archivo debe ser similar al siguiente fragmento:

   ```
   var app = express();
   app.get('/hikes', hike.index);
   app.post('/add_hike', hike.add_hike);
   ```

1. Copie `nodejs-example-express-rds/views/index.jade` en `nodejs-example-express-rds/views/hike.jade`. 

   ```
   ~/nodejs-example-express-rds$ cp views/index.jade views/hike.jade
   ```

1. Implemente los cambios con el comando [**eb deploy**](eb3-deploy.md).

   ```
   ~/nodejs-example-express-rds$ eb deploy
   ```

1. Su entorno se actualizará al cabo de unos minutos. Cuando el entorno esté listo, asegúrese de que funciona actualizando el navegador y agregando **hikes** al final de la URL (por ejemplo, `http://node-express-env-syypntcz2q.elasticbeanstalk.com/hikes`).

   Debería ver una página web con el título **My Hiking Log**.

Ya ha creado una aplicación web que utiliza el marco Express. En la siguiente sección, modificaremos la aplicación para utilizar un Amazon Relational Database Service (RDS) para almacenar un registro de hiking.

## Actualice la aplicación para que use Amazon RDS.
<a name="create_deploy_nodejs_express.add_rds"></a>

En el siguiente paso, actualizamos la aplicación para usar Amazon RDS para MySQL.

**Para actualizar la aplicación para que use RDS para MySQL**

1. Para crear una base de datos RDS para MySQL acoplada a su entorno de Elastic Beanstalk, siga las instrucciones del tema [Agregar una base de datos](create-deploy-nodejs.rds.md) que se incluye más adelante en este capítulo. Añadir una instancia de base de datos demora aproximadamente 10 minutos.

1.  Actualice la sección de dependencias en `package.json` con el siguiente contenido: 

   ```
   "dependencies": {
       "async": "^3.2.4",
       "express": "4.18.2",
       "jade": "1.11.0",
       "mysql": "2.18.1",
       "node-uuid": "^1.4.8",
       "body-parser": "^1.20.1",
       "method-override": "^3.0.0",
       "morgan": "^1.10.0",
       "errorhandler": "^1.5.1"
     }
   ```

1. Ejecute **npm install**.

   ```
   ~/nodejs-example-express-rds$ npm install
   ```

1. Actualice `app.js` para conectarse a la base de datos, crear una tabla e insertar un único registro de hiking predeterminado. Cada vez que se implemente esta aplicación, eliminará la tabla de hiking anterior y la volverá a crear.

   ```
   /**
    * Module dependencies.
    */
   
    const express = require('express')
    , routes = require('./routes')
    , hike = require('./routes/hike')
    , http = require('http')
    , path = require('path')
    , mysql = require('mysql')
    , async = require('async')
    , bodyParser = require('body-parser')
    , methodOverride = require('method-override')
    , morgan = require('morgan')
    , errorhandler = require('errorhandler');
   
   const { connect } = require('http2');
   
   const app = express()
   
   app.set('views', __dirname + '/views')
   app.set('view engine', 'jade')
   app.use(methodOverride())
   app.use(bodyParser.json())
   app.use(bodyParser.urlencoded({ extended: true }))
   app.use(express.static(path.join(__dirname, 'public')))
   
   
   app.set('connection', mysql.createConnection({
   host: process.env.RDS_HOSTNAME,
   user: process.env.RDS_USERNAME,
   password: process.env.RDS_PASSWORD,
   port: process.env.RDS_PORT}));  
   
   function init() {
    app.get('/', routes.index);
    app.get('/hikes', hike.index);
    app.post('/add_hike', hike.add_hike);
   }
   
   const client = app.get('connection');
   async.series([
    function connect(callback) {
      client.connect(callback);
      console.log('Connected!');
    },
    function clear(callback) {
      client.query('DROP DATABASE IF EXISTS mynode_db', callback);
    },
    function create_db(callback) {
      client.query('CREATE DATABASE mynode_db', callback);
    },
    function use_db(callback) {
      client.query('USE mynode_db', callback);
    },
    function create_table(callback) {
       client.query('CREATE TABLE HIKES (' +
                           'ID VARCHAR(40), ' +
                           'HIKE_DATE DATE, ' +
                           'NAME VARCHAR(40), ' +
                           'DISTANCE VARCHAR(40), ' +
                           'LOCATION VARCHAR(40), ' +
                           'WEATHER VARCHAR(40), ' +
                           'PRIMARY KEY(ID))', callback);
    },
    function insert_default(callback) {
      const hike = {HIKE_DATE: new Date(), NAME: 'Hazard Stevens',
            LOCATION: 'Mt Rainier', DISTANCE: '4,027m vertical', WEATHER:'Bad', ID: '12345'};
      client.query('INSERT INTO HIKES set ?', hike, callback);
    }
   ], function (err, results) {
    if (err) {
      console.log('Exception initializing database.');
      throw err;
    } else {
      console.log('Database initialization complete.');
      init();
    }
   });
   
   module.exports = app
   ```

1. Agregue el siguiente contenido a `routes/hike.js`. Esto permitirá a las rutas insertar nuevos registros de hiking en la base de datos de *HIKES*.

   ```
   const uuid = require('node-uuid');
   exports.index = function(req, res) {
     res.app.get('connection').query( 'SELECT * FROM HIKES', function(err,
   rows) {
       if (err) {
         res.send(err);
       } else {
         console.log(JSON.stringify(rows));
         res.render('hike', {title: 'My Hiking Log', hikes: rows});
     }});
   };
   exports.add_hike = function(req, res){
     const input = req.body.hike;
     const hike = { HIKE_DATE: new Date(), ID: uuid.v4(), NAME: input.NAME,
     LOCATION: input.LOCATION, DISTANCE: input.DISTANCE, WEATHER: input.WEATHER};
     console.log('Request to log hike:' + JSON.stringify(hike));
     req.app.get('connection').query('INSERT INTO HIKES set ?', hike, function(err) {
         if (err) {
           res.send(err);
         } else {
           res.redirect('/hikes');
         }
      });
   };
   ```

1. Reemplace todo el contenido de `routes/index.js` por lo siguiente:

   ```
   /*
    * GET home page.
    */
   
   exports.index = function(req, res){
     res.render('index', { title: 'Express' });
   };
   ```

1. Añada la siguiente plantilla de jade a `views/hike.jade` para proporcionar la interfaz de usuario para añadir registros de hiking.

   ```
   extends layout
   
   block content
     h1= title
     p Welcome to #{title}
   
     form(action="/add_hike", method="post")
       table(border="1")
         tr
           td Your Name
           td
             input(name="hike[NAME]", type="textbox")
         tr
           td Location
           td
             input(name="hike[LOCATION]", type="textbox")
         tr
           td Distance
           td
             input(name="hike[DISTANCE]", type="textbox")
         tr
           td Weather
           td
             input(name="hike[WEATHER]", type="radio", value="Good")
             | Good
             input(name="hike[WEATHER]", type="radio", value="Bad")
             | Bad
             input(name="hike[WEATHER]", type="radio", value="Seattle", checked)
             | Seattle
         tr
           td(colspan="2")
             input(type="submit", value="Record Hike")
   
     div
       h3 Hikes
       table(border="1")
         tr
           td Date
           td Name
           td Location
           td Distance
           td Weather
         each hike in hikes
           tr
             td #{hike.HIKE_DATE.toDateString()}
             td #{hike.NAME}
             td #{hike.LOCATION}
             td #{hike.DISTANCE}
             td #{hike.WEATHER}
   ```

1. Implemente los cambios con el comando [**eb deploy**](eb3-deploy.md).

   ```
   ~/nodejs-example-express-rds$ eb deploy
   ```

## Limpieza
<a name="create_deploy_nodejs_express.delete"></a>

Si ha terminado de trabajar con Elastic Beanstalk, puede terminar su entorno.

Utilice el comando **eb terminate** para terminar el entorno y todos los recursos que contiene.

```
~/nodejs-example-express-rds$ eb terminate
The environment "nodejs-example-express-rds-env" and all associated instances will be terminated.
To confirm, type the environment name: nodejs-example-express-rds-env
INFO: terminateEnvironment is starting.
...
```