AWS Cost Optimization: Automatización de Elastic IPs No Utilizadas
Serverless, Python y buenas prácticas para optimizar infraestructura cloud.

Ingeniero en Telecomunicaciones con enfoque en redes, conectividad y automatización. Actualmente estudiando AWS, DevOps y CI/CD. Comparto mi camino con proyectos prácticos y artículos técnicos desde Chile 🇨🇱.
https://robertoespana.hashnode.dev/portafolio
Hoy realizaré mi siguiente proyecto utilizando AWS Lambda con Boto3 en Python para automatizar procesos relacionados con la VPC. En este caso, el objetivo es optimizar los recursos de mi cuenta de AWS, buscando las direcciones IP elásticas (Elastic IPs) que no están siendo utilizadas y que generan un costo innecesario.
Como podemos ver en el siguiente diagrama, tenemos la función Lambda con los permisos necesarios (en este caso, permisos de EC2) para interactuar con las direcciones IP elásticas. Luego configuro un EventBridge en modo Scheduler, programado para ejecutarse todos los días y así correr mi script diariamente. Por último, el script lista todas las Elastic IPs de la cuenta y libera aquellas que no estén asociadas, devolviéndolas automáticamente a AWS. Las que sí están asociadas simplemente son ignoradas.

Código explicado
Primero obtengo el recurso EC2 usando boto3, ya que las Elastic IP pertenecen al servicio EC2:
import boto3
def lambda_handler(event, context):
ec2_resource = boto3.resource('ec2')
Luego hago un bucle sobre ec2_resource.vpc_addresses.all(), que devuelve todas las Elastic IP de la cuenta asociadas a VPC:
for elastic_ip in ec2_resource.vpc_addresses.all():
Para cada Elastic IP reviso si instance_id es None, lo que significa que no está asociada a ninguna instancia:
if elastic_ip.instance_id is None:
print(f"\nNo association for elastic IP: {elastic_ip}. Releasing...\n")
elastic_ip.release()
Si está sin asociación, imprimo un mensaje para tener observabilidad y luego libero la IP usando elastic_ip.release().
Finalmente retorno una respuesta indicando que el proceso terminó:
return {
'statusCode': 200,
'body': "Processed elastic IPs."
}
Código completo
import boto3
def lambda_handler(event, context):
ec2_resource = boto3.resource('ec2')
for elastic_ip in ec2_resource.vpc_addresses.all():
if elastic_ip.instance_id is None:
print(f"\nNo association for elastic IP: {elastic_ip}. Releasing...\n")
elastic_ip.release()
return {
'statusCode': 200,
'body': "Processed elastic IPs."
}
Configuraciones necesarias
- Asignar permisos a la función Lambda
Como esta es una demo, asignaré permisos completos (full access). Sin embargo, en un entorno de producción se recomienda aplicar el principio de mínimo privilegio.

Configurar el trigger de EventBridge en modo Scheduler (diario)
Creamos una nueva regla, asignamos un nombre, elegimos el tipo Schedule y usamos la expresión:rate(1 day)Esto hace que la función se ejecute una vez por día.

Demostración
Para esta demostración debemos tener:
Una instancia EC2.
Una Elastic IP asociada a la instancia.
Otra Elastic IP sin asociar.


Actualizamos la página y, como podemos ver, la segunda Elastic IP que no estaba asociada ya no aparece, porque fue liberada automáticamente.

Luego revisamos el Log Stream en CloudWatch. Recordemos que Lambda envía logs allí de forma automática. Podemos ver que encontró una Elastic IP sin asociación (la misma de la captura anterior) y finalmente realizó la liberación de la IP.

Con esto doy por finalizado mi sexto proyecto utilizando Boto3 , entrando a lo que ya es optimización de recursos con Lambda.
Espero que este proyecto te sea tan útil como a mí.
Saludos.



