En este proyecto, aprenderás a utilizar Terraform para desplegar una aplicación serverless. Las aplicaciones serverless permiten a los desarrolladores centrarse en el código sin preocuparse por la infraestructura subyacente. Utilizaremos AWS Lambda, API Gateway y DynamoDB para construir una aplicación simple.

Objetivos del Proyecto

  1. Configurar AWS Lambda: Crear una función Lambda que se ejecute en respuesta a eventos.
  2. Configurar API Gateway: Crear una API RESTful que invoque la función Lambda.
  3. Configurar DynamoDB: Crear una tabla DynamoDB para almacenar datos.
  4. Integrar los Componentes: Conectar Lambda, API Gateway y DynamoDB para crear una aplicación funcional.

Requisitos Previos

  • Cuenta de AWS.
  • Conocimientos básicos de Terraform.
  • Conocimientos básicos de AWS Lambda, API Gateway y DynamoDB.

Paso 1: Configuración Inicial

1.1. Estructura del Proyecto

Crea una estructura de directorios para organizar los archivos de Terraform:

project-serverless/
├── main.tf
├── variables.tf
├── outputs.tf
└── lambda/
    └── function.zip

1.2. Archivo variables.tf

Define las variables necesarias para el proyecto:

variable "region" {
  description = "AWS region"
  default     = "us-west-2"
}

variable "lambda_function_name" {
  description = "Name of the Lambda function"
  default     = "MyServerlessFunction"
}

variable "dynamodb_table_name" {
  description = "Name of the DynamoDB table"
  default     = "MyServerlessTable"
}

1.3. Archivo outputs.tf

Define las salidas para obtener información útil después del despliegue:

output "api_gateway_url" {
  description = "URL of the API Gateway"
  value       = aws_api_gateway_deployment.my_api.invoke_url
}

Paso 2: Configurar AWS Lambda

2.1. Código de la Función Lambda

Crea un archivo index.js en el directorio lambda/ con el siguiente contenido:

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

2.2. Empaquetar la Función Lambda

Empaqueta el código en un archivo ZIP:

cd lambda
zip function.zip index.js
cd ..

2.3. Definir el Recurso Lambda en main.tf

Añade el siguiente bloque de código en main.tf para crear la función Lambda:

provider "aws" {
  region = var.region
}

resource "aws_lambda_function" "my_lambda" {
  function_name = var.lambda_function_name
  handler       = "index.handler"
  runtime       = "nodejs14.x"
  role          = aws_iam_role.lambda_exec.arn
  filename      = "lambda/function.zip"
  source_code_hash = filebase64sha256("lambda/function.zip")
}

resource "aws_iam_role" "lambda_exec" {
  name = "lambda_exec_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "lambda_policy" {
  role       = aws_iam_role.lambda_exec.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

Paso 3: Configurar API Gateway

3.1. Definir el Recurso API Gateway en main.tf

Añade el siguiente bloque de código en main.tf para crear la API Gateway:

resource "aws_api_gateway_rest_api" "my_api" {
  name        = "MyServerlessAPI"
  description = "API Gateway for serverless application"
}

resource "aws_api_gateway_resource" "my_resource" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  parent_id   = aws_api_gateway_rest_api.my_api.root_resource_id
  path_part   = "myresource"
}

resource "aws_api_gateway_method" "my_method" {
  rest_api_id   = aws_api_gateway_rest_api.my_api.id
  resource_id   = aws_api_gateway_resource.my_resource.id
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "my_integration" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  resource_id = aws_api_gateway_resource.my_resource.id
  http_method = aws_api_gateway_method.my_method.http_method
  type        = "AWS_PROXY"
  integration_http_method = "POST"
  uri         = aws_lambda_function.my_lambda.invoke_arn
}

resource "aws_lambda_permission" "api_gateway" {
  statement_id  = "AllowAPIGatewayInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.my_lambda.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "${aws_api_gateway_rest_api.my_api.execution_arn}/*/*"
}

resource "aws_api_gateway_deployment" "my_api" {
  depends_on = [aws_api_gateway_integration.my_integration]
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  stage_name  = "prod"
}

Paso 4: Configurar DynamoDB

4.1. Definir el Recurso DynamoDB en main.tf

Añade el siguiente bloque de código en main.tf para crear la tabla DynamoDB:

resource "aws_dynamodb_table" "my_table" {
  name           = var.dynamodb_table_name
  billing_mode   = "PAY_PER_REQUEST"
  hash_key       = "id"

  attribute {
    name = "id"
    type = "S"
  }
}

Paso 5: Integrar los Componentes

5.1. Actualizar la Función Lambda para Interactuar con DynamoDB

Actualiza el archivo index.js para interactuar con DynamoDB:

const AWS = require('aws-sdk');
const dynamo = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
    const params = {
        TableName: process.env.TABLE_NAME,
        Item: {
            id: '1',
            message: 'Hello from DynamoDB!'
        }
    };

    await dynamo.put(params).promise();

    const response = {
        statusCode: 200,
        body: JSON.stringify('Data saved to DynamoDB!'),
    };
    return response;
};

5.2. Actualizar la Configuración de Lambda en main.tf

Añade una variable de entorno para la tabla DynamoDB:

resource "aws_lambda_function" "my_lambda" {
  function_name = var.lambda_function_name
  handler       = "index.handler"
  runtime       = "nodejs14.x"
  role          = aws_iam_role.lambda_exec.arn
  filename      = "lambda/function.zip"
  source_code_hash = filebase64sha256("lambda/function.zip")

  environment {
    variables = {
      TABLE_NAME = aws_dynamodb_table.my_table.name
    }
  }
}

Paso 6: Desplegar la Aplicación

6.1. Inicializar y Aplicar Terraform

Inicializa y aplica la configuración de Terraform:

terraform init
terraform apply

Conclusión

En este proyecto, has aprendido a utilizar Terraform para desplegar una aplicación serverless en AWS utilizando Lambda, API Gateway y DynamoDB. Has configurado cada componente y los has integrado para crear una aplicación funcional. Este conocimiento te permitirá construir aplicaciones más complejas y escalables en el futuro.

Resumen de Conceptos Aprendidos

  • AWS Lambda: Crear y configurar funciones Lambda.
  • API Gateway: Crear y configurar API RESTful.
  • DynamoDB: Crear y configurar tablas DynamoDB.
  • Integración: Conectar Lambda, API Gateway y DynamoDB.

Próximos Pasos

  • Experimenta con diferentes eventos que pueden desencadenar la función Lambda.
  • Añade más endpoints a la API Gateway.
  • Implementa operaciones CRUD completas en DynamoDB.

¡Felicidades por completar el proyecto!

© Copyright 2024. Todos los derechos reservados