Construyendo una aplicación web completa en los servicios de AWS

Construyendo una aplicación web en AWS

Introducción

Cuando empezamos a aprender AWS, generalmente aprendemos partes de él, como algunos de los servicios principales; trabajando en la consola de AWS, podemos crear una nueva instancia de EC2 o un bucket de S3 y subir algo a él. Pero en la mayoría de los casos, no pudimos unir todos los servicios en una aplicación real. Conocíamos diferentes servicios de AWS que hemos estado aprendiendo pero no pudimos integrarlos en algo utilizable, y si te sientes de la misma manera, has venido al lugar correcto. Después de terminar este artículo, podrás construir una aplicación de administración de contraseñas alojada en AWS, realizará sus cálculos en el servidor de AWS, los datos del usuario se enviarán al servidor backend a través de un API Gateway, el resultado final se mostrará al usuario en el navegador y también se almacenará los datos en una base de datos de AWS.

Asegúrate de tener una cuenta de AWS y acceso a la consola antes de continuar. No es necesario tener conocimientos previos de AWS para este artículo; si ya tienes una comprensión básica, eso será útil, si no lo sabes, aún deberías poder seguir el proceso mientras construimos nuestra aplicación. Este artículo no pretende ser una inmersión profunda en ninguno de los servicios de AWS, sino que pretende unirlos todos en una aplicación funcional.

Objetivos de Aprendizaje

  • Crear una aplicación web de extremo a extremo integrando diferentes servicios de AWS.
  • Aprender cómo implementar y alojar aplicaciones web utilizando AWS Amplify.
  • Aprender cómo crear un servidor backend utilizando AWS Lambda.
  • Aprender cómo utilizar API Gateway para la transferencia de datos entre los componentes frontend y backend.
  • Aprender cómo almacenar y recuperar datos de la base de datos de AWS DynamoDB.

Resumen de los Servicios y la Aplicación que Construiremos

Este artículo utiliza cinco servicios de AWS para construir aplicaciones web de extremo a extremo desde cero, como se muestra en la imagen anterior. Crearemos una aplicación de administración de contraseñas seguras que genera y almacena contraseñas seguras tomando el nombre, la longitud y las propiedades de las contraseñas (letras mayúsculas, letras minúsculas, números, caracteres especiales) como entrada. Esta es una aplicación sencilla, pero une todos los componentes principales que necesitarías para construir una aplicación del mundo real mucho más grande.

¿Qué necesitamos hacer para construir esta aplicación?

1. Debemos crear y alojar una página web en la que nuestros usuarios navegarán en sus navegadores.

2. Necesitamos una forma de invocar la funcionalidad de generación de contraseñas.

3. Necesitamos una forma de realizar el cálculo que da resultados.

4. Necesitamos una forma de almacenar el resultado y una forma de devolver el resultado al usuario.

5. Necesitamos manejar los permisos de estos servicios en AWS.

Crear y Desplegar una Página Web en Vivo utilizando AWS Amplify

En AWS, en realidad hay varias formas de hacer esto. Elegiremos AWS Amplify; con Amplify, podemos construir y alojar sitios web. Es un gran servicio, especialmente si eres un desarrollador frontend. Crearemos una página HTML y luego utilizaremos Amplify para implementar y alojar esa página web. Hagámoslo ahora. A continuación se muestra un código HTML simple que muestra el nombre de nuestro artículo cuando lo abrimos.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title> ¡Administrador de Contraseñas Seguras! </title>
</head>
<body>
    Creando una Aplicación AWS de Extremo a Extremo.
</body>
</html>

Paso 1: Guarda este código con el nombre index.html y comprime este archivo. Ahora vamos a implementarlo en AWS Amplify. Ve a la consola de administración de AWS y busca AWS Amplify.

Paso 2: Queremos alojar la aplicación web aquí, así que selecciona Amplify Hosting.

Paso 3: No tenemos un proveedor de Git, así que selecciona “Implementar sin proveedor de Git” y continúa.

Paso 4: Dale un nombre de tu elección a la aplicación. Yo le voy a poner “PasswordGeneratorFrontend”. Dale un nombre al entorno. Selecciona “arrastrar y soltar” y toma el archivo zip que creamos antes, y haz clic en guardar y desplegar.

Ahora verás que el despliegue es exitoso y obtendrás el enlace a la página web alojada. También puedes acceder a este enlace en cualquier momento yendo a la gestión de dominios en la barra lateral.

Tenemos una página web en vivo a la que los usuarios pueden acceder en nuestra aplicación.

Configuración de un servicio AWS Lambda para realizar la computación en nuestra aplicación

Como podrás saber, una función lambda es solo un fragmento de código que se ejecuta en respuesta a algún desencadenante, por ejemplo, cuando subes una imagen a un bucket S3, eso podría desencadenar una función lambda para procesar la imagen y crear una miniatura o algo por el estilo. Es solo código o funciones que están allí en AWS y se ejecutan cuando los necesitas. Estos son sin servidor, lo que significa que no tienes que configurar ni administrar servidores para ejecutar el código; simplemente sucede automáticamente sin que tú lo veas. Entonces, escribiremos un código Python y haremos los cálculos que necesitamos.

Paso 1: Ve a la consola de AWS y navega hasta Lambda.

Paso 2: Crea una nueva función y selecciona “crear desde cero”, que debería ser tu opción predeterminada, y luego da un nombre a la función. Luego selecciona el entorno de ejecución, vamos a usar la versión más reciente disponible de Python. Puedes dejar todo lo demás igual y hacer clic en crear función.

Paso 3: Ahora desplázate hacia abajo en la consola y verás un editor para escribir código. Colocaremos nuestro código Python en ese editor. A continuación se muestra nuestro código Python:

import json
import random
import string

def lambda_handler(event, context):
    # Extraer los parámetros de entrada del objeto event
    name = event['name']
    length = int(event['length'])
    req_capital_letters = int(event['reqCapitalLetters'])
    req_small_letters = int(event['reqSmallLetters'])
    req_numbers = int(event['reqNumbers'])
    req_special_chars =int(event['reqSpecialChars'])
    # Generar la contraseña
    password_chars = []
    allowed="" # caracteres permitidos
    # Incluir un carácter de cada conjunto de caracteres seleccionado
    if req_capital_letters:
        password_chars.append(random.choice(string.ascii_uppercase ))
        allowed=allowed+string.ascii_uppercase
    if req_small_letters:
        password_chars.append(random.choice(string.ascii_lowercase))
        allowed=allowed+string.ascii_lowercase
    if req_numbers:
        password_chars.append(random.choice(string.digits))
        allowed=allowed+string.digits
    if req_special_chars:
        password_chars.append(random.choice(string.punctuation))
        allowed=allowed+string.punctuation
    # Calcular la longitud restante para los caracteres aleatorios
    remaining_length = length - len(password_chars)
    # Generar caracteres aleatorios para la longitud restante
    password_chars.extend(random.choice(allowed) for _ in range(remaining_length))
    # Mezclar los caracteres para eliminar el sesgo de orden
    random.shuffle(password_chars)
    # Concatenar los caracteres para formar la contraseña
    password = ''.join(password_chars)
    # Devolver la contraseña en una respuesta JSON
    return {
        'statusCode': 200,
        'body': json.dumps('Tu contraseña para '+name+' es: ' + password)
    }

El código es bastante simple de entender. Solo estamos importando las bibliotecas de utilidad JSON y las bibliotecas de cadenas aleatorias de Python para generar caracteres aleatorios, luego tenemos nuestro controlador lambda; esto es común a todas las funciones lambda, y aquí es donde hacemos la mayor parte del trabajo. Como recordarás, nuestro usuario va a pasar el nombre, la longitud y las propiedades de la contraseña (mayúsculas, minúsculas, números, caracteres especiales) como entrada. Estamos obteniendo esos valores del objeto de evento y almacenándolos en variables respectivas. Luego incluimos un carácter de cada conjunto seleccionado por el usuario. Luego calculamos la longitud restante para la contraseña y, en función de esa longitud, generamos caracteres aleatorios para la longitud restante a partir de los conjuntos seleccionados por el usuario. Finalmente, devolvemos el resultado como un objeto JSON.

Asegúrate de guardar este código (puedes simplemente hacer CTRL + S) y, muy importante, también debes implementarlo haciendo clic en el botón de implementación justo ahí.

Paso 4: Ahora, probemos nuestra función lambda para asegurarnos de que esta función esté funcionando correctamente. Haz clic en la pequeña flecha desplegable cerca del botón de prueba y haz clic en “Configurar evento de prueba”.

Paso 5: Configuremos un evento de prueba; nos permite pasar algunos datos de prueba para asegurarnos de que la función esté funcionando correctamente. Crea un nuevo evento y dale un nombre al evento. En el JSON de evento, pasaremos algunas propiedades de contraseñas aleatorias. En mi caso, he dado una longitud de contraseña de 10 y seleccionado todos los conjuntos de caracteres (1-seleccionado, 0-no seleccionado). Desplázate hacia abajo y luego haz clic en guardar.

Paso 6: Hemos configurado correctamente el evento de prueba; ahora, debemos ejecutar la prueba, lo cual podemos hacer haciendo clic en el botón de prueba. Como puedes ver, obtuvimos un código de estado 200 y el resultado contiene al menos un carácter de todos los conjuntos. Por lo tanto, nuestra función lambda está funcionando correctamente.

Hasta ahora, tenemos una página html simple alojada utilizando Amplify y una función lambda para implementar la funcionalidad de nuestra aplicación.

Creando una API para invocar la funcionalidad del generador de contraseñas

A continuación, necesitamos una forma de invocar nuestra funcionalidad de generador de contraseñas o básicamente invocar esa función lambda. Obviamente, nuestros usuarios no van a entrar en la consola de AWS como acabamos de hacer y ejecutarlo, por lo que necesitamos un punto final o URL público que se pueda llamar para activar la función lambda y ejecutarla, y para eso, vamos a utilizar el servicio de API Gateway, este es un servicio principal en AWS que podemos usar para construir nuestras propias API (interfaces de programación de aplicaciones), ya sean API http, REST o WebSocket, es realmente la forma perfecta de invocar una función lambda. Creemos una API REST para nuestra función lambda utilizando API Gateway.

Paso 1: Ve a la Consola de AWS y busca API Gateway.

Paso 2: Crea una nueva API haciendo clic en el botón de crear API. Ahora ve a la sección de API REST y haz clic en el botón de construir.

Paso 3: Ahora selecciona REST y selecciona Nueva API, luego necesitamos darle un nombre. En mi caso, le doy “CallPasswordGenerator”. Puedes dejar todo lo demás igual y hacer clic en “Crear API”.

Paso 4: Actualmente tenemos una API vacía, no está integrada con ninguna función lambda. Hagamos eso ahora. En la barra lateral, asegúrate de tener seleccionados los recursos, y luego selecciona la barra diagonal invertida, y luego en el menú de acciones, selecciona crear método. El tipo de método será post, ya que el usuario enviará datos a AWS y luego hace clic en la pequeña marca de verificación junto a POST.

Paso 5: Para el tipo de integración, vamos a usar una función lambda, y le damos un nombre a nuestra función lambda y luego hacemos clic en guardar.

Paso 6: Ahora, una cosa importante es que necesitamos habilitar CORS o uso compartido de recursos de origen cruzado. Así que ve al menú de acciones y selecciona “Habilitar CORS”. Esto permite que una aplicación web que se ejecuta en un origen o dominio acceda a recursos en un origen o dominio diferente porque nuestra aplicación web se ejecuta en un dominio en Amplify. Nuestra función lambda se ejecutará en otro dominio, por lo que necesitamos poder trabajar entre esos dominios u orígenes, por eso estamos haciendo esto.

Solo deja todos los valores por defecto y haz clic en el botón Habilitar CORS a continuación.

Paso 7: Vamos a implementar la API para poder probarla. Ve al menú de acciones y selecciona Implementar API. Necesitaremos configurar una nueva etapa aquí porque es posible que tengas diferentes etapas para desarrollo, pruebas y producción. Haz clic en ‘Implementar’.

Paso 8: Copia la URL de invocación que apareció en tu pantalla porque la necesitaremos más adelante, así que abre un bloc de notas o donde quieras guardar esto. Actuará como nuestra URL de la puerta de enlace de la API.

Paso 9: Vamos a validar esta API. Ve a los recursos en la barra lateral y selecciona POST. Haz clic en la opción Prueba. Esto nos permitirá enviar los datos de prueba que queremos y mostrar la respuesta correspondiente.

Paso 10: Utilizamos el mismo formato para probar la función lambda. Pasa las propiedades de contraseña requeridas en formato JSON y haz clic en el botón de prueba. Podemos ver que nuestra API funcionó correctamente y recibimos la respuesta, que contiene nuestra contraseña y el código de estado de éxito.

Almacenar los datos en una base de datos

En realidad, no tenemos que almacenar los resultados en ninguna parte, podríamos devolvérselos al usuario, pero la mayoría de las aplicaciones del mundo real tienen bases de datos. Así que tenemos que configurar una base de datos, y también necesitamos manejar los permisos entre las diferentes partes de la aplicación, específicamente, necesitamos darle permiso a nuestra función lambda para escribir en la base de datos. Comenzando con la base de datos, vamos a usar DynamoDB, una base de datos clave-valor o NoSQL que generalmente será más liviana que algo como una base de datos relacional, donde tienes que configurar tu esquema y relaciones de antemano.

Paso 1: Ve a la consola, busca DynamoDB y haz clic en Crear una tabla.

Paso 2: Dale un nombre a la tabla; para la clave de partición, pongamos el nombre como ‘ID’. Puedes dejar todo lo demás igual y crear una tabla.

Paso 3: Ahora necesitamos guardar el nombre de recurso de Amazon o ARN; para esto, haz clic en el nombre de la tabla y, bajo la información general, en información adicional, puedes encontrar el ARN. Guarda este ARN. Volveremos y lo obtendremos más adelante.

Paso 4: Para dar permiso de escritura a la función lambda, ve al servicio de lambda y ve a la pestaña de configuración, luego debes hacer clic en el nombre del rol en el rol de ejecución. Esto debería abrirse en una nueva pestaña.

Paso 5: Básicamente, necesitamos agregar algunos permisos a lo que ya tiene este rol. Para hacer eso, haz clic en agregar permisos y crear una política inline.

Paso 6: Trabajar con el código JSON es más fácil, así que haz clic en la pestaña JSON allí. Coloca este código en esa pestaña.

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
            "dynamodb:PutItem",
            "dynamodb:DeleteItem",
            "dynamodb:GetItem",
            "dynamodb:Scan",
            "dynamodb:Query",
            "dynamodb:UpdateItem"
        ],
        "Resource": "TU-ARN-DE-TABLA"
    }
    ]
}

Permite todas estas acciones especificadas en JSON para que la función lambda tenga permiso para hacer todas estas cosas en nuestra tabla DynamoDB. Aún así, es muy importante que actualices el ARN de la tabla que copiaste y hagas clic en Revisar Política.

Paso 7: Ahora, ponle nombre a esta política y, finalmente, crea una política.

Paso 8: Necesitamos actualizar el código Python de la función lambda para interactuar con la base de datos. Nuestro código anterior no tiene esta funcionalidad.

import json
import random
import string
# importa el SDK de AWS (para Python, el nombre del paquete es boto3)
import boto3
# crea un objeto DynamoDB usando el SDK de AWS
dynamodb = boto3.resource('dynamodb')
# usa el objeto DynamoDB para seleccionar nuestra tabla
table = dynamodb.Table('PasswordDatabase')
def lambda_handler(event, context):
    # Extrae los parámetros de entrada del objeto evento
    name = event['name']
    length = int(event['length'])
    req_capital_letters = int(event['reqCapitalLetters'])
    req_small_letters = int(event['reqSmallLetters'])
    req_numbers = int(event['reqNumbers'])
    req_special_chars =int(event['reqSpecialChars'])
    # Genera la contraseña
    password_chars = []
    allowed="" # caracteres permitidos
    # Incluye un carácter de cada conjunto de caracteres seleccionado
    if req_capital_letters:
        password_chars.append(random.choice(string.ascii_uppercase ))
        allowed=allowed+string.ascii_uppercase
    if req_small_letters:
        password_chars.append(random.choice(string.ascii_lowercase))
        allowed=allowed+string.ascii_lowercase
    if req_numbers:
        password_chars.append(random.choice(string.digits))
        allowed=allowed+string.digits
    if req_special_chars:
        password_chars.append(random.choice(string.punctuation))
        allowed=allowed+string.punctuation
    # Calcula la longitud restante para los caracteres aleatorios
    remaining_length = length - len(password_chars)
    # Genera caracteres aleatorios para la longitud restante
    password_chars.extend(random.choice(allowed) for _ in range(remaining_length))
    # Mezcla los caracteres para eliminar el sesgo de orden
    random.shuffle(password_chars)
    # Concatena los caracteres para formar la contraseña
    password = ''.join(password_chars)
    
    # escribe el resultado en la tabla DynamoDB usando el objeto que instanciamos
    response = table.put_item(
        Item={
            'ID': name,
            'Password':password
            })

    # Devuelve la contraseña en una respuesta JSON
    return {
        'statusCode': 200,
        'body': json.dumps('Tu contraseña para '+name+' es: ' + password)
    }

Lo que es nuevo aquí en este código es que hemos importado un módulo para el SDK (kit de desarrollo de software) de AWS llamado boto3, y luego obtenemos nuestro objeto de recurso boto3 para DynamoDB. A continuación, usamos este objeto para conectar nuestra tabla de DynamoDB pasando el nombre de la tabla; el resto es igual que antes. Finalmente, el código inserta el nombre de la contraseña y la contraseña generada en la tabla utilizando la función table.put_item().

Paso 9: Asegúrese de guardar este código con un CTRL+S y, muy importante, asegúrese de implementar este código y luego probémoslo presionando el botón de prueba. Podemos ver que nuestro código funciona bien y da el resultado correcto.

Paso 10: Verifiquemos si estos resultados se actualizan en la tabla de DynamoDB yendo a explorar los elementos de la tabla, esto nos mostrará lo que se ha almacenado.

Podemos ver que ahora tenemos un nuevo resultado en la tabla, este resultado acaba de llegar a través de la ejecución de la prueba para la función lambda.

Conectando el Frontend con el Backend

Hasta ahora, podemos escribir cosas en la tabla de DynamoDB y tenemos los permisos adecuados en la función lambda, pero es posible que hayas notado que falta una conexión entre Amplify y la API gateway. Actualmente, desde nuestra página index.html, no hay forma de activar nuestra función lambda. Así que trabajemos en esta última pieza.

Necesitamos actualizar la página index.html para llamar a la API gateway. Aquí está el enlace al código final de index.html.

Explicación del código: Inicialmente, en la sección de estilo, hicimos un poco de estilo para mejorar la apariencia de las etiquetas h1, los inputs y los forms en nuestra página web. Puedes modificar y actualizar el CSS según tus preferencias. Tenemos una etiqueta h1, “Generador de contraseñas”, en la sección body. Esto será el encabezado de nuestra página web. A continuación, tenemos un formulario donde el usuario ingresará el nombre y las propiedades de la contraseña utilizando checkboxes, y tenemos un botón para enviar el formulario, que invoca la función “call API”, definida en la etiqueta script. Estamos pasando el nombre y la longitud de la contraseña como parámetros a esta función. En esta función, inicializamos los valores de las propiedades como 0 o 1 según la entrada del usuario en el formulario.

Estamos creando un objeto JSON con estos valores y llamando al endpoint pasando este objeto en el cuerpo de la solicitud. Finalmente, mostramos una alerta en el navegador que muestra la respuesta de la API gateway.

Ahora tenemos que volver a implementar nuestra página index.html usando Amplify. Haz un archivo zip de nuevo con este archivo. Abre Amplify y arrastra y suelta el archivo zip. Debería implementarse en unos segundos y obtendremos el enlace a la aplicación alojada.

Solo abre el enlace. Podemos ver que nuestra aplicación se implementó correctamente.

Aquí vamos; el resultado se ha actualizado correctamente en nuestra base de datos DynamoDB.

Eliminar tus recursos

Si has seguido los pasos, vamos a eliminar todo lo que hemos creado en este artículo. Todo debería estar en el nivel gratuito, por si acaso no quieres recibir ninguna factura sorpresa al final del mes.

Paso 1: Ve a tu recurso de Amplify, ve a acciones en la esquina superior derecha y haz clic en eliminar aplicación. Necesitarás confirmar la operación antes de la eliminación.

Paso 2: A continuación, ve a DynamoDB y haz clic en tablas. Selecciona la tabla y haz clic en eliminar. También se requiere confirmación antes de la eliminación.

Paso 3: A continuación, puedes eliminar tu función lambda. Navega hasta AWS Lambda, selecciona funciones en la barra lateral y luego selecciona el nombre de tu función. Luego ve al menú desplegable de acciones y haz clic en eliminar.

Paso 4: Por último, API gateway. Selecciona el nombre de la API y, en acciones, haz clic en eliminar.

Conclusión

En este artículo, hemos implementado una aplicación web de principio a fin utilizando varios servicios de AWS. En esta aplicación, los usuarios pueden ingresar su nombre de contraseña y propiedades en una página web alojada y desplegada utilizando AWS Amplify. Cuando el usuario envía los detalles de la contraseña, el script en la página web llama a API gateway pasando los datos del usuario en el cuerpo de la solicitud, lo que activa la función lambda de AWS, que realiza el cálculo y crea la contraseña basada en la entrada del usuario. El resultado se escribe en la base de datos DynamoDB de AWS y luego recibimos un mensaje en el navegador a través de API gateway. Hemos visto todo el proceso de creación de una API gateway, creación de la función Lambda, configuración de la base de datos y asignación de permisos de usuario para que la función Lambda escriba en la base de datos. Si bien el ejemplo es relativamente simple, cubre componentes esenciales requeridos para aplicaciones del mundo real más complejas.

Puntos clave

  1. AWS Amplify nos ayuda a crear y alojar páginas web fácilmente, lo que lo hace ideal para desarrolladores front-end.
  2. AWS Lambda actúa como un servicio backend sin servidor que invoca nuestro código en respuesta a disparadores sin necesidad de gestionar servidores.
  3. API Gateway ayuda a conectar varios servicios en una aplicación web proporcionando un punto de conexión.
  4. DynamoDB puede almacenar los resultados generados por la función Lambda en formato JSON utilizando las SDK adecuadas.
  5. Configurar permisos y configurar las políticas necesarias para los servicios de AWS es crucial para garantizar el correcto funcionamiento de la aplicación.

Preguntas frecuentes

Los medios mostrados en este artículo no son propiedad de Analytics Vidhya y se utilizan a discreción del autor.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

Esta investigación de IA presenta métodos innovadores para adaptar modelos de lenguaje a la diseño de chips

ChipNeMo explora la utilización de LLMs para el diseño de chips industriales, empleando técnicas de adaptación de dom...

Inteligencia Artificial

Deci presenta DeciCoder un modelo de lenguaje grande de código abierto con 1 billón de parámetros para generación de código.

En el mundo acelerado de la IA, la generación eficiente de código es un desafío que no se puede pasar por alto. Con l...

Inteligencia Artificial

Este boletín de inteligencia artificial es todo lo que necesitas #57

En el mundo de la IA esta semana, las evaluaciones de rendimiento del modelo LLM fueron un tema de enfoque. En partic...

Inteligencia Artificial

Estas nuevas herramientas podrían ayudar a proteger nuestras imágenes de la IA

Sin embargo, estas herramientas no son perfectas ni suficientes por sí solas.

Inteligencia Artificial

Generación mejorada por recuperación (RAG) De la teoría a la implementación de LangChain

Ejemplo de implementación de Generación con Recuperación Aumentada (RAG) en Python con LangChain, OpenAI y Weaviate

Aprendizaje Automático

El Programa MIT-Takeda entra en su cuarto año con una cosecha de 10 nuevos proyectos.

El programa aprovecha la experiencia en investigación del MIT y el conocimiento industrial de Takeda para investigar ...