📝 Como listar la concurrencia reservada y aprovisionada de nuestras Lambdas ⚡.


La concurrencia en funciones lambdas se refiere al número de solicitudes que una función puede manejar simultáneamente. Existen dos tipos principales de control de concurrencia:
Concurrencia reservada: Establece un límite máximo de instancias simultáneas para una función específica, garantizando que otras funciones no utilicen esa capacidad. No tiene costos y no mejora el Cold start. El límite por cuenta de la concurrencia reservada es de 1000, se puede aumentar a nivel de cuenta.
Concurrencia aprovisionada: Mantiene un número fijo de entornos de ejecución pre inicializados para una función, asegurando que estén listos para manejar solicitudes sin demora. Tiene un costo 💵adicional y ayuda a mejorar el Cold Start ❄️. Son Lambdas que están siempre encendidas ⚠️.
Bien, con esto en mente supongamos un escenario donde tenemos una región con más de 70 lambdas desplegadas y por alguna razón, no tenemos control sobre como está distribuida la concurrencia entre estas lambdas.
Con este escenario podemos intentar ir a AWS cli, o crear un Script de Python (u otro lenguaje) para consultar a través del SDK (Boto3), y en ese momento nos daremos cuenta de que posiblemente nos retorne cero cuando el panel de Amazon y el costo nos está indicando que tenemos concurrencia reservada:
💡 Bien, lo que sucede es que no podemos realizar la consulta si el rol o el usuario que estamos usando para consultar no tiene permisos(🔏)para acceder a esta información de las lambdas.
Solución Alternativa y Reutilizable
Como no podría ser de otra manera para quien me ha leído antes, la solución propuesta es una Lambda 😀que haga este trabajo, desplegado con AWS Sam, y que podemos desplegar y destruir de manera rápida y en distintas regiones.
Código Fuente
https://github.com/olcortesb/list-lambda-provisioned-reserved
Repositorio con todo el codigo que se presenta en este post
Los permisos:
El primer punto es definir la infraestructura y definir los permisos correspondientes.
# https://github.com/olcortesb/list-lambda-provisioned-reserved/blob/main/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: List Lambda provisioned reserved
Resources:
ListFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: lambda.lambda_handler
Runtime: python3.10
Architectures: [arm64]
Timeout: 900
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- lambda:GetFunctionConcurrency
- lambda:ListFunctions
- lambda:ListProvisionedConcurrencyConfigs
Resource: "*"
Los permisos relacionados con Provicioned
y concurrency
son los que permiten acceder a los atributos.
El código:
El código está basado en Boto3 y lo que hacemos es consultar por todas las lambdas y revisar cuáles tienen configuraciones de concurrencia.
# https://github.com/olcortesb/list-lambda-provisioned-reserved/tree/main/src
# Base on https://repost.aws/knowledge-center/lambda-provisioned-reserved-concurrency
import os
import boto3
def lambda_handler(event, context):
...
try:
response = lambda_client.get_function_concurrency(
FunctionName=function_name
)
if 'ReservedConcurrentExecutions' in response:
count += 1
reserved_concurrency = response['ReservedConcurrentExecutions']
print(f"{count}. Function Name: {function_name}, Reserved Concurrency: {reserved_concurrency}")
except lambda_client.exceptions.ResourceNotFoundException:
pass
except Exception as e:
print(f"Error retrieving concurrency for {function_name}: {e}")
try:
response = lambda_client.list_provisioned_concurrency_configs(
FunctionName=function_name
)
if 'ProvisionedConcurrencyConfigs' in response and response['ProvisionedConcurrencyConfigs']:
provisioned_concurrency = response['ProvisionedConcurrencyConfigs'][0]['RequestedProvisionedConcurrentExecutions']
count += 1
print(f"{count}. Function Name: {function_name}, Provisioned Concurrency: {provisioned_concurrency}")
except lambda_client.exceptions.ResourceNotFoundException:
pass
except Exception as e:
print(f"Error retrieving provisioned concurrency for {function_name}: {e}")
Resultados
Ale ejecutar la función recorrerá todas las lambdas que tenemos en la región donde la hemos desplegado y validara si tienen configurada concurrencia reservada o provisionada respectivamente, dándonos un listado de las funciones y la cantidad de concurrencia. Para este ejemplo lo sacamos en un log, pero se puede obtener vía API o enviarlo a algún lugar que concentre los reportes de nuestra infraestructura
Function Logs:
START RequestId: 253fe873-d35c-44e2-8593-f6a43b9cecc3 Version: $LATEST
Total functions 75
1. Function Name: fibonacci-x86-n4, Reserved Concurrency: 5
2. Function Name: fibonacci-x86-n4, Provisioned Concurrency: 1
END RequestId: 253fe873-d35c-44e2-8593-f6a43b9cecc3
REPORT RequestId: 253fe873-d35c-44e2-8593-f6a43b9cecc3 Duration: 8857.61 ms ...
Conclusión
Probamos como poder obtener los datos de nuestra concurrencia en una región específica.
Identificamos los permisos necesarios para que la lambda pueda consultar por estos permisos
Sacamos en un log los resultados como prueba básica, pudiendo enviarlos a distintos destinos o devolviendo mediante una API de ser necesario
Referencias
Subscribe to my newsletter
Read articles from Oscar Cortes Bracho directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Oscar Cortes Bracho
Oscar Cortes Bracho
Cloud Software Engineer