diff --git a/README.md b/README.md index 7d07fe2..7746814 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,9 @@ inputs: KeyType: HASH Projection: ProjectionType: 'ALL' + timeToLiveSpecification: # (optional) + AttributeName: attribute2 + Enabled: false region: us-east-1 ``` diff --git a/src/serverless.js b/src/serverless.js index 8c34659..484fe65 100644 --- a/src/serverless.js +++ b/src/serverless.js @@ -5,7 +5,14 @@ const { mergeDeepRight, pick } = require('ramda'); const AWS = require('aws-sdk'); // eslint-disable-next-line import/no-unresolved const { Component } = require('@serverless/core'); -const { log, createTable, deleteTable, describeTable, updateTable } = require('./utils'); +const { + log, + createTable, + deleteTable, + describeTable, + updateTable, + updateTimeToLive, +} = require('./utils'); const outputsList = ['name', 'arn', 'region']; @@ -27,6 +34,7 @@ const defaults = { name: null, region: 'us-east-1', deletionPolicy: 'delete', + timeToLiveSpecification: undefined, }; class AwsDynamoDb extends Component { @@ -88,6 +96,10 @@ class AwsDynamoDb extends Component { await updateTable.call(this, { dynamodb, prevGlobalSecondaryIndexes, ...config }); } + if (config.timeToLiveSpecification) { + await updateTimeToLive({ dynamodb, ...config }); + } + log(`Table ${config.name} was successfully deployed to the ${config.region} region.`); this.state.arn = config.arn; diff --git a/src/utils.js b/src/utils.js index 7ae0545..2023fc0 100644 --- a/src/utils.js +++ b/src/utils.js @@ -119,10 +119,28 @@ async function deleteTable({ dynamodb, name }) { return !!res; } +async function updateTimeToLive({ dynamodb, name, timeToLiveSpecification = {} }) { + return await dynamodb + .waitFor('tableExists', { TableName: name }, async (err) => { + if (err) throw err; + return await dynamodb + .updateTimeToLive({ + TableName: name, + TimeToLiveSpecification: { + AttributeName: timeToLiveSpecification.AttributeName, + Enabled: timeToLiveSpecification.Enabled, + }, + }) + .promise(); + }) + .promise(); +} + module.exports = { log, createTable, describeTable, updateTable, deleteTable, + updateTimeToLive, }; diff --git a/templates/aws-dynamodb-starter/serverless.template.yml b/templates/aws-dynamodb-starter/serverless.template.yml index 509d303..93488a4 100644 --- a/templates/aws-dynamodb-starter/serverless.template.yml +++ b/templates/aws-dynamodb-starter/serverless.template.yml @@ -3,4 +3,4 @@ org: serverlessinc description: Deploys a serverless NoSQL database powered by AWS DynamoDB keywords: aws, serverless, nosql, database repo: https://github.com/serverless-components/aws-dynamodb -license: MIT \ No newline at end of file +license: MIT diff --git a/test/integration.test.js b/test/integration.test.js index 5e402b1..2756d59 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -16,6 +16,10 @@ const instanceYaml = { stage: 'dev', inputs: { deletionPolicy: 'delete', + timeToLiveSpecification: { + AttributeName: 'expires', + Enabled: true, + }, attributeDefinitions: [ { AttributeName: 'attribute1', @@ -75,6 +79,8 @@ it('should successfully deploy dynamodb table and local index', async () => { const res = await getTable(credentials, name); + // const resTTL = await getTableTimeToLive(credentials, name); + expect(instance.outputs.name).toBeDefined(); expect(instance.outputs.arn).toBeDefined(); expect(res.Table.AttributeDefinitions.length).toEqual(2); diff --git a/test/utils.js b/test/utils.js index 183fae3..5e47786 100644 --- a/test/utils.js +++ b/test/utils.js @@ -28,7 +28,7 @@ const getCredentials = () => { }; if (!credentials.aws.accessKeyId || !credentials.aws.accessKeyId) { - throw new Error('Unable to run tests. AWS credentials not found in the envionrment'); + throw new Error('Unable to run tests. AWS credentials not found in the environment'); } return credentials; @@ -67,4 +67,30 @@ const getTable = async (credentials, tableName) => { .promise(); }; -module.exports = { sleep, generateId, getCredentials, getServerlessSdk, getTable }; +/* + * Fetches a DynamoDB timeToLive for a table from aws for validation + * @param ${object} credentials - the cross provider credentials object + * @param ${string} tableName - the name of the dynamodb table + */ +const getTableTimeToLive = async (credentials, tableName) => { + const config = { + credentials: credentials.aws, + region: 'us-east-1', + }; + const dynamodb = new AWS.DynamoDB(config); + + return dynamodb + .describeTimeToLive({ + TableName: tableName, + }) + .promise(); +}; + +module.exports = { + sleep, + generateId, + getCredentials, + getServerlessSdk, + getTable, + getTableTimeToLive, +};