> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Exceeds versions limits remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        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

        1. Sign in to the **AWS Management Console**.
        2. Go to **Lambda**:\
           Services → **Lambda**.
        3. In the left pane, click **Functions**, then select your **Lambda function**.
        4. In the function view, select the **Versions** tab.
           * You will see: `$LATEST` and numbered versions (e.g., 1, 2, 3…).

        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
        * Keep a small number of recent versions for rollback (e.g., last 3–5).

        ***

        ### 2. Check and update aliases (so deletes are safe)

        1. In the same function, go to the **Aliases** tab.
        2. For each alias (e.g., `prod`, `dev`):
           * Confirm which **version** it is pointing to.
        3. 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

        1. Back in the **Versions** tab:
        2. 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
        * 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.
      </Accordion>

      <Accordion title="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

        ```bash theme={null}
        aws lambda list-functions --query 'Functions[].{FunctionName:FunctionName, Version:Version}' --output table
        ```

        To see exactly how many versions a function has:

        ```bash theme={null}
        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)

        ```bash theme={null}
        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

        ```bash theme={null}
        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`):

        ```bash theme={null}
        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.

        ```bash theme={null}
        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:

        ```bash theme={null}
        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:

        ```bash theme={null}
        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).
      </Accordion>

      <Accordion title="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):

        ```json theme={null}
        {
          "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:

        ```bash theme={null}
        pip install boto3
        ```

        Python code (adjust config at the top):

        ```python theme={null}
        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

        1. **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.

        2. **Backup / change control**
           * (Optional but recommended) Export function configuration or code, or rely on your CI/CD source of truth.

        3. **Run in non‑prod first**
           * Test the script on a dev/staging Lambda.

        4. **Run with deletes enabled**
           * Uncomment `delete_version` call.
           * Execute for each target function.

        ***

        ## 5. Optional: Extend to Multiple Functions

        You can list all functions and loop:

        ```python theme={null}
        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.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # 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.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
