Skip to content

Commit

Permalink
fix(lambda): avoid OperationAbortedException when using log retention (
Browse files Browse the repository at this point in the history
…#2237)

If multiple LogRetention constructs are present in the stack, they will try to
act on the provider's log group at the same time. This can sometime result in
an OperationAbortedException. To avoid this and because this operation is not
critical it is better to catch all errors when acting on the provider's log
group
  • Loading branch information
jogold authored and Elad Ben-Israel committed Apr 11, 2019
1 parent 8f0468a commit 12a118c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
13 changes: 10 additions & 3 deletions packages/@aws-cdk/aws-lambda/lib/log-retention-provider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,16 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent
// group for this function should already exist at this stage because we
// already logged the event but due to the async nature of Lambda logging
// there could be a race condition. So we also try to create the log group
// of this function first.
await createLogGroupSafe(`/aws/lambda/${context.functionName}`);
await setRetentionPolicy(`/aws/lambda/${context.functionName}`, 1);
// of this function first. If multiple LogRetention constructs are present
// in the stack, they will try to act on this function's log group at the
// same time. This can sometime result in an OperationAbortedException. To
// avoid this and because this operation is not critical we catch all errors.
try {
await createLogGroupSafe(`/aws/lambda/${context.functionName}`);
await setRetentionPolicy(`/aws/lambda/${context.functionName}`, 1);
} catch (e) {
console.log(e);
}
}
}

Expand Down
35 changes: 35 additions & 0 deletions packages/@aws-cdk/aws-lambda/test/test.log-retention-provider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import AWSSDK = require('aws-sdk');
import AWS = require('aws-sdk-mock');
import nock = require('nock');
import { Test } from 'nodeunit';
Expand Down Expand Up @@ -227,4 +228,38 @@ export = {

test.done();
},

async 'does not fail when operations on provider log group fail'(test: Test) {
const createLogGroupFake = (params: AWSSDK.CloudWatchLogs.CreateLogGroupRequest) => {
if (params.logGroupName === '/aws/lambda/provider') {
return Promise.reject(new Error('OperationAbortedException'));
}
return Promise.resolve({});
};

const putRetentionPolicyFake = sinon.fake.resolves({});
const deleteRetentionPolicyFake = sinon.fake.resolves({});

AWS.mock('CloudWatchLogs', 'createLogGroup', createLogGroupFake);
AWS.mock('CloudWatchLogs', 'putRetentionPolicy', putRetentionPolicyFake);
AWS.mock('CloudWatchLogs', 'deleteRetentionPolicy', deleteRetentionPolicyFake);

const event = {
...eventCommon,
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
RetentionInDays: '30',
LogGroupName: 'group'
}
};

const request = createRequest('SUCCESS');

await provider.handler(event as AWSLambda.CloudFormationCustomResourceCreateEvent, context);

test.equal(request.isDone(), true);

test.done();
}
};

0 comments on commit 12a118c

Please sign in to comment.