Skip to content

Commit 5b07d5e

Browse files
feat(cli): put s3 bucket lifecycle policy for aws tests (#2434)
* feat(fargate): set s3 lifecycle rules for object expiration * refactor(lambda): use central util getAccountId and ensureS3BucketExists * feat(lambda): set s3 lifecycle rules for object expiration
1 parent 35f0e1c commit 5b07d5e

File tree

3 files changed

+64
-40
lines changed

3 files changed

+64
-40
lines changed

packages/artillery/lib/platform/aws-ecs/ecs.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,21 @@ class PlatformECS {
2727
if (!this.testRunId) {
2828
throw new Error('testRunId is required');
2929
}
30+
31+
this.s3LifecycleConfigurationRules = [
32+
{
33+
Expiration: { Days: 2 },
34+
Filter: { Prefix: 'tests/' },
35+
ID: 'RemoveAdHocTestData',
36+
Status: 'Enabled'
37+
},
38+
{
39+
Expiration: { Days: 7 },
40+
Filter: { Prefix: 'test-runs/' },
41+
ID: 'RemoveTestRunMetadata',
42+
Status: 'Enabled'
43+
}
44+
];
3045
}
3146

3247
async init() {
@@ -35,7 +50,7 @@ class PlatformECS {
3550
this.accountId = await getAccountId();
3651

3752
await ensureSSMParametersExist(this.platformOpts.region);
38-
await ensureS3BucketExists();
53+
await ensureS3BucketExists('global', this.s3LifecycleConfigurationRules);
3954
await createIAMResources(this.accountId);
4055
}
4156

packages/artillery/lib/platform/aws-lambda/index.js

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ const prices = require('./prices');
3434
const { STATES } = require('../local/artillery-worker-local');
3535

3636
const { SQS_QUEUES_NAME_PREFIX } = require('../aws/constants');
37+
const ensureS3BucketExists = require('../aws/aws-ensure-s3-bucket-exists');
38+
const getAccountId = require('../aws/aws-get-account-id');
3739

3840
const createSQSQueue = require('../aws/aws-create-sqs-queue');
3941

@@ -91,6 +93,20 @@ class PlatformLambda {
9193
platformConfig['lambda-role-arn'] || platformConfig['lambdaRoleArn'];
9294

9395
this.platformOpts = platformOpts;
96+
this.s3LifecycleConfigurationRules = [
97+
{
98+
Expiration: { Days: 2 },
99+
Filter: { Prefix: '/lambda' },
100+
ID: 'RemoveAdHocTestData',
101+
Status: 'Enabled'
102+
},
103+
{
104+
Expiration: { Days: 7 },
105+
Filter: { Prefix: '/' },
106+
ID: 'RemoveTestRunMetadata',
107+
Status: 'Enabled'
108+
}
109+
];
94110

95111
this.artilleryArgs = [];
96112
}
@@ -103,7 +119,7 @@ class PlatformLambda {
103119
artillery.log('λ Creating AWS Lambda function...');
104120

105121
await setDefaultAWSCredentials(AWS);
106-
this.accountId = await this.getAccountId();
122+
this.accountId = await getAccountId();
107123

108124
const dirname = temp.mkdirSync(); // TODO: May want a way to override this by the user
109125
const zipfile = temp.path({ suffix: '.zip' });
@@ -313,7 +329,10 @@ class PlatformLambda {
313329
await this.createZip(dirname, zipfile);
314330

315331
artillery.log('Preparing AWS environment...');
316-
const bucketName = await this.ensureS3BucketExists();
332+
const bucketName = await ensureS3BucketExists(
333+
this.region,
334+
this.s3LifecycleConfigurationRules
335+
);
317336
this.bucketName = bucketName;
318337

319338
const s3path = await this.uploadLambdaZip(bucketName, zipfile);
@@ -639,42 +658,6 @@ class PlatformLambda {
639658
});
640659
}
641660

642-
// TODO: Move into reusable platform util
643-
async ensureS3BucketExists() {
644-
const accountId = await this.getAccountId();
645-
// S3 and Lambda have to be in the same region, which means we can't reuse
646-
// the bucket created by Pro to store Lambda deployment zips
647-
const bucketName = `artilleryio-test-data-${this.region}-${accountId}`;
648-
const s3 = new AWS.S3({ region: this.region });
649-
650-
try {
651-
await s3.listObjectsV2({ Bucket: bucketName, MaxKeys: 1 }).promise();
652-
} catch (s3Err) {
653-
if (s3Err.code === 'NoSuchBucket') {
654-
const res = await s3.createBucket({ Bucket: bucketName }).promise();
655-
} else {
656-
throw s3Err;
657-
}
658-
}
659-
660-
return bucketName;
661-
}
662-
663-
// TODO: Move into reusable platform util
664-
async getAccountId() {
665-
let stsOpts = {};
666-
if (process.env.ARTILLERY_STS_OPTS) {
667-
stsOpts = Object.assign(
668-
stsOpts,
669-
JSON.parse(process.env.ARTILLERY_STS_OPTS)
670-
);
671-
}
672-
673-
const sts = new AWS.STS(stsOpts);
674-
const awsAccountId = (await sts.getCallerIdentity({}).promise()).Account;
675-
return awsAccountId;
676-
}
677-
678661
async createLambdaRole() {
679662
const ROLE_NAME = 'artilleryio-default-lambda-role-20230116';
680663
const POLICY_NAME = 'artilleryio-lambda-policy-20230116';

packages/artillery/lib/platform/aws/aws-ensure-s3-bucket-exists.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,34 @@ const getAWSAccountId = require('./aws-get-account-id');
1010

1111
const { S3_BUCKET_NAME_PREFIX } = require('./constants');
1212

13+
const setBucketLifecyclePolicy = async (
14+
bucketName,
15+
lifecycleConfigurationRules
16+
) => {
17+
const s3 = new AWS.S3();
18+
const params = {
19+
Bucket: bucketName,
20+
LifecycleConfiguration: {
21+
Rules: lifecycleConfigurationRules
22+
}
23+
};
24+
try {
25+
await s3.putBucketLifecycleConfiguration(params).promise();
26+
} catch (err) {
27+
debug('Error setting lifecycle policy');
28+
debug(err);
29+
}
30+
};
31+
1332
// Create an S3 bucket in the given region if it doesn't already exist.
1433
// By default, the bucket will be created without specifying a specific region.
1534
// Sometimes we need to use region-specific buckets, e.g. when
1635
// creating Lambda functions from a zip file in S3 the region of the
1736
// Lambda and the region of the S3 bucket must match.
18-
module.exports = async function ensureS3BucketExists(region = 'global') {
37+
module.exports = async function ensureS3BucketExists(
38+
region = 'global',
39+
lifecycleConfigurationRules = []
40+
) {
1941
const accountId = await getAWSAccountId();
2042
let bucketName = `${S3_BUCKET_NAME_PREFIX}-${accountId}`;
2143
if (region !== 'global') {
@@ -34,6 +56,10 @@ module.exports = async function ensureS3BucketExists(region = 'global') {
3456
}
3557
}
3658

59+
if (lifecycleConfigurationRules.length > 0) {
60+
await setBucketLifecyclePolicy(bucketName, lifecycleConfigurationRules);
61+
}
62+
3763
debug(bucketName);
3864
return bucketName;
3965
};

0 commit comments

Comments
 (0)