Created
July 14, 2024 15:15
-
-
Save willblaschko/89bfcc298d06cf1c69581d074dcf74b6 to your computer and use it in GitHub Desktop.
Delete Old Cognito Records (Reduce Cost)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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') | |
}; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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