Search code examples
amazon-web-servicesaws-lambdaaws-sdkaws-secrets-manager

how to update secrets manager secret value from lambda function?


I have a access token retrieved from an api and its lifetimes is 5 hours. I saw that secrets manager can rotate a secret but minimum rotation time is 1 day. Because of this i thought that i can write a lambda function that works every 5 hours and takes a new token from api and updates secret with this token. This answer https://stackoverflow.com/a/66610124/11902308 mentions that it can be done but i couldn't find any resource about how to update a secret from a lambda function.

Note: I have multiple task and token is invalid when a new one is generated because of that task have to share it.


Solution

  • You didn't mention which AWS SDK you are using, but here is an example for AWS SDK for JS to create or update a Secret. Additionally, it handles the case for deleted secrets (SecretsManager doesn't delete secrets immediately, it marks them as scheduled for deletion) and restores and updates them.

    import { AWSError } from 'aws-sdk';
    import SecretsManager, { SecretARNType } from 'aws-sdk/clients/secretsmanager';
    
    const secretsManager = new SecretsManager({ apiVersion: '2017-10-17' });
    
    const putSecret = async (name: string, secret: Record<string, unknown>, secretId?: SecretARNType): Promise<SecretARNType> => {
      try {
        const result = secretId
          ? secretsManager.updateSecret({
              SecretId: secretId,
              SecretString: JSON.stringify(secret),
            })
          : secretsManager.createSecret({
              Name: name,
              SecretString: JSON.stringify(secret),
            });
    
        const { ARN } = await result.promise();
    
        if (!ARN) throw new Error(`Error saving secret ${name}`);
    
        return ARN;
      } catch (error) {
        const awsError = error as AWSError;
    
        // InvalidRequestException indicates that the secret is scheduled for deletion
        if (awsError.code === 'InvalidRequestException') {
          // restore existng secret
          await secretsManager
            .restoreSecret({
              SecretId: secretId || name,
            })
            .promise();
          // update secret
          const { ARN } = await secretsManager
            .updateSecret({
              SecretId: secretId || name,
              SecretString: JSON.stringify(secret),
            })
            .promise();
    
          if (!ARN) throw new Error(`Error restoring secret ${name}`);
    
          return ARN;
        }
    
        throw error;
      }
    };
    
    

    The code is in TypeScript, but should be easily converted into the language of your choice because the AWS SDK functions have the same name in other languages.