Skip to content

Instantly share code, notes, and snippets.

@willblaschko
Created July 14, 2024 15:15
Show Gist options
  • Save willblaschko/89bfcc298d06cf1c69581d074dcf74b6 to your computer and use it in GitHub Desktop.
Save willblaschko/89bfcc298d06cf1c69581d074dcf74b6 to your computer and use it in GitHub Desktop.
Delete Old Cognito Records (Reduce Cost)
//
// Run this in Lambda for as long as is required to get through your pool. If you re-run it'll need to skip the keep records,
// but there should be less the second time around
//
import { CognitoIdentityClient, ListIdentitiesCommand, DeleteIdentitiesCommand } from "@aws-sdk/client-cognito-identity";
// Initialize the Cognito Identity Client
const client = new CognitoIdentityClient({ region: "<IDENTITY POOL REGION e.g. us-east-1>" });
// Set the Identity Pool ID
const identityPoolId = '<IDENTITY POOL ID>';
// Set the Age in Years you want to delete
const ageInYears = 2;
// Helper function for exponential backoff
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
// Retry function with exponential backoff
async function retryWithBackoff(fn, maxRetries = 5, delay = 200) {
for (let i = 0; i < maxRetries; i++) {
try {
let val = await fn();
console.log("Command Completed " + JSON.stringify(val));
return val;
} catch (error) {
if (error.name !== 'TooManyRequestsException' || i === maxRetries - 1) throw error;
console.log("Backing off " + delay);
await sleep(delay * Math.pow(2, i));
}
}
}
let deleteIdentities = async function(identities){
const oneYearAgo = new Date();
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - ageInYears);
const identitiesForDeletion = identities.filter(identity =>
new Date(identity.LastModifiedDate) < oneYearAgo
).map(identity => identity.IdentityId);
console.log("Identities to delete:");
console.log(JSON.stringify(identitiesForDeletion));
for (let i = 0; i < identitiesForDeletion.length; i += 25) {
const batch = identitiesForDeletion.slice(i, i + 25);
const deleteIdentitiesCommand = new DeleteIdentitiesCommand({
IdentityIdsToDelete: batch
});
await retryWithBackoff(() => client.send(deleteIdentitiesCommand));
console.log(`Deleted identities ${i + 1} to ${Math.min(i + 25, identitiesForDeletion.length)}`);
}
}
export const handler = async (event) => {
try {
let identities = [];
let nextToken = null;
do {
const listIdentitiesCommand = new ListIdentitiesCommand({
IdentityPoolId: identityPoolId,
MaxResults: 60,
NextToken: nextToken
});
const response = await retryWithBackoff(() => client.send(listIdentitiesCommand));
identities = response.Identities;
await deleteIdentities(identities);
nextToken = response.NextToken;
} while (nextToken);
return {
statusCode: 200,
body: JSON.stringify('Identity cleanup completed successfully')
};
} catch (error) {
console.error('Error:', error);
return {
statusCode: 500,
body: JSON.stringify('Error during identity cleanup')
};
}
};
{
"name": "cognito-cleanup",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-cognito-identity-provider": "^3.614.0",
"aws-sdk": "^2.1659.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment