AWS Too many versions present?
More Info:
Are there too many versions for any Lambda function?
Risk Level
Low
Address
Compliance Standards
Triage and Remediation
- Remediation
Remediation
Using Console
To reduce “too many versions” for an AWS Lambda function using the AWS Console, you essentially need to (1) decide which versions to keep, (2) update aliases, and (3) delete old versions.
Below are the step‑by‑step instructions.
1. Identify which versions can be deleted
- Sign in to the AWS Management Console.
- Go to Lambda:
Services → Lambda. - In the left pane, click Functions, then select your Lambda function.
- In the function view, select the Versions tab.
- You will see:
$LATESTand numbered versions (e.g., 1, 2, 3…).
- You will see:
Decide which versions to keep:
- Keep any versions currently used by:
- Aliases (e.g.,
prod,staging,beta) - Event source mappings / triggers tied to a specific version
- Aliases (e.g.,
- Keep a small number of recent versions for rollback (e.g., last 3–5).
2. Check and update aliases (so deletes are safe)
- In the same function, go to the Aliases tab.
- For each alias (e.g.,
prod,dev):- Confirm which version it is pointing to.
- If an alias points to a version you plan to delete:
- Click the alias name.
- Click Edit.
- Change Version to a version you intend to keep (e.g., the latest stable).
- Click Save.
Do not delete any version still in use by an alias or a direct trigger.
3. Delete old Lambda versions
- Back in the Versions tab:
- For each old version you want to delete:
- Click the radio button for that version (you must first click into that version’s detail page if there is no direct delete button in the list).
- In the top‑right, choose Actions → Delete (or Delete version from the version details page).
- Confirm the deletion.
Repeat for all old, unused versions.
Note: $LATEST cannot be deleted.
4. (Optional) Set a version cleanup policy using automation
The console has no built‑in “auto‑prune” for versions. To avoid this problem returning:
- Adopt a policy like “keep only last N versions” and:
- Use a scheduled Lambda (invoked by EventBridge) that uses the AWS SDK to:
- List versions of a function
- Exclude those used by aliases
- Delete older ones beyond N
- Use a scheduled Lambda (invoked by EventBridge) that uses the AWS SDK to:
- Or enforce version limits via your CI/CD process (delete older versions after each deployment).
Summary
- Use Versions tab to list and delete old, unused versions.
- Update Aliases first so they don’t reference versions you’ll delete.
- Keep only a small set of recent, active versions going forward and automate cleanup if possible.
Using CLI
For AWS Lambda, “Too many versions present” means you’re hitting/approaching the 75-version-per-function limit. You fix it by deleting old, unused versions.
Below are step‑by‑step AWS CLI steps.
1. Identify functions with many versions
aws lambda list-functions --query 'Functions[].{FunctionName:FunctionName, Version:Version}' --output table
To see exactly how many versions a function has:
FUNC_NAME="my-function"
aws lambda list-versions-by-function \
--function-name "$FUNC_NAME" \
--query 'length(Versions[])'
2. List all versions (to decide what to keep)
FUNC_NAME="my-function"
aws lambda list-versions-by-function \
--function-name "$FUNC_NAME" \
--output table \
--query 'Versions[].{Version:Version, LastModified:LastModified, Description:Description}'
Decide:
- KEEP:
$LATEST - KEEP: versions used by aliases (e.g.,
prod,staging, etc.) - DELETE: old versions not used by aliases
3. Find which versions are in use by aliases
FUNC_NAME="my-function"
aws lambda list-aliases \
--function-name "$FUNC_NAME" \
--query 'Aliases[].{Name:Name, FunctionVersion:FunctionVersion}' \
--output table
Make a note of all FunctionVersion values here; do not delete these.
4. Delete old versions (manually)
Delete a specific version (not $LATEST):
FUNC_NAME="my-function"
VER_TO_DELETE="5"
aws lambda delete-function \
--function-name "$FUNC_NAME" \
--qualifier "$VER_TO_DELETE"
Repeat for each unneeded version.
5. Delete old versions (scripted, keeping latest N and alias‑targets)
Example: keep the 10 most recent versions + all versions used by aliases.
FUNC_NAME="my-function"
KEEP_RECENT=10
# Versions used by aliases
ALIAS_VERSIONS=$(aws lambda list-aliases \
--function-name "$FUNC_NAME" \
--query 'Aliases[].FunctionVersion' \
--output text)
# All numbered versions, sorted newest first, excluding $LATEST
ALL_VERSIONS=$(aws lambda list-versions-by-function \
--function-name "$FUNC_NAME" \
--query "Versions[?Version!='\$LATEST'].Version" \
--output text | tr '\t' '\n' | sort -nr)
# Build list of versions to keep
KEEP_SET=$(printf "%s\n" $ALL_VERSIONS | head -n $KEEP_RECENT; printf "%s\n" $ALIAS_VERSIONS) \
| sort -n | uniq
# Delete everything not in KEEP_SET
for v in $ALL_VERSIONS; do
if ! printf "%s\n" $KEEP_SET | grep -qx "$v"; then
echo "Deleting $FUNC_NAME version $v"
aws lambda delete-function --function-name "$FUNC_NAME" --qualifier "$v"
fi
done
6. (Optional) Clean up across all functions
List all functions and loop:
for FUNC_NAME in $(aws lambda list-functions --query 'Functions[].FunctionName' --output text); do
echo "Processing $FUNC_NAME"
# Insert the version‑cleanup logic from step 5 here, referencing $FUNC_NAME
done
After cleaning up, re-run:
aws lambda list-versions-by-function --function-name "my-function" --query 'length(Versions[])'
to confirm the number of versions is reduced below your target (and below the limit).
Using Python
In AWS Lambda, “too many versions present” means you’re hitting or approaching the 75 versions per function limit. The fix is to clean up old versions safely, keeping only the ones actively used (by aliases or other references).
Below are step‑by‑step instructions plus a Python example you can run (locally or as its own Lambda) to delete old versions.
1. Decide Your Retention Policy
Before deleting anything, choose rules like:
- Keep all versions referenced by aliases (e.g.,
prod,dev,staging). - Keep the N most recent versions (e.g., last 10).
- Delete everything else.
Example policy we’ll implement:
- Keep:
- All aliased versions
- Last 10 published versions
- Delete:
- All older, unaliased versions
2. IAM Permissions Needed
Ensure the identity running the script has these permissions on the function(s):
{
"Effect": "Allow",
"Action": [
"lambda:ListVersionsByFunction",
"lambda:ListAliases",
"lambda:DeleteFunction"
],
"Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME"
}
If targeting many functions, widen the Resource to match a pattern.
3. Python Script to Clean Up Old Versions
Install boto3 if running locally:
pip install boto3
Python code (adjust config at the top):
import boto3
# -------- CONFIGURE THESE --------
REGION = "us-east-1"
FUNCTION_NAME = "my-lambda-function" # name or full ARN
VERSIONS_TO_KEEP = 10 # number of most recent versions to retain (besides aliased)
# ---------------------------------
lambda_client = boto3.client("lambda", region_name=REGION)
def get_all_versions(function_name):
versions = []
paginator = lambda_client.get_paginator("list_versions_by_function")
for page in paginator.paginate(FunctionName=function_name):
versions.extend(page.get("Versions", []))
# Exclude $LATEST from deletion logic
return [v for v in versions if v["Version"] != "$LATEST"]
def get_aliased_versions(function_name):
aliased_versions = set()
paginator = lambda_client.get_paginator("list_aliases")
for page in paginator.paginate(FunctionName=function_name):
for alias in page.get("Aliases", []):
aliased_versions.add(alias["FunctionVersion"])
return aliased_versions
def delete_version(function_name, version):
print(f"Deleting version {version} of {function_name}")
lambda_client.delete_function(
FunctionName=function_name,
Qualifier=version
)
def main():
# 1. Get all versions (excluding $LATEST)
all_versions = get_all_versions(FUNCTION_NAME)
# Sort by numeric version (string to int)
all_versions_sorted = sorted(
all_versions,
key=lambda v: int(v["Version"])
)
# 2. Find versions referenced by aliases
aliased_versions = get_aliased_versions(FUNCTION_NAME)
print(f"Aliased versions: {aliased_versions}")
# 3. Determine versions to always keep
# a) aliased versions
# b) latest N versions
latest_versions = all_versions_sorted[-VERSIONS_TO_KEEP:]
latest_versions_set = {v["Version"] for v in latest_versions}
protected_versions = aliased_versions.union(latest_versions_set)
print(f"Latest {VERSIONS_TO_KEEP} versions: {latest_versions_set}")
print(f"Protected versions (aliased + latest): {protected_versions}")
# 4. Identify deletable versions
deletable_versions = [
v["Version"]
for v in all_versions_sorted
if v["Version"] not in protected_versions
]
if not deletable_versions:
print("No versions to delete based on current policy.")
return
print("Versions to delete:", deletable_versions)
# 5. Delete (uncomment actual delete when ready)
for version in deletable_versions:
# Safety: final check that version is not protected
if version in protected_versions:
continue
delete_version(FUNCTION_NAME, version)
if __name__ == "__main__":
main()
4. Safe Execution Process
-
Dry run first
- Comment out the
delete_version(...)call and just print which versions would be deleted. - Confirm:
- No version used by
prod,staging, etc. will be deleted. - You’re okay losing those historic versions.
- No version used by
- Comment out the
-
Backup / change control
- (Optional but recommended) Export function configuration or code, or rely on your CI/CD source of truth.
-
Run in non‑prod first
- Test the script on a dev/staging Lambda.
-
Run with deletes enabled
- Uncomment
delete_versioncall. - Execute for each target function.
- Uncomment
5. Optional: Extend to Multiple Functions
You can list all functions and loop:
def list_all_functions():
funcs = []
paginator = lambda_client.get_paginator("list_functions")
for page in paginator.paginate():
funcs.extend(page["Functions"])
return funcs
def main():
functions = list_all_functions()
for f in functions:
name = f["FunctionName"]
print(f"\nProcessing function: {name}")
# reuse logic above, parameterize FUNCTION_NAME with name
6. Prevent Recurrence
- Integrate this script into:
- A scheduled Lambda (CloudWatch Events / EventBridge rule, e.g., daily/weekly).
- Your CI/CD pipeline after deployments.
- Optionally, make your pipeline avoid publishing unnecessary versions unless needed.
This will keep Lambda from reaching the “too many versions” limit again.
Using Terraform
# Terraform cannot automatically prune existing AWS Lambda versions.
# Version cleanup must be done via CLI/console or an external process.
# Going forward, ensure Terraform does NOT keep creating new versions
# unless you explicitly need them.
resource "aws_lambda_function" "this" {
function_name = "LAMBDA_FUNCTION_NAME" # substitute your Lambda name
role = aws_iam_role.lambda_exec.arn
handler = "HANDLER_NAME" # e.g. "index.handler"
runtime = "RUNTIME_NAME" # e.g. "python3.11"
filename = "PACKAGE_ZIP_PATH" # e.g. "build/lambda.zip"
# Do NOT set publish = true unless you want a new version every apply
# publish = true
# ...other required arguments...
}
Terraform does not expose any argument to limit or automatically delete old Lambda versions; to remediate “too many versions present” you must delete old versions via AWS Console or a script/CLI outside Terraform (e.g., aws lambda list-versions-by-function + delete-function --qualifier). After updating Terraform as above, terraform plan should show no further changes related to Lambda versions unless you modify the function itself.