Saltar a contenido

Creación de recursos en la nube

Para crear los diferentes recursos disponibles en AWS podemos usar muchas de sus instrucciones que podemos encontrar en sus cursos estructurados. Al principio puedes ser un poco abrumador por la gran cantidad de servicios que tenemos disponibles, pero pronto veras que al principio con solo conocer unos pocos ya podemos hacer cosas muy interesantes con nuestros alumnos.

Además existe muchísimo material al respecto en diferentes fuentes que te voy a proporcionar a continuación, y que te ayudaran no solo a conocer como crear estos recursos en la nube, sino como integrarlos en los diferentes módulos de los ciclos de Formación Profesional de Informática y Comunicaciones.

Crear una Máquina Virtual en la nube (EC2)

Pasos a seguir:

  • Crear una Red Privada Virtual ( VPC )
  • Configurar un Grupo de Seguirdad
  • Lanzar una instancia EC2.

Tarea 1: Crear una VPC

En esta tarea, utilizará el asistente de VPC para crear una VPC y un gateway de Internet en una única zona de disponibilidad. El gateway de Internet (IGW) es un componente de la VPC que permite la comunicación entre instancias de la VPC e Internet.

Pasos a realizar:

  1. Pulsamos en el botón crear VPC.
  2. Introducimos el nombre de nuestra VPC: ASO-VPC y su direccionamiento: 172.16.0.0/16

Crear VPC

  1. Definimos dos zonas de disponibilidad y las subredes asociadas.

ZonasDisponibilidad

Subredes Asociadas

  1. Pulsamos el botón crear VPC.

Botón Crear VPC

  1. Una vez creada la VPC, podemos ver el mapa de recursos definidos.

Mapa de recursos definidos

Tarea 2: Crear un Grupo de Seguridad.

En este punto vamos a crear un grupo de seguridad asociado al VPC creado. Este grupo de seguridad actúa como un firewall virtual. Podemos agregar reglas a cada grupo de seguridad que permitan el tráfico hacia o desde las instancias asociadas.

  1. En el panel lateral izquierdo seleccionamos → Seguridad → Grupos de Seguridad → Crear grupo de seguridad.

IMPORTANTE : debemos seleccionar nuestra VPC: ASO-VPC. (Creada en la Tarea 1)

Crear grupo de Seguridad

  1. Definimos la regla de entrada, Tipo: SSH, Origen: Anywhere-IPv4

Regla de entrada

  1. Pulsamos Crear Grupo de Seguridad

Tarea 3: Lanzar la instancia EC2.

  1. Accedemos al panel de administración EC2 y seleccionamos lanzar instancia.

Lanzar la instancia EC2

  1. Le asignamos un nombre: Servidor SSH. Seleccionamos como Sistema Operativo: Amazon Linux 2 AMI.

Nombre y Amazon Linux 2 AMI

  1. Tipo de instancia: t2.micro. Seleccionamos → Nombre del par de claves: vockey.

Tipo de instancia y par de claves

  1. Configuración de red, pulsamos Editar.

  2. Seleccionamos nuestra VPC: ASO-VPC.

  3. Subred: Zona de disponibilidad: us-east-1a.

  4. Asignar automáticamente la IP pública: Habilitar.

  5. Firewall (grupos de seguridad) → Seleccionar un grupo de seguridad existente → Seleccionamos el grupo creado previamente en la Tarea 2.

  6. Pulsamos → Lanzar Instancia.

image-20250111200718953

  1. Volvemos al panel de administración EC2, pulsamos en el menú: Instancias y esperamos a que finalice la configuración de la máquina virtual.
Consejo

Actualizar la ṕagina hasta que en la máquina virtual veamos que se ha superado la comprobación de estado

Comprobaciones superadas

  1. Copiamos la dirección IP Pública de nuestra instancia.

  2. Para descargar la clave privada que nos permite realizar una conexión desde nuestra organización hacia la instancia EC2, debemos de volver a la página del Learner Lab y pulsamos sobre el botón: ℹ AWS Details, posteriormente pulsamos sobre: Download PEM.

    image-20250111201103797

  3. Copiamos el fichero descargado: labuser.pem, a nuestro directorio de trabajo.

  4. Cambiamos los permisos para que sólo el usuario propietario del archivo tenga permisos de lectura:

    1
    sudo chmod 400 labuser.pem
    
  5. Comprobamos si desde nuestra organización podemos iniciar sesión mediante SSH en la instancia EC2. Ejecutamos el comando:

    1
    sudo ssh -i labsuser.pem ec2-user@44.212.42.178
    
    Consejo

    Recuerda cambiar la IP Pública de tu instancia EC2 que has obtenido anteriormente.

  6. Tras realizar el acceso, veremos el terminal de la instancia EC2.

    Conexión SSH

Tarea 4: Administración remota

Por un lado podemos por ejemplo cambiar el nombre de host, para ello ejecutamos el siguiente comando para obtener privilegios de root:

1
sudo su

y posteriormente:

1
hostnamectl hostname XYZ-SSH-Server

Renombrar hostname

Podemos reiniciar la instancia mediante el comando: reboot, y al volver a conectar veremos el nombre de la máquina cambiado en el prompt del sistema.

Reiniciar EC2

A continuación vamos a asignar un IP Elástica a nuestra instancia (IP estática). Para ello hacemos clic en el panel izquierdo: Red y Seguridad → IP Elástica → Asignar la dirección Elástica.

Asignar IP Elástica

Pulsamos asignar y veremos la IP estática creada. Pulsamos sobre la etiqueta Name y le ponemos un nombre descriptivo. Por ejemplo, IP Elástica XYZ-SSH-Server.

IP Elástica

Ahora pulsamos en Acciones → Asociar la dirección IP Elástica

Asociar IP Elástica

En la siguiente pantalla seleccionamos la instancia SSH-Server y pulsamos Asociar. De este modo nuestro servidor SSH siempre va a tener la misma dirección IP Pública.

Otra cosa interesante que podemos hacer es transferir ficheros desde nuestro PC hacia el servidor mediante el comando: scp. Por ejemplo, para transferir el fichero: saludo.txt desde el PC hacia la instancia EC2. Ejecutamos el siguiente comando:

1
2
touch saludo.txt
scp -i labsuser.pem ./saludo.txt admin@34.237.158.189:/home/admin

El resultado obtenido debería de ser :

Transferir ficheros a la EC2

Implantación de una web estática en bucket S3 (S3)

Pasos a seguir:

  • Crear un bucket en Amazon S3
  • Cargar contenido al bucket
  • Habilitar el acceso a los objetos del bucket
  • Actualizar el sitio web

Tarea 1: crear un bucket en Amazon S3

En esta tarea, crearás un bucket de S3 y lo configurarás para el alojamiento de sitios web estáticos.

  1. En la Consola de administración de AWS, en el menú Services (Servicios), elige S3.
  2. Elige Create bucket (Crear bucket).
Atención!

El nombre de un bucket de S3 es único a nivel global, y el espacio de nombres se comparte entre todas las cuentas de AWS. Luego de haber creado un bucket, ese nombre no se podrá utilizar por otra cuenta de AWS en ninguna región de AWS a menos que elimines el bucket. Por lo tanto, para este laboratorio, utilizarás un nombre de bucket que incluya un número aleatorio, como website-123.

  1. En Bucket name (Nombre del bucket), escribe: website-<123> (sustituye <123> con un número aleatorio).

El acceso público a los buckets está bloqueado de forma predeterminada. Dado que los archivos de tu sitio web estático deben ser accesibles a través de Internet, debes permitir el acceso público.

  1. En la sección Object Ownership (Propiedad del objeto), selecciona ACLs enabled (ACL habilitadas), luego verifica que Bucket owner preferred (Propietario preferido del bucket) esté seleccionado.

  2. Desactiva Block all public access (Bloquear todo el acceso público) y, luego, selecciona la casilla que indica I acknowledge that the current settings may result in this bucket and the objects within becoming public (Reconozco que la configuración actual puede dar lugar a que este bucket y los objetos dentro de él se conviertan en públicos).

  3. Elige Create bucket (Crear bucket).

Puedes utilizar etiquetas para agregar información adicional a un bucket, como un código de proyecto, un centro de costos o un propietario.

A continuación, configurarás el bucket para el alojamiento de sitios web estáticos.

  1. Quédate en la consola Properties (Propiedades).

  2. Desplázate hasta el panel Static website hosting (Alojamiento de sitios web estáticos).

  3. Elige Edit (Editar).

  4. Configura los siguientes ajustes:

    • Static web hosting (Alojamiento web estático): habilitado.
    • En Hosting type: (Tipo de alojamiento), elige Host a static website (Alojar un sitio web estático).
    • Index document (Documento de índice): index.html.
    • Nota: Debes escribir este valor, aunque ya se muestre.
    • Error document (Documento de error): error.html.
  5. Elige Save changes (Guardar cambios).

  6. En el panel Static website hosting (Alojamiento de sitios web estáticos), selecciona el enlace debajo de Bucket website endpoint (Punto de enlace del sitio web del bucket).

    Recibirás un mensaje 403 Forbidden (403 Prohibido) porque aún no se han configurado los permisos del bucket. Mantén esta pestaña abierta en tu navegador web para que puedas regresar a ella más tarde.

    Has configurado el bucket para alojar un sitio web estático.

Tarea 2: cargar contenido al bucket

En esta tarea, cargarás en el bucket los archivos que servirán para tu sitio web estático.

  1. Crea un archivo index.html con tu nombre

  2. Vuelve a la consola de Amazon S3 y en el bucket website-<123> que creaste anteriormente, elige la pestaña Objects (Objetos).

  3. Selecciona Upload (Cargar).

  4. Elige Add files (Agrega el archivo index.html).

  5. Selecciona Upload (Cargar).

Los archivos se cargan en el bucket.

  • Selecciona Close (Cerrar).

Tarea 3: habilitar el acceso a los objetos

De forma predeterminada, los objetos almacenados en Amazon S3 son privados. Esto garantiza que los datos de tu organización permanecen seguros.

En esta tarea, lograrás que los objetos cargados tengan acceso público.

En primer lugar, confirma que actualmente los objetos sean privados.

  1. Vuelve a la pestaña del navegador que muestra el mensaje 403 Forbidden (403 Prohibido).
  2. Actualiza la página web.
Más información

Si cerraste accidentalmente esta pestaña, ve a la pestaña Properties (Propiedades) y, en el panel Static website hosting (Alojamiento de sitios web estáticos), selecciona Endpoint (Punto de enlace).

Aún deberías ver el mensaje 403 Forbidden (403 Prohibido).

Análisis: ¡Esta es la respuesta esperada! Este mensaje indica que Amazon S3 aloja tu sitio web estático, pero que el contenido es privado.

Puedes hacer públicos los objetos de Amazon S3 de dos maneras diferentes:

  • Para hacer público un bucket completo o un directorio específico dentro del bucket, utiliza una política de bucket.
  • Puedes utilizar una lista de control de acceso (ACL) para hacer públicos objetos individuales en un bucket.

En general, es más seguro hacer públicos objetos individuales porque esto evita que otros objetos se hagan públicos por accidente. Sin embargo, si sabes que la totalidad del bucket no contiene información confidencial, puedes utilizar una política de bucket.

Ahora configurarás los objetos individuales para que sean accesibles públicamente.

  1. Vuelve a la pestaña del explorador web con la consola de Amazon S3 (pero no cierres la pestaña del sitio web).

  2. Selecciona los tres objetos.

  3. En el menú Actions (Acciones), elige Make public via ACL (Hacer público a través de ACL).

Se muestra una lista de los tres objetos.

  1. Selecciona Make public (Hacer público).

Tu sitio web estático ahora es accesible públicamente.

  1. Vuelve a la pestaña del navegador web que tiene el mensaje 403 Forbidden (403 Prohibido).

  2. Actualiza la página web.

Ahora deberías ver el sitio web estático alojado por Amazon S3.

Tarea 4: Actualizar el sitio web

Puedes modificar el sitio web al editar el archivo HTML y cargarlo de nuevo en el bucket de S3.

Consejo

Amazon S3 es un servicio de almacenamiento de objetos, por lo que debes cargar el archivo completo. Esta acción reemplazará al objeto existente en el bucket. No se puede editar el contenido de un objeto, debe sustituirse por completo.

  1. En tu equipo, carga el archivo index.html en un editor de texto (por ejemplo, Bloc de notas o TextEdit).
  2. Busca el texto Served from Amazon S3 (Entregado desde Amazon S3) y sustitúyelo por Created by y reemplaza <YOUR-NAME> por tu nombre (por ejemplo, Creado por David).
  3. Guarda el archivo.
  4. Vuelve a la consola de Amazon S3 y carga el archivo index.html que acabas de editar.
  5. Selecciona index.html y usa el menú Actions (Acciones) para elegir la opción Make public via ACL (Hacer público a través de ACL).
  6. Regresa a la pestaña del navegador web con el sitio web estático y actualiza la página.

Tu nombre debería estar ahora en la página.

El sitio web estático ahora es accesible en Internet. Debido a que está alojado en Amazon S3, el sitio web tiene una alta disponibilidad y puede entregar grandes volúmenes de tráfico sin necesidad de ningún servidor.

También puedes usar tu propio nombre de dominio para dirigir a los usuarios a un sitio web estático que se encuentre alojado en Amazon S3. Para lograrlo, puedes utilizar el servicio del sistema de nombres de dominio (DNS) de Amazon Route 53 combinado con Amazon S3.

Creación de un punto de montaje para copias de seguridad (EFS)

Pasos a seguir:

  • Configurar un Grupo de Seguirdad.
  • Configurar el servicio de Almacenamiento EFS.
  • Transferir una copia de seguridad desde un equipo de la organización al servicio de almacenamiento.

Tarea 1 : Configurar un grupo de seguridad

Vamos a configurar un grupo de seguridad para acceder al sistema de archivos de EFS. El grupo de seguridad se asocia a un punto de montaje, que debe permitir el acceso de entrada para TCP en el puerto 2049 para Network File System (NFS).

Este es el grupo de seguridad que ahora creará, configurará y asociará a los destinos de montaje de EFS.

  1. Accedemos al panel EC2.

  2. Seleccionamos en el panel de navegación de la izquierda -> Security Groups.

  3. Copiamos el ID del grupo de seguridad asociado al servicio SSH.

    Grupo de seguridad SSH

  4. Pulsamos sobre el botón: Crear Grupo de Seguridad.

  5. Nombre: ASO Punto de Montaje EFS.

  6. VPC: ASO-VPC

  7. Regla de Entrada: NFS, Origen: nuestro grupo de seguridad.

  8. Pulsamos: Crear grupo de seguridad.

    Crear grupo de Seguridad

Tarea 2: Configurar el servicio de almacenamiento EFS

  1. Accedemos al panel de administración EFS y pulsamos sobre: Crear un sistema de archivos, y pulsamos personalizar.

  2. Como nombre ponemos: ASO Backups.

  3. Clase de almacenamiento: Estándar.

  4. Desactivamos: copias de seguridad automáticas.

  5. Agregamos etiqueta: name, valor: ASO sistema de archivos EFS.

  6. Pulsamos: Siguiente.

  7. En configuración de Red, seleccionamos nuestra VPC: ASO-VPC.

  8. Eliminamos el Grupo de seguridad que aparece por defecto.

  9. Agregamos nuestra subred: ASO-VPC-subnet-public, y nuestro grupo de seguridad.

  10. Pulsamos siguiente.

    Acceso a la red

  11. Paso 3, siguiente.

  12. Paso 4, crear.

    Sistemas de archivos

  13. Seleccionamos nuestro sistema de archivos, y pulsamos sobre el botón: Asociar.

  14. Copiamos el comando de montaje mediante cliente NFS.

Tarea 3: Transferir una copia de seguridad

En este punto volvemos al terminal de la instancia EC2 (que hemos creado anteriormente), y vamos a configurar el punto de montaje del sistema de archivos EFS.

  1. Ejecutamos el comando:

    1
    sudo yum install -y amazon-efs-utils
    
  2. Creamos el directorio que nos sirve como punto de montaje:

    1
    sudo mkdir efs
    
  3. Copiamos en el terminal el comando de montaje.

    1
    sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,nores vport fs-09cff32e3f3d07dff.efs.us-east-1.amazonaws.com:/ efs
    
  4. Comprobamos que el sistema de archivos se ha montado correctamente, ejecutamos el comando: df -hT

    Comando df -hT

  5. Cambiamos el propietario del directorio: efs

    1
    sudo chown ec2-user.ec2-user ./efs
    
  6. Cambiamos los permisos:

    1
    sudo chmod 700 ./efs
    
  7. Transferimos desde un ordenador de nuestra organización la copia de seguridad hasta el directorio efs de la máquina EC2:

    1
    sudo scp -i labsuser.pem ./backup.tgz ec2-user@3.92.134.58:/home/ec2-user/efs
    
  8. Comprobamos la transferencia de la copia de seguridad.

    Comprobar copia

  9. Por último, si queremos que el sistema de archivos se monte de forma automática, debemos de agregar en la máquina virtual EC2 la siguiente línea en el fichero: /etc/fstab.

    1
    fs-09cff32e3f3d07dff.efs.us-east-1.amazonaws.com:/ /home/ec2-user/efs nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,_netdev 0 0
    

    Para montar la unidad ejecutamos:

    1
    sudo mount /home/ec2-user/efs
    

Bases de datos con AWS (RDS)

Pasos a seguir:

  • Instalar mariadb en una instancia EC2
  • Restaurar una base de datos
  • Cambiar configuración en mariadb
  • Crear una base de datos RDS
  • Cambiar configuración en RDS
  • Copias de seguridad en RDS

Podemos usar la máquina EC2 creada previamente, o usar una nueva.

Tarea 1: conectar a la instancia EC2 e instalar MariaDB

  • EC2 -> Instancias

  • Seleccionar la EC2 en la que instalaremos MariaDB

  • [Conectar]

  • Instalar mariadb y arrancar servicio

1
2
3
sudo yum install -y mariadb-server.x86_64
sudo systemctl start mariadb
sudo systemctl enable mariadb

MariaDB quedará activado y en funcionamento

Tarea 2: descargar BBDD y restaurar

Descargaremos la BBDD world de MySQL:

1
2
3
wget https://downloads.mysql.com/docs/world-db.zip
unzip world-db.zip
sudo mysql < world-db/world.sql

Ahora comprobaremos que la BBDD de MariaDB esta funcionando correctamente en nuestra máquina EC2.

1
2
3
4
5
6
sudo mysql
mysql> show databases;
mysql> use world;
mysql> show tables;
mysql> select * from city limit 100;
mysql> show grants;

Tarea 3: cambiar configuración en MariaDB

Desde la instancia EC2 vamos a cambiar el número de conexiones máximas simultáneas:

  • Editar archivo de configuración

  • Comprobamos el valor de max_connections:

    1
     sudo mysql -e “show variables like ‘max_conn%’”
    

    img

  • Vamos a cambiar a 10 su valor:

1
sudo nano /etc/my.cnf.d/server.cnf

añadir la línea siguiente dentro de la sección [mysqld]:

1
max-connections = 10
  • Reiniciamos el servicio de MariaDB para que los cambios surtan efecto:
1
sudo systemctl restart mariadb
  • Volvemos a comprobar el valor para asegurarnos que ha funcionado correctamente:
1
sudo mysql -e “show variables like ‘max_conn%’”

Tarea 4: crear base de datos RDS

Esta es otra manera de crear una BBDD.

  1. Vamos al servicio RDS Y elegimos [Crear base de datos]

  2. Método creación: Estándar o sencilla

Elegimos estándar pues la sencilla utiliza máquinas mucho más potentes (caras) y no nos permite ver todas las posibilidades.

  • Tipo de motor: MySQL

  • Plantillas: Desarrollo y pruebas

  • Disponibilidad y durabilidad: Instancia de base de datos única. Para emular lo que tenemos sobre EC2, después veremos el resto de opciones.

  • Configuración:

  • Identificador: mibbdd1

  • Contraseña: Mínimo 8 caracteres ASCII imprimibles.

  • Configuración de la instancia:

Clases con ráfagas (t) - db.t3.micro

Para las pruebas nos sobra, para un entorno en producción habría que elegir el que más se ajuste a la carga de trabajo. Ojo, el coste se puede disparar.

  • Almacenamiento: SSD de IOPS provisionadas (io1). Ver el resto, para las pruebas no va a ser determinante.

Almacenamiento asignado: 100. IOPS provisionadas: 1000. Escalado automático: Deshabilitar.

  • Conectividad:

Recurso de computación: Conectarse a un recurso informático EC2 o podemos elegir que la cree por nosotros en este momento.

Instancia de EC2: elegir la creada anteriormente

No nos dejará marcar acceso público, no lo necesitamos. También se encargará de configurar grupo de seguridad para poder conectar EC2 con RDS.

Tipo de red: IPv4

Grupo de subredes: Configuración automática

​ Resto de opciones dejamos como están.

  • Configuración adicional:

Puerto de la bbdd: 3306

  • Autenticación de bases de datos

Autenticación con contraseña

  • Supervisión

Deshabilitar monitorización mejorada

  • Configuración adicional Opciones de base de datos:

Dejar valores propuestos

  • Copia de seguridad:

Deshabilitar las copias de seguridad automatizadas

Resto de opciones dejamos

  • Elegimos el botón [Crear base de datos]

La creación de la base de datos tarda unos minutos.

Mientras se está creando en el estado aparecerá: “Creando

Creando BBDD

Una vez creada aparecerá un banner en la parte superior.

BBDD Creada

  1. Ahora revisaremos las opciones de nuestra BBDD RDS:

En la pestaña Conectividad y seguridad:

Conectividad y seguridad

Fíjate en el Punto de enlace que necesitarás más adelante

  1. También comprobaremos la conexión desde la máquina virtual EC2

Desde la consola de EC2:

1
mysql -u admin -p -h punto_de_enlace

En el ejemplo anterior seria:

1
- mysql -u admin -p -h mibbdd1.cffyiqzvud19.us-east-1.rds.amazonaws.com

Si hemos cambiado el puerto tendremos que añadir -P puerto.

  1. Subir BBDD a RDS desde EC2

O bien conectamos como antes y desde dentro de mysql hacemos:

1
mysql> source world.sql;

O bien,

1
- mysql -u admin -p -h mibbdd1.cffyiqzvud19.us-east-1.rds.amazonaws.com < world.sql
  1. Comprobar world en RDS

O accedemos, o ejecutamos con -e

1
show databases;

Tarea 5: cambiar opciones de configuración en RDS

Para cambiar la configuración en RDS debemos hacerlo a través del grupo de parámetros. El grupo por defecto que hemos seleccionado al crear la BBDD no se puede modificar, debemos crear un grupo de parámetros nuevo y asignar a nuestra BBDD.

  • Crear grupo de parámetros

RDS > Parameter groups > [Create parameter group] > mis-parametros

  • Comparar valores

Seleccionar default y mis-parametros y en acciones -> Compare

  • Asignar grupo creado a mibbdd1

  • Para ello ir a modificar mibbdd1 y seleccionar como grupo de parámetros mis-parametros.

  • Tras aplicar tarda un rato en estado “modificando” y aún así no se aplican los cambios, hasta reiniciar. Lo indica si consultamos la pestaña de configuración de la BBDD, aparece el grupo mis-parametros pero pendiente de reinicio.

  • Reinciamos la BBDD y comprobamos que se ha cambiado el valor.

Tarea 6: copias de seguridad en RDS

Se pueden activar a través de Acciones rápidas -> Activar copias de seguridad o modificando la BBDD.

Para activar modificando lo único que hay que hacer es asignar un periodo de retención. También es conveniente elegir la ventana de tiempo en la que se realizarán las copias.

Si queremos activar la replicación de copias de seguridad en otra región de AWS deberemos crear previamente las claves KMS para la encriptación en esa otra zona.

Una vez modificados, antes de darle a [Modificar la instancia de la bbdd] seleccionar aplicar inmediatamente. Aún así tarda un tiempo, el estado se pondrá en “Modificando” y hasta que no termine no será efectivo. Al activar las copias de seguridad se crea un primer backup.

Sockets con AWS (Cloud9)

Pasos a seguir:

  • Preparar entorno de la nube
    • Iniciar Laboratorio
    • Crear entorno Cloud9
    • Creación de servidor de Sockets
    • Abrir puerto en la instancia EC2 de Cloud9
    • Dirección pública de la EC2
  • Preparar cliente local
  • Ejecución de la prueba
    • Desde el punto de vista del cliente
    • Desde el punto de vista del servidor

Tarea 1: Preparar el entorno en la nube

Iniciar Laboratorio

Lo primero que necesitamos es arrancar el laboratorio, para ello Accedemos al LMS del awsacademy, buscamos el Curso facilitado por el docente, accedemos a sus contenidos y a continuación al Learner Lab. (Si es la primera vez que accedemos debemos aceptar los términos de uso).

Inicialmente el laboratorio está en rojo:

Estado inicial del laboratorio

Elegimos la opción Start Lab y esperamos a que aparezca el laboratorio en verde:

Laboratorio iniciado correctamente

Por defecto el Learner Lab nos proporciona 100 dolares de saldo, y un tiempo de 4 horas, tras el cual se detendrán la mayoría de servicios que tengamos en marcha. Pero mientras quede saldo podemos volver a iniciar el Laboratorio y dispondremos de 4 horas más.

Una vez aparece en verde podemos hacer click sobre las letras AWS y aparecerá el Dashboard de AWS (debemos permitir las ventanas emergentes):

Dashboard AWS

Crear un entorno Cloud9

Cloud9 es un entorno de desarrollo en la nube que proporciona AWS asociado a una instáncia EC2 (máquina virtual en la nube).

El primer paso es crear este entorno, para ello buscamos cloud9 en la parte superior del Dashboard:

Buscar cloud9 en el dashboard

A continuación seleccionamos Create environment:

Crear el entorno

En la siguiente ventana debemos especificar el nombre (Name), cambiaremos la plataforma a Ubuntu Server 18.04 LTS, también podemos ampliar el tiempo de Timeout para no tener problemas a 4 horas i por último dentro de los Network settings elegiremos la conexión por SSH, el resto de opciones se quedan por defecto y pulsamos el botón naranja del final Create.

Propiedades del cloud9

Propiedades del cloud9

Si todo ha ido bien podemos seleccionar el botón Open:

Abrir el entorno creado

Y deberíamos ver algo parecido a esto:

Entorno cloud9 en ejecución

Creación del servidor de Sockets

Primero cerraremos la ventana de bienvenida, a continuación creamos un nuevo fichero, por ejemplo ServidorSocket.java con el siguiente código java:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.io.*;
import java.net.*;

public class ServidorSocket {

    private static final int PORT=11000;

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String FraseClient;
        String FraseMajuscules;
        ServerSocket serverSocket;
        Socket clientSocket;
        ObjectInputStream entrada;
        ObjectOutputStream eixida;
        serverSocket = new ServerSocket(PORT);
        System.out.println("Server iniciado y escuchando en el puerto "+ PORT);
        while (true) {
            clientSocket = serverSocket.accept();
            entrada = new ObjectInputStream(clientSocket.getInputStream());
            FraseClient = (String) entrada.readObject();

            System.out.println("La frase recibida es: " + FraseClient);

            eixida = new ObjectOutputStream(clientSocket.getOutputStream());
            FraseMajuscules = FraseClient.toUpperCase();
            System.out.println("El server devuelve la frase: " + FraseMajuscules);
            eixida.writeObject(FraseMajuscules);

            clientSocket.close();
            System.out.println("Server esperando una nueva conexión...");
        }
    }
}

Debería quedar algo así:

Código fuente en cloud9

Y si iniciamos el servidor:

Servidor en la nube en marcha

Abrir el puerto en la instancia EC2 del cloud9

Ahora debemos volver a la pestaña donde tenemos el Dashboard de AWS y buscar EC2 (donde antes buscamos cloud9):

Buscar EC2 en el dashboard

Una vez abierto elegimos la opción Instancias (en ejecución):

Elegir instancias en ejecución

Deberíamos tener al menos una Instancia, si tenemos más de una debemos buscar la que contenga el nombre de nuestra instancia cloud9, debemos marcar el check que tiene justo delante del nombre y a continuación elegir la pestaña Seguridad:

Seleccionar la instancia y la pestaña seguridad

Si nos fijamos en las reglas de entrada del grupo de seguridad, solo tiene habilitada la entrada para el puerto 22 (SSH), a continuación hacemos click sobre el enlace del Grupo de seguridad:

Reglas de entrada

Y añadiremos el puerto 11000 (o el que hayamos elegido para nuestro servidor) a las reglas de entrada, elegimos el botón Editar reglas de entrada, a continuación Agregar regla Elegimos TCP Personalizado, puerto 11000 y AnywhereIpv4 y añadimos una descripción si lo deseamos:

Editar reglas

Una vez hecho esto si volvemos a la pestaña Seguridad de nuestra instancia EC2 veremos la regla añadida.

Dirección pública de la EC2

Necesitamos saber la DNS de IPv4 pública de nuestra instancia EC2 para acceder desde el cliente, marcamos el check de nuestra instancia y accedemos a la primera pestaña Detalles, y nos fijamos en la parte derecha y pulsaremos el botón de copiar y guardaremos esta información para más adelante:

Dirección pública de la EC2

Tarea 2: Preparar el cliente local

En nuestro IDE preferido creamos un nuevo archivo ClienteSocket.java con el siguiente código:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ClienteSocket {

    private static final String DNSAWS = "ec2-3-84-52-97.compute-1.amazonaws.com";

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Socket socket;
        ObjectInputStream entrada;
        ObjectOutputStream eixida;
        String frase;

        socket = new Socket(DNSAWS, 11000);
        eixida = new ObjectOutputStream(socket.getOutputStream());

        System.out.println("Introduce la frase a enviar en minúsculas");
        Scanner in = new Scanner(System.in);
        frase = in.nextLine();
        System.out.println("Se envia la frase " + frase);
        eixida.writeObject(frase);

        entrada = new ObjectInputStream(socket.getInputStream());
        System.out.println(
                "La frase recibida es: " + (String) entrada.readObject());
        socket.close();
    }
}
Consejo

Recuerda cambiar la constante DNSAWS por el String que corresponde con la dirección DNS IPv4 de tu instancia EC2 obtenida en el punto anterior.

Tarea 3: Ejecución de prueba

Desde el punto de vista del cliente

Una vez ejecutado el cliente debe aparecer algo similar a esto:

1
Introduce la frase a enviar en minúsculas

Escribimos nuestra frase, y al pular INTRO obtenemos el siguiente resultado:

1
2
3
4
Introduce la frase a enviar en minúsculas
esta frase está en minúsculas
Se envia la frase esta frase está en minúsculas
La frase recibida es: ESTA FRASE ESTÁ EN MINÚSCULAS

Desde el punto de vista del servidor

La consola de salida del servidor por su parte debe haber registrado la conexión del cliente, la recepción de la frase, y la frase devuelta:

1
2
3
4
Server iniciado y escuchando en el puerto 11000
La frase recibida es: esta frase está en minúsculas
El server devuelve la frase: ESTA FRASE ESTÁ EN MINÚSCULAS
Server esperando una nueva conexión...

BBDD en la nube (RDS) desde IntelliJ

Pasos a seguir:

  • Preparar entorno de la nube
    • Iniciar Laboratorio
    • Crear una BBDD en AWS (RDS)
    • Abrir puertos
    • Dirección pública de la BBDD
  • Cargar datos desde Intellij
    • Instalar MySQL WorkBench
    • Conexión de prueba
    • Importar datos de muestra
  • Preparar cliente local:
    • Descargar conector MySQL
    • Código del cliente
  • Ejecución de prueba
    • Desde el punto de vista del cliente

Tarea 1: Preparar el entorno de la nube

Iniciar Laboratorio

Lo primero que necesitamos es arrancar el laboratorio, para ello Accedemos al LMS del awsacademy, buscamos el Curso facilitado por el docente, accedemos a sus contenidos y a continuación al Learner Lab. (Si es la primera vez que accedemos debemos aceptar los términos de uso).

Inicialmente el laboratorio está en rojo:

Estado inicial del laboratorio

Elegimos la opción Start Lab y esperamos a que aparezca el laboratorio en verde:

Laboratorio iniciado correctamente

Por defecto el Learner Lab nos proporciona 100 dolares de saldo, y un tiempo de 4 horas, tras el cual se detendrán la mayoría de servicios que tengamos en marcha. Pero mientras quede saldo podemos volver a iniciar el Laboratorio y dispondremos de 4 horas más.

Una vez aparece en verde podemos hacer click sobre las letras AWS y aparecerá el Dashboard de AWS (debemos permitir las ventanas emergentes):

Dashboard AWS

Crear una BD en AWS

Debemos buscar el apartado Amazon RDS:

Buscar RDS

Una vez aquí debemos pulsar el botón [Crear base de datos]:

Screenshot_20230404_113411

Ahora debemos elegir las opciones para nuestra base de datos:

Al Crear base de datos dejamos la Creación estándar por defecto:

Método de creación

En Opciones del motor elegimos MariaDB (Como versión puedes elegir la más moderna que aparezca):

Opciones del motor

En Plantillas elegimos la Capa gratuita:

Plantillas

A continuación, en Configuración:

Elegimos el Identificador de instancias de bases de datos, podemos poner el que más nos guste, en mi caso databaseDMP, también debemos indicar el username, en mi caso admin, y por último la Contraseña maestra y su confirmación, que deberá tener más de 8 carácteres ASCII imprimibles, en mi caso 123456Ab$.

Atención

Anota todos estos datos en un lugar seguro, los necesitarás más adelante.

Apartado Configuración

En la Configuración de la instancia dejamos todo por defecto:

Screenshot_20230404_114838

En Almacenamiento dejamos el Almacenamiento asignado en 20GiB y deshabilitamos el escalado automático del almacenamiento:

Screenshot_20230404_114929

Dejamos Disponibilidad y durabilidad por defecto.

Disponibilidad y durabilidad

En el apartado Conectividad dejamos todo por defecto excepto la opción de Acceso público que debemos indicar que :

Conectividad

En la parte baja elegiremos crear un nuevo Grupo de seguridad de VPC y el puerto 3306, el resto de opciones por defecto:

Grupo de seguridad

En el apartado Configuración adicional indicamos starwars como nombre de la base de datos inicial y cambiamos el periodo de retención de copias a 1 dia:

Configuración adicional

dejamos el resto de opciones por defecto y pulsaremos el botón del final [Crear base de datos]:

Crear base de datos

Si todo ha ido bien AWS nos indica que se está creando la BD y puede tardar unos minutos:

Creando BD

Una vez aparezca el estado en Disponible, podremos pasar al siguiente paso:

Screenshot_20230404_120627

Abrir puertos para el acceso público

Ahora abriremos el puerto necesario para la que la BD sea accesible desde el exterior, para ello haremos clic sobre el nombre de la base de datos:

Clic en el nombre de la BD

Y en la siguiente ventana hacemos click sobre el Grupo de seguridad de la VPC :

Grupo de seguridad

Una vez estamos en el apartado de Grupos de seguridad, debemos elegir la pestaña Reglas de entrada, y el botón Editar reglas de entrada:

Editar reglas de entrada

Si hemos seguido correctamente la guia debería aparecer el puerto 3306 abierto, pero solo para la ip pública desde la que estamos accediendo, así que deberemos pulsar la x para eliminar esa ip:

Puerto 3306

Y por último agrega la ip 0.0.0.0 para que sea acesible desde cualquier lugar:

ip 0.0.0.0

Dirección pública de la BBDD

Ahora necesitamos la URL de acceso a la BD desde el exterior, primero volvemos al apartado RDS:

Buscar RDS

y a continuación haremos clic sobre el nombre de la base de datos:

Clic en el nombre de la BD

Y en la siguiente ventana encontraremos los datos que necesitamos, por un lado el Punto de enlace (databasedmp.cm6pc9b4jil5.us-east-1.rds.amazonaws.com) y por otro el Puerto (3306):

Punto de enlace y puerto

Con toda esta información podemos realizar conexiones desde el exterior.

Tarea 2: Carga de datos desde IntelliJ

Instalar MySQL WorkBench

Dependiendo de nuestro sistema operativo deberemos usar un procedimiento u otro, lo mejor es consultar la página web y seguir sus instrucciones:

https://www.mysql.com/products/workbench/

Conexión de prueba

Una vez instalado nuestro cliente configuraremos una nueva conexión con los datos que hemos guardado en pasos anteriores, indicaremos el Connection Name (nombre de la conexión), Hostname (URL de la base de datos), y username (usuario de la base de datos). Al pulsar el botón Test Connection, nos permite probar la conexión y nos pedirá el password, y si pulsamos OK se guardará.

Crear conexión

Es posible que nos indique que puede haber problemas de compatibilidad, pero podemos dar a Continue anyway sin preocuparnos.

Continue anyway

Y deberíamos ver nuestro entorno de modo similar a este:

Entorno

Importar datos de muestra

Para no trabajar con una base de datos vacía partiremos de una base de datos con información que podemos encontrar en el siguiente enlace: https://github.com/miguelmarti/FreakDataBases

En concreto usaremos la de StarWars.sql, la descargaremos de github, abriremos el archivo con nuestro editor preferido, copiaremos todo su contenido y lo pegaremos en la ventana blanca del entorno. A continuación pulsamos el rayo para ejecutar el script, y por último el botón para refrescar el contenido de las tablas:

Pegar starwars.sql

Una vez hecho todo esto debería tener al menos 7 tablas:

Screenshot_20230404_163800

Cuando comprobemos que tenemos la 7 tablas, podemos seguir.

Tarea 3: Preparar el cliente local

Descargar MySQL connector

En este punto deberias añadir a tu proyecto de IntelliJ el conector de MySQL. Hay muchas maneras de hacerlo, añandiendo el jar, con un gestor de dependencias como Maven o Gradle). Si no estas familiarizado con esto, te dejo el enlace a un taller que les proporciono a mis alumnos de Programación de 1º de DAM: Taller Conectores IntelliJ.

Código del cliente

En nuestro IDE preferido creamos un nuevo archivo AWSTest.java con el siguiente código:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package UD10.AWS;

import java.sql.*;
import java.util.Scanner;

/**
 *
 * @author David Martínez (wwww.martinezpenya.es|ieseduardoprimo.es)
 */
public class AWSTest {

    private static final String AWSDNS = "databasedmp.cm6pc9b4jil5.us-east-1.rds.amazonaws.com";
    private static final String DBNAME = "starwars";
    private static final int PUERTO = 3306;
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "123456Ab$";

    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        try (Connection con = DriverManager.getConnection("jdbc:mysql://" + AWSDNS + ":" + PUERTO + "/" + DBNAME, USERNAME, PASSWORD);) {
            Statement stmt = con.createStatement();
            //Query sin parámetros
            ResultSet rs = stmt.executeQuery("select * from films");
            System.out.println("Estas son las películas de Star Wars");
            while (rs.next()) {
                System.out.println(rs.getInt(1) + "  " + rs.getString(2) + "  " + rs.getString(3));
            }
            System.out.print("Elige un número de película y te mostraré los personajes que aparecen en ella: ");
            String numPelicula = sc.nextLine();
            PreparedStatement pStmt = con.prepareStatement("SELECT C.id, name, C.height, C.mass, C.hair_color, C.skin_color "
                    + "FROM starwars.characters C, starwars.character_films CF, starwars.films F "
                    + "WHERE F.id=CF.id_film AND CF.id_character=C.id "
                    + "AND CF.id_film = ?;");
            pStmt.setString(1, numPelicula);
            //Query con parámetros
            ResultSet rs2 = pStmt.executeQuery();
            while (rs2.next()) {
                System.out.println(rs2.getInt(1) + "  " + rs2.getString(2) + "  " + rs2.getInt(3) + "  " + rs2.getFloat(4) + "  " + rs2.getString(5) + "  " + rs2.getString(6));
            }
            con.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
Consejo

Recuerda cambiar la constante AWSDNS, DBNAME, PUERTO, USERNAME y PASSWORD por el String o int que corresponda con tu configuración.

Tarea 4: Ejecución de prueba

Desde el punto de vista del cliente

Una vez ejecutado el cliente debe aparecer algo similar a esto:

1
2
3
4
5
6
7
8
Estas son las películas de Star Wars
1  Episode I  The Phantom Menace
2  Episode II  Attack of the Clones
3  Episode III  Revenge of the Sith
4  Episode IV  A New Hope
5  Episode V  The Empire Strikes Back
6  Episode VI  Return of the Jedi
Elige un número de película y te mostraré los personajes que aparecen en ella: 

Y si a continuación elegimos por ejemplo la película 4:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Elige un número de película y te mostraré los personajes que aparecen en ella: 4
1  Luke Skywalker  172  77.0  blond  fair
2  C-3PO  167  75.0  n/a  gold
3  R2-D2  96  32.0  n/a  white, blue
4  Darth Vader  202  136.0  none  white
5  Leia Organa  150  49.0  brown  light
6  Owen Lars  178  120.0  brown, grey  light
7  Whitesun lars  165  75.0  brown  light
8  R5-D4  97  32.0  n/a  white, red
9  Biggs Darklighter  183  84.0  black  light
10  Obi-Wan Kenobi  182  77.0  auburn, white  fair
12  Wilhuff Tarkin  180  0.0  auburn, grey  fair
13  Chewbacca  228  112.0  brown  null
14  Han Solo  180  80.0  brown  fair
15  Greedo  173  74.0  n/a  green
18  Wedge Antilles  170  77.0  brown  fair
19  Jek Tono Porkins  180  110.0  brown  fair
81  Raymus Antilles  188  79.0  brown  light
89  Cornelius Evazan  0  0.0  null  null
90  Ponda Baba  0  0.0  null  null

Infraestructura de red de tres capas (VPC)

Vamos a crear una arquitectura de red segura en AWS que implemente una aplicación web de 3 capas, aplicando principios de seguridad y segmentación de red.

Schema

Escenario

Una empresa necesita desplegar una aplicación web con tres capas:

  • Capa de Presentación: Servidores web accesibles desde Internet
  • Capa de Aplicación: Servidores de lógica de negocio
  • Capa de Base de Datos: Servidores de base de datos

Requisitos Técnicos

1. Topología de Red

  • VPC Principal: 10.0.0.0/16
  • 1 Subred Pública (capa de presentación)
  • 2 Subredes Privadas (capa de aplicación y BD)
  • Tablas de rutas específicas para cada tipo de subnet

2. Seguridad por Capas

  • Capa Presentación: Accesible desde Internet (puerto 80/443)
  • Capa Aplicación: Solo accesible desde Capa Presentación (puerto 3000)
  • Capa Base de Datos: Solo accesible desde Capa Aplicación (puerto 5432)

Tareas a Realizar

Parte 1: Creación de la VPC y Subnets

Estructura de subnets propuesta:

  • Subnet Pública: Presentacion 10.0.1.0/24
  • Subnet Privada Aplicacion: 10.0.10.0/24
  • Subnet Privada BaseDatos: 10.0.20.0/24

El primer paso para construir una infraestructura AWS robusta es crear una VPC (Virtual Private Cloud) para aislar y proteger tus recursos. Piensa en una VPC como tu sección personal de la nube de AWS: una red privada donde tienes control total sobre todo lo que hay dentro, incluyendo los bloques CIDR, los rangos de IP y las configuraciones de seguridad. Al usar una VPC, puedes segmentar eficientemente los niveles de tu aplicación en subredes específicas para una mejor organización y seguridad.

Para comenzar:

  1. Dirígete a la Consola de AWS y busca VPC.
  2. En el panel de control de VPC, selecciona Crear VPC.

Configuración de la VPC: En la configuración de la VPC, tendrás dos opciones:

  • Solo VPC: Esto crea solo la VPC con un bloque CIDR, dejando que configures las subredes, las puertas de enlace NAT y otros recursos manualmente.
  • VPC y más: Esta opción acelera la productividad al permitirte configurar múltiples recursos, incluyendo el número de Zonas de Disponibilidad (AZ), subredes públicas y privadas, y puertas de enlace NAT, de una sola vez.

Para mayor eficiencia y simplicidad, selecciona VPC y más. Esto te permitirá crear:

  • Subredes públicas y privadas para aislar los niveles de la aplicación.
  • Una puerta de enlace NAT, que garantiza una comunicación segura entre tus subredes privadas e internet.

Crear VPC 1

Crear VPC 2

Después de finalizar tus configuraciones, haz clic en Crear VPC. El proceso de creación suele tomar unos 5 minutos. No es necesario que te preocupes por configurar las tablas de enrutamiento; la opción VPC y más se encarga de ello por ti. Si deseas ver un adelanto de tu configuración, selecciona Vista previa del código para visualizar cómo quedará la VPC antes de confirmar los cambios.

Crear VPC 3

Proceso de creación:

Crear VPC 4

Parte 2: Configuración de Gateways y Rutas

  1. Internet Gateway para tráfico público
  2. NAT Gateway en subnets públicas para salida a Internet desde subnets privadas
  3. Tablas de rutas personalizadas para cada subnet

Al haber usado "Crear VPC y más" en el paso anterior tenemos todo esto ya configurado y listo.

Parte 3: Grupos de Seguridad

Ahora seguimos en el Panel de VPC, dentro del apartado Seguridad, encontramos la opción "Grupos de seguridad".

Los grupos de seguridad funcionan como cortafuegos virtuales a nivel de instancia que controlan el tráfico entrante y saliente. A diferencia de los firewalls tradicionales, solo permiten reglas de "allow" (permitir) y son stateful: si se permite una solicitud entrante, automáticamente se permite la respuesta saliente.

Cada instancia EC2 puede tener asociados uno o más grupos de seguridad que filtran el tráfico basándose en puertos, protocolos y direcciones IP origen/destino, siendo fundamentales para implementar el principio de menor privilegio en arquitecturas multicapa como la tuya.

Vamos a crear 3 grupos de seguridad gs, uno para cada EC2, asegurate que pertenecen al VPC que hemos creado:

Presentación (gs-presentacion):
  • Reglas de Entrada:

    • HTTP (80) desde 0.0.0.0/0
    • HTTPS (443) desde 0.0.0.0/0
    • SSH (22) desde 0.0.0.0/0, aunque lo más seguro seria desde tu IP pública (para administración) !!! example "Reglas de entrada gs-presentacion" Presentación: Reglas de Entrada
  • Reglas de Salida:

    • TCP (3000) hacia gs-aplicacion (node.js) (necesitaras crear primero gs-aplicacion)
    • HTTP (80) hacia 0.0.0.0/0 (para updates)
    • HTTPS (443) hacia 0.0.0.0/0 (para updates).
    • SSH (22) hacia gs-aplicacion (administración) (necesitaras crear primero gs-aplicacion) !!! example "Reglas de salida gs-presentacion" Presentación: Reglas de Salida
Aplicación (gs-aplicacion):
  • Reglas de Entrada:

    • TCP (3000) desde gs-presentacion (node.js) (asegurate que asocias el gs al vpc correcto, sino no aparecerá el gs-presentacion en el desplegable)
    • TCP (22) desde gs-presentacion (administración) !!! example "Reglas de entrada gs-aplicacion" Aplicación: Reglas de Entrada
  • Reglas de Salida:

    • TCP (5432) hacia gs-basedatos (postgresql) (necesitaras crear primero el gs-basedatos)
    • TCP (22) hacia gs-basedatos (administración) (necesitaras crear primero el gs-basedatos)
    • HTTP (80) hacia 0.0.0.0/0 (para updates)
    • HTTPS (443) hacia 0.0.0.0/0 (para updates) !!! example "Reglas de salida gs-aplicacion" Aplicación: Reglas de Salida
Base de Datos (gs-basedatos):
  • Reglas de Entrada:

    • TCP (5432) desde gs-aplicacion (postgresql)
    • TCP (22) desde gs-aplicacion (administración) !!! example "Reglas de entrada gs-basedatos" Base de Datos: Reglas de Entrada
  • Reglas de Salida:

    • HTTP (80) hacia 0.0.0.0/0 (para updates)
    • HTTPS (443) hacia 0.0.0.0/0 (para updates) !!! example "Reglas de salida gs-basedatos" Base de Datos: Reglas de Salida

Recordatorio

Recuerda, ahora que ya tienes todos los grupos de seguridad, volver hacia atrás y añadir las reglas que dependían de la creación de grupos de seguridad que aún no existían.

Parte 4: Instancias EC2

Amazon EC2 (Elastic Compute Cloud) es el servicio fundamental de computación en la nube de AWS que proporciona servidores virtuales escalables y de autoservicio en la nube, permitiendo lanzar y gestionar instancias (máquinas virtuales) con diversos sistemas operativos, capacidades de CPU, memoria, almacenamiento y configuraciones de red, ofreciendo control total sobre el entorno informático con un modelo de pago por uso y la capacidad de escalar horizontal o verticalmente según demanda.

Vamos a crear 3 instancias EC2 con Amazon Linux:

  1. servidor-presentacion (t3.micro)

    • En subnet privada de presentación, grupo de seguridad gs-presentacion
    • Nginx como proxy inverso (más adelante)
    • Crear nuevo par de claves vockey2. Guardar la clave privada: vockey2.pem, la necesitaremos más adelante para conectar por ssh.

      Crear EC2 1

    • Recuerda editar la configuración de red para poder elegir nuestro VPC, subred y grupo de seguridad (habilita la asignación automática de IP pública):

      Crear EC2 1

  2. servidor-aplicacion (t3.micro)

    • En subnet privada de aplicación, grupo de seguridad gs-aplicacion
    • Node.js (más adelante)
    • Elige la misma clave vockey2 que hemos generado en la primera EC2

    Crear EC2 2 4. servidor-basedatos (t3.micro)

    • En subnet privada de base de datos, grupo de seguridad gs-basedatos
    • PostgreSQL (más adelante)

    Crear EC2 3

Validación del Ejercicio

Tests de Conectividad

Para hacer la conexión usaremos reglas encadenadas (gracias Jorge López por tu práctica), esto hará que la única manera de acceder al servidor de aplicación sea desde el servidor de presentación, y desde allí al servidor de base de datos. Podemos consultar más inforamción en https://repost.aws/es/knowledge-center/ec2-linux-private-subnet-bastion-host, siguiendo estos pasos desde nuestro equipo con local en linux:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
ubuntu@fubuntu:~$ eval $(ssh-agent)
Agent pid 31884
ubuntu@fubuntu:~$ ssh-add vockey2.pem 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for 'vockey2.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
ubuntu@fubuntu:~$ chmod 400 vockey2.pem 
ubuntu@fubuntu:~$ ssh-add vockey2.pem 
Identity added: vockey2.pem (vockey2.pem)
ubuntu@fubuntu:~$ ssh-add -l
2048 SHA256:aSTLjccA71LIX8Up1sKFxynBVHqkS4IOhGTuChLMZ3M vockey2.pem (RSA)
ubuntu@fubuntu:~$ 

permisos vockey2.pem

Si obtienes un error sobre los permisos de vockey2.pem, puedes resolverlo asignando un permiso 400 con el comando chmod.

  1. Acceso a la Aplicación:

    Desde Internet, en nuestro equipo cliente, vamos a verificar la conexión con el equipo de presentación (público).

    Para ello, primero necesitamos su dirección pública:

    Verificar 1

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ubuntu@fubuntu:~$ ssh ec2-user@ec2-100-48-98-206.compute-1.amazonaws.com -A
    The authenticity of host 'ec2-100-48-98-206.compute-1.amazonaws.com (100.48.98.206)' can't be established.
    ED25519 key fingerprint is SHA256:vU7P9k8Y84HRz2x3B6iCJaNiepm05SeNI322HrkYNLc.
    This key is not known by any other names.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added 'ec2-100-48-98-206.compute-1.amazonaws.com' (ED25519) to the list of known hosts.
       ,     #_
       ~\_  ####_        Amazon Linux 2023
      ~~  \_#####\
      ~~     \###|
      ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
       ~~       V~' '->
        ~~~         /
          ~~._.   _/
             _/ _/
           _/m/'
    Last login: Sat Dec 27 11:22:04 2025 from 178.237.133.104
    [ec2-user@ip-10-0-1-143 ~]$ 
    

    Podemos ver que tenemos acceso a través de ssh (hemos tenido que añadirlo a la lista de hosts conocidos). Debes tener en cuenta que:

    • el usuario de conexión a máquinas amazon linux es ec2-user
    • el nombre DNS de conexión no coincide con el de la captura, porque estan hechos en tiempos diferentes (pero tu nombre debe ser similar)
    • el parámetro -A hace que la clave de conexión se mantenga en memoria, y la necesitaremos para saltar entre las diferentes máquinas.

    Como opción podemos cambiar los hostname de las EC2 para evitar confusiones:

    1
    2
    3
    4
    5
    [ec2-user@ip-10-0-1-143 ~]$ hostname
    ip-10-0-1-143.ec2.internal
    [ec2-user@ip-10-0-1-143 ~]$ sudo hostnamectl set-hostname presentacion
    [ec2-user@ip-10-0-1-143 ~]$ hostname
    presentacion
    
  2. Desde Presentación a Aplicación y a Base de datos:

    Necesitamos la ip privada de aplicación:

    Verificar 2

    Y también la ip privada de base de datos:

    Verificar 3

    Ahora, desde la conexión ssh que teniamos abierta con presentación, saltaremos al servidor de aplicación (10.0.10.74), y desde allí al de base de datos (10.0.20.16) (con las ip's que hemos recogido en las capturas anteriores)

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    [ec2-user@ip-10-0-1-143 ~]$ ssh ec2-user@10.0.10.74 -A
    The authenticity of host '10.0.10.74 (10.0.10.74)' can't be established.
    ED25519 key fingerprint is SHA256:h3y1V7Zkg1ipYW1jYO4nIfGm8o9GrynamPUas3LFj40.
    This key is not known by any other names
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added '10.0.10.74' (ED25519) to the list of known hosts.
       ,     #_
       ~\_  ####_        Amazon Linux 2023
      ~~  \_#####\
      ~~     \###|
      ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
       ~~       V~' '->
        ~~~         /
          ~~._.   _/
             _/ _/
           _/m/'
    [ec2-user@ip-10-0-10-74 ~]$ hostname
    ip-10-0-10-74.ec2.internal
    [ec2-user@ip-10-0-10-74 ~]$ sudo hostnamectl set-hostname aplicacion
    [ec2-user@ip-10-0-10-74 ~]$ hostname
    aplicacion
    [ec2-user@ip-10-0-10-74 ~]$ 
    

    ahora saltaremos al de base de datos:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    [ec2-user@ip-10-0-10-74 ~]$ ssh ec2-user@10.0.20.16 -A
    The authenticity of host '10.0.20.16 (10.0.20.16)' can't be established.
    ED25519 key fingerprint is SHA256:cbQ8PbpGHJSgKohQ26I1WcGv6fuDAkDuohKSp2Et2rI.
    This key is not known by any other names
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added '10.0.20.16' (ED25519) to the list of known hosts.
       ,     #_
       ~\_  ####_        Amazon Linux 2023
      ~~  \_#####\
      ~~     \###|
      ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
       ~~       V~' '->
        ~~~         /
          ~~._.   _/
             _/ _/
           _/m/'
    [ec2-user@ip-10-0-20-16 ~]$ sudo hostnamectl set-hostname basedatos
    [ec2-user@ip-10-0-20-16 ~]$ hostname
    basedatos
    [ec2-user@ip-10-0-20-16 ~]$ 
    

    Instalación de aplicaciones

    Ahora que hemos conseguido conectar con todas las máquinas de manera encadenada, y antes de deshacer el camino, aprovecharemos para ir instalando lo necesario en cada capa para realizar una simple prueba de concepto al estilo de "Hola Mundo":

    Capa de Base de Datos

    Instalamos PostgreSQL 16

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # Actualizar metadata de repositorios
    sudo dnf update -y
    sudo dnf clean all
    sudo dnf makecache
    
    # Buscar paquetes PostgreSQL disponibles
    sudo dnf search postgresql
    
    # Instalar PostgreSQL 16 directamente
    sudo dnf install -y postgresql16 postgresql16-server
    
    # Iniciando Base de Datos
    sudo postgresql-setup initdb
    
    # Activando e iniciando servicio
    sudo systemctl enable postgresql
    sudo systemctl start postgresql
    sudo systemctl status postgresql
    

    Creamos una BD de prueba:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    # Crear base de datos y usuario
    sudo -u postgres psql -c "CREATE DATABASE holamundo;"
    sudo -u postgres psql -c "CREATE USER appuser WITH PASSWORD 'Password123';"
    
    # Crear tabla simple
    sudo -u postgres psql -d holamundo -c "
    CREATE TABLE mensajes (
        id SERIAL PRIMARY KEY,
        mensaje VARCHAR(100),
        fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    INSERT INTO mensajes (mensaje) VALUES ('Hola Mundo desde la BD!');
    "
    sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE holamundo TO appuser;"
    

    Habilitamos las conexiones desde el exterior de la máquina:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    # Editar postgresql.conf
    sudo nano /var/lib/pgsql/data/postgresql.conf
    
    # Buscar y cambiar (y descomentar):
    # listen_addresses = 'localhost'  ->  listen_addresses = '*'
    
    sudo nano /var/lib/pgsql/16/data/pg_hba.conf
    
    # AÑADIR al final:
    host    all             all             10.0.0.0/16           md5
    # Esto permite toda la VPC (10.0.0.0/16)
    

    Ahora si lanzamos la prueba de acceso a la BD y escribimos la constraseña "Password123":

    1
    2
    3
    4
    5
    6
    7
    8
    [ec2-user@basedatos ~]$ psql -h 10.0.20.16 -U appuser -d holamundo -c "SELECT 1;"
    Password for user appuser: 
     ?column? 
    ----------
            1
    (1 row)
    
    [ec2-user@basedatos ~]$ 
    
    Capa de Aplicación

    Ahora nos movemos a la capa de aplicación (exit) (recuerda que puedes saber en que instancia EC2 te encuentras con el comando hostname) y aquí instalaremos Node.js y crearemos la API:

    1
    2
    3
    4
    5
    6
    7
    8
    [ec2-user@ip-10-0-20-16 postgresql-setup]$ hostname
    basedatos
    [ec2-user@ip-10-0-20-16 postgresql-setup]$ exit
    logout
    Connection to 10.0.20.16 closed.
    [ec2-user@ip-10-0-10-74 ~]$ hostname
    aplicacion
    [ec2-user@ip-10-0-10-74 ~]$ 
    

    Instalar Node.js

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    # Instalar Node.js
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
    source ~/.bashrc
    nvm install 18
    npm install -g pm2
    
    # Crear aplicación
    mkdir ~/app && cd ~/app
    npm init -y
    npm install express pg
    
    # Crear app.js
    cat > app.js << 'EOF'
    const express = require('express');
    const { Client } = require('pg');
    const app = express();
    const port = 3000;
    
    // Configuración - cambiar según tu BD
    const dbConfig = {
        host: '10.0.20.16', // Reemplazar con IP real
        port: 5432,
        database: 'holamundo',
        user: 'appuser',
        password: 'Password123'
    };
    
    app.get('/', async (req, res) => {
        try {
            const client = new Client(dbConfig);
            await client.connect();
            const result = await client.query('SELECT * FROM mensajes ORDER BY fecha DESC LIMIT 1');
            await client.end();
    
            res.json({
                mensaje: 'Hola desde la capa de aplicación!',
                datos_bd: result.rows[0],
                timestamp: new Date()
            });
        } catch (error) {
            res.status(500).json({ error: error.message });
        }
    });
    
    app.get('/health', (req, res) => {
        res.json({ status: 'ok', servicio: 'app-layer' });
    });
    
    app.listen(port, '0.0.0.0', () => {
        console.log(`App escuchando en puerto ${port}`);
    });
    EOF
    
    # Iniciar con PM2
    pm2 start app.js --name "app-layer"
    pm2 save
    pm2 startup
    

    Revisa los parámetros de conexión de tu BD

    Revisa la IP, el puerto, BD, usuario y contraseña para acceder a tu base de datos.

    Comprueba bien la salida de los comandos pm2, porque seguramente tendras que ejecutar algo similar a esto:

    1
    sudo env PATH=$PATH:/home/ec2-user/.nvm/versions/node/v18.20.8/bin /home/ec2-user/.nvm/versions/node/v18.20.8/lib/node_modules/pm2/bin/pm2 startup systemd -u ec2-user --hp /home/ec2-user
    

    Desde aquí también probaremos a acceder a la BD:

    1
    2
    3
    4
    # Desde capa de aplicación, verificar conexión a BD:
    # Para PostgreSQL:
    sudo dnf install postgresql16 -y
    psql -h 10.0.20.16 -U appuser -d holamundo -c "SELECT 1;"
    

    Y escribimos "Password123" tamibén obtenemos:

    1
    2
    3
    4
    5
    6
    7
    8
    [ec2-user@aplicacion ~]$ psql -h 10.0.20.16 -U appuser -d holamundo -c "SELECT 1;"
    Password for user appuser: 
     ?column? 
    ----------
            1
    (1 row)
    
    [ec2-user@aplicacion ~]$
    
    Capa de Aplicación

    Ahora que ya tenemos en funcionamiento la capa de aplicación, volvemos a la de presentación:

    1
    2
    3
    4
    5
    6
    7
    8
    [ec2-user@ip-10-0-10-74 app]$ hostname
    aplicacion
    [ec2-user@ip-10-0-10-74 app]$ exit
    logout
    Connection to 10.0.10.74 closed.
    [ec2-user@ip-10-0-1-143 ~]$ hostname
    presentacion
    [ec2-user@ip-10-0-1-143 ~]$ 
    

    Ahora instalaremos y configuraremos nginx:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    # 1. Instalar Nginx directamente con dnf
    sudo dnf install nginx -y
    
    # 2. Crear configuración de proxy inverso
    sudo tee /etc/nginx/conf.d/proxy.conf << 'EOF'
    server {
        listen 80;
        server_name _;
    
        location / {
            proxy_pass http://10.0.10.74:3000; # IP privada de tu capa app
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    
        location /health {
            proxy_pass http://10.0.10.74:3000/health;
        }
    }
    EOF
    
    # 3. Verificar sintaxis de Nginx
    sudo nginx -t
    
    # 4. Habilitar e iniciar Nginx
    sudo systemctl enable nginx
    sudo systemctl start nginx
    
    # 5. Verificar estado
    sudo systemctl status nginx
    
    # 6. Verificar que escucha en puerto 80
    sudo ss -tlnp | grep :80
    

    Revisa los parámetros de conexión con tu Aplicación

    Revisa la IP y el puerto de conexión con tu servidor de aplicación Node.js. Fíjate que aparece en dos lineas diferentes.

    1
    2
    # Desde capa de aplicación, verificar conexión a app:
    curl http://10.0.10.74:3000/health
    

    Deberíamos ver:

    1
    2
    3
    [ec2-user@aplicacion ~]$ curl http://10.0.10.74:3000/health
    {"status":"ok","servicio":"app-layer"}
    [ec2-user@aplicacion ~]$
    
    Capa de presentación
    1
    2
    # Desde capa de presentación, verificar conexión a app:
    curl http://10.0.10.74:3000/health
    

    Y desde presentación:

    1
    2
    3
    [ec2-user@ip-10-0-1-143 ~]$ curl http://10.0.10.74:3000/health
    {"status":"ok","servicio":"app-layer"}
    [ec2-user@ip-10-0-1-143 ~]$ 
    
    Verificaciones finales

    Vamos a comprobar que todo lo que hemos instalado y configurado funciona correctamente, para ello accederemos a la ip publica desde nuestro navegador preferido: http://ec2-100-48-98-206.compute-1.amazonaws.com/

    Y deberíamos ver algo similar a esto:

    Verificar 4