Introducció
En aquest projecte, aprendrem a utilitzar Terraform per desplegar una aplicació sense servidor (serverless) utilitzant AWS Lambda i altres serveis relacionats. Les aplicacions sense servidor permeten executar codi sense gestionar servidors, la qual cosa simplifica la infraestructura i redueix els costos operatius.
Objectius del Projecte
- Crear una funció Lambda amb Terraform.
- Configurar un API Gateway per invocar la funció Lambda.
- Emmagatzemar dades en DynamoDB.
- Gestionar permisos amb IAM.
Requisits Previs
- Coneixements bàsics de Terraform.
- Compte d'AWS amb permisos suficients per crear recursos.
- Instal·lació de Terraform i AWS CLI.
Passos del Projecte
- Configuració Inicial
1.1. Crear el Directori del Projecte
1.2. Fitxer main.tf
Crea un fitxer main.tf
per definir els recursos de Terraform.
provider "aws" { region = "us-west-2" } resource "aws_iam_role" "lambda_role" { name = "lambda_basic_execution" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Sid = "" Principal = { Service = "lambda.amazonaws.com" } }, ] }) } resource "aws_iam_role_policy_attachment" "lambda_policy" { role = aws_iam_role.lambda_role.name policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" }
- Crear la Funció Lambda
2.1. Codi de la Funció Lambda
Crea un fitxer lambda_function.py
amb el següent codi:
2.2. Definir la Funció Lambda a Terraform
Afegim la definició de la funció Lambda al fitxer main.tf
.
resource "aws_lambda_function" "hello_world" { filename = "lambda_function.zip" function_name = "HelloWorldFunction" role = aws_iam_role.lambda_role.arn handler = "lambda_function.lambda_handler" runtime = "python3.8" source_code_hash = filebase64sha256("lambda_function.zip") }
2.3. Crear el Fitxer ZIP
- Configurar API Gateway
3.1. Definir l'API Gateway
Afegim la configuració de l'API Gateway al fitxer main.tf
.
resource "aws_api_gateway_rest_api" "api" { name = "ServerlessAPI" description = "API per a la funció Lambda" } resource "aws_api_gateway_resource" "resource" { rest_api_id = aws_api_gateway_rest_api.api.id parent_id = aws_api_gateway_rest_api.api.root_resource_id path_part = "hello" } resource "aws_api_gateway_method" "method" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.resource.id http_method = "GET" authorization = "NONE" } resource "aws_api_gateway_integration" "integration" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.resource.id http_method = aws_api_gateway_method.method.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.hello_world.invoke_arn } resource "aws_lambda_permission" "apigw" { statement_id = "AllowAPIGatewayInvoke" action = "lambda:InvokeFunction" function_name = aws_lambda_function.hello_world.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.api.execution_arn}/*/*" }
- Emmagatzemar Dades en DynamoDB
4.1. Crear la Taula DynamoDB
Afegim la configuració de DynamoDB al fitxer main.tf
.
resource "aws_dynamodb_table" "table" { name = "ServerlessTable" billing_mode = "PAY_PER_REQUEST" hash_key = "ID" attribute { name = "ID" type = "S" } }
4.2. Actualitzar la Funció Lambda per Interactuar amb DynamoDB
Actualitzem el codi de la funció Lambda per emmagatzemar dades a DynamoDB.
import boto3 import json dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('ServerlessTable') def lambda_handler(event, context): table.put_item( Item={ 'ID': '1', 'Message': 'Hello from Lambda!' } ) return { 'statusCode': 200, 'body': json.dumps('Data inserted into DynamoDB') }
- Gestionar Permisos amb IAM
5.1. Afegir Permisos a la Funció Lambda
Actualitzem el fitxer main.tf
per afegir permisos a la funció Lambda.
resource "aws_iam_role_policy" "lambda_dynamodb_policy" { name = "lambda_dynamodb_policy" role = aws_iam_role.lambda_role.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = [ "dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:Scan", "dynamodb:Query" ] Effect = "Allow" Resource = aws_dynamodb_table.table.arn }, ] }) }
- Desplegar la Infraestructura
6.1. Inicialitzar Terraform
6.2. Aplicar la Configuració
Conclusió
En aquest projecte, hem après a desplegar una aplicació sense servidor utilitzant AWS Lambda, API Gateway i DynamoDB amb Terraform. Hem cobert la creació de funcions Lambda, la configuració d'API Gateway per invocar aquestes funcions, l'emmagatzematge de dades en DynamoDB i la gestió de permisos amb IAM. Aquest projecte proporciona una base sòlida per desenvolupar aplicacions sense servidor més complexes.
Exercicis Pràctics
- Afegir una nova funció Lambda que llegeixi dades de DynamoDB i les retorni a través de l'API Gateway.
- Configurar un endpoint POST a l'API Gateway per inserir dades a DynamoDB des d'una petició HTTP.
- Implementar una política de seguretat que restringeixi l'accés a l'API Gateway a usuaris autenticats.
Solucions als Exercicis
Exercici 1: Afegir una nova funció Lambda
import boto3 import json dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('ServerlessTable') def lambda_handler(event, context): response = table.get_item( Key={ 'ID': '1' } ) item = response.get('Item', {}) return { 'statusCode': 200, 'body': json.dumps(item) }
Exercici 2: Configurar un endpoint POST
resource "aws_api_gateway_method" "post_method" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.resource.id http_method = "POST" authorization = "NONE" } resource "aws_api_gateway_integration" "post_integration" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.resource.id http_method = aws_api_gateway_method.post_method.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.hello_world.invoke_arn }
Exercici 3: Implementar una política de seguretat
resource "aws_api_gateway_authorizer" "authorizer" { name = "CognitoAuthorizer" rest_api_id = aws_api_gateway_rest_api.api.id identity_source = "method.request.header.Authorization" provider_arns = ["arn:aws:cognito-idp:us-west-2:123456789012:userpool/us-west-2_abcdefgh"] type = "COGNITO_USER_POOLS" } resource "aws_api_gateway_method" "secure_method" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.resource.id http_method = "GET" authorization = "COGNITO_USER_POOLS" authorizer_id = aws_api_gateway_authorizer.authorizer.id }
Amb aquests exercicis, hauràs reforçat els conceptes apresos i estaràs preparat per desenvolupar aplicacions sense servidor més avançades.
Curs de Terraform
Mòdul 1: Introducció a Terraform
- Què és Terraform?
- Instal·lant Terraform
- Conceptes bàsics de Terraform
- Primera configuració de Terraform
Mòdul 2: Llenguatge de configuració de Terraform
Mòdul 3: Gestió de l'estat
Mòdul 4: Mòduls de Terraform
Mòdul 5: Proveïment de recursos
- Conceptes bàsics de proveïment
- Proveïment de recursos AWS
- Proveïment de recursos Azure
- Proveïment de recursos GCP
Mòdul 6: Funcionalitats avançades de Terraform
Mòdul 7: Millors pràctiques de Terraform
- Organització del codi
- Control de versions
- Proves del codi de Terraform
- Millors pràctiques de seguretat
Mòdul 8: Terraform en CI/CD
- Integració de Terraform amb CI/CD
- Automatització de Terraform amb Jenkins
- Ús de Terraform amb GitHub Actions
- Terraform Cloud i Enterprise