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
