@gammarers/aws-daily-cloud-watch-logs-archive-stack 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js ADDED
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DailyCloudWatchLogsArchiveStack = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const crypto = require("crypto");
7
+ const aws_secure_bucket_1 = require("@gammarers/aws-secure-bucket");
8
+ const aws_secure_log_bucket_1 = require("@gammarers/aws-secure-log-bucket");
9
+ const cdk = require("aws-cdk-lib");
10
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
11
+ const iam = require("aws-cdk-lib/aws-iam");
12
+ const logs = require("aws-cdk-lib/aws-logs");
13
+ const scheduler = require("aws-cdk-lib/aws-scheduler");
14
+ const sfn = require("aws-cdk-lib/aws-stepfunctions");
15
+ const tasks = require("aws-cdk-lib/aws-stepfunctions-tasks");
16
+ const log_archiver_function_1 = require("./funcs/log-archiver-function");
17
+ class DailyCloudWatchLogsArchiveStack extends cdk.Stack {
18
+ constructor(scope, id, props) {
19
+ super(scope, id, props);
20
+ // 👇 Get current account & region
21
+ //const account = cdk.Stack.of(this).account;
22
+ //const stackName: string = cdk.Stack.of(this).stackName;
23
+ //const region = cdk.Stack.of(this).region;
24
+ //const account = this.account;
25
+ const region = this.region;
26
+ const randomNameKey = crypto.createHash('shake256', { outputLength: 4 })
27
+ .update(cdk.Names.uniqueId(this))
28
+ .digest('hex');
29
+ // 👇 Create Backup S3 Bucket
30
+ const logArchiveBucket = new aws_secure_log_bucket_1.SecureLogBucket(this, 'LogArchiveBucket', {
31
+ bucketName: `log-archive-${randomNameKey}`,
32
+ encryption: aws_secure_bucket_1.SecureBucketEncryption.S3_MANAGED,
33
+ });
34
+ logArchiveBucket.addToResourcePolicy(new iam.PolicyStatement({
35
+ effect: iam.Effect.ALLOW,
36
+ principals: [
37
+ new iam.ServicePrincipal(`logs.${region}.amazonaws.com`),
38
+ ],
39
+ actions: [
40
+ 's3:GetBucketAcl',
41
+ ],
42
+ resources: [
43
+ logArchiveBucket.bucketArn,
44
+ ],
45
+ }));
46
+ logArchiveBucket.addToResourcePolicy(new iam.PolicyStatement({
47
+ effect: iam.Effect.ALLOW,
48
+ principals: [
49
+ new iam.ServicePrincipal(`logs.${region}.amazonaws.com`),
50
+ ],
51
+ actions: [
52
+ 's3:PutObject',
53
+ ],
54
+ resources: [
55
+ `${logArchiveBucket.bucketArn}/*`,
56
+ ],
57
+ conditions: {
58
+ StringEquals: {
59
+ 's3:x-amz-acl': 'bucket-owner-full-control',
60
+ },
61
+ },
62
+ }));
63
+ // 👇 Create Lambda Execution role.
64
+ const lambdaExecutionRole = new iam.Role(this, 'LambdaExecutionRole', {
65
+ roleName: `daily-cw-logs-archive-lambda-exec-${randomNameKey}-role`,
66
+ description: 'daily CloudWatch Logs archive machine exec role.',
67
+ assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
68
+ managedPolicies: [
69
+ iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
70
+ ],
71
+ inlinePolicies: {
72
+ ['log-export-policy']: new iam.PolicyDocument({
73
+ statements: [
74
+ new iam.PolicyStatement({
75
+ effect: iam.Effect.ALLOW,
76
+ actions: [
77
+ 'logs:CreateExportTask',
78
+ ],
79
+ resources: ['*'],
80
+ }),
81
+ ],
82
+ }),
83
+ ['put-bucket-policy']: new iam.PolicyDocument({
84
+ statements: [
85
+ new iam.PolicyStatement({
86
+ effect: iam.Effect.ALLOW,
87
+ actions: [
88
+ 's3:GetBucketAcl',
89
+ 's3:PutObject',
90
+ ],
91
+ resources: [
92
+ logArchiveBucket.bucketArn,
93
+ ],
94
+ }),
95
+ ],
96
+ }),
97
+ },
98
+ });
99
+ // 👇 Create Lambda Function
100
+ const lambdaFunction = new log_archiver_function_1.LogArchiverFunction(this, 'LogArchiveFunction', {
101
+ functionName: `daily-cw-logs-archive-${randomNameKey}-func`,
102
+ description: 'A function to archive logs s3 bucket from CloudWatch Logs.',
103
+ environment: {
104
+ BUCKET_NAME: logArchiveBucket.bucketName,
105
+ },
106
+ role: lambdaExecutionRole,
107
+ });
108
+ // 👇 Create Lambda Function Log Group
109
+ new logs.LogGroup(this, 'LambdaFunctionLogGroup', {
110
+ // logGroupName: lambdaFunction.logGroup.logGroupName, // <- If you specify this line to Custom:LogRotation resource created.
111
+ logGroupName: `/aws/lambda/${lambdaFunction.functionName}`,
112
+ retention: logs.RetentionDays.ONE_MONTH,
113
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
114
+ });
115
+ const succeed = new sfn.Succeed(this, 'Succeed');
116
+ // 👇 Get CloudWatch Logs Resources
117
+ const getLogGroupResources = new tasks.CallAwsService(this, 'GetResources', {
118
+ iamResources: ['*'],
119
+ iamAction: 'tag:GetResources',
120
+ service: 'resourcegroupstaggingapi',
121
+ action: 'getResources',
122
+ parameters: {
123
+ ResourceTypeFilters: [
124
+ 'logs:log-group',
125
+ ],
126
+ TagFilters: [
127
+ {
128
+ 'Key.$': '$.tagKey',
129
+ 'Values.$': '$.tagValues',
130
+ },
131
+ ],
132
+ },
133
+ resultPath: '$.Result',
134
+ resultSelector: {
135
+ 'TargetResources.$': '$..ResourceTagMappingList[*].ResourceARN',
136
+ },
137
+ });
138
+ // Log Group Export Map
139
+ const logGroupExportMap = new sfn.Map(this, 'LogGroupExportMap', {
140
+ itemsPath: sfn.JsonPath.stringAt('$.Result.TargetResources'),
141
+ maxConcurrency: 1,
142
+ });
143
+ // 👇 Get Log Group Name
144
+ const getLogGroupName = new sfn.Pass(this, 'GetLogGroupName', {
145
+ parameters: {
146
+ 'TargetLogGroupName.$': "States.ArrayGetItem(States.StringSplit($, ':'), 6)",
147
+ },
148
+ });
149
+ logGroupExportMap.iterator(getLogGroupName);
150
+ // 👇 Invoke Lambda Function
151
+ const invokeLambdaFunction = new tasks.LambdaInvoke(this, 'InvokeLambdaFunction', {
152
+ lambdaFunction: lambdaFunction,
153
+ outputPath: '$.Payload',
154
+ payload: sfn.TaskInput.fromJsonPathAt('$'),
155
+ retryOnServiceExceptions: true,
156
+ });
157
+ getLogGroupName.next(invokeLambdaFunction);
158
+ // 👇 Describe Export Tasks
159
+ const describeExportTasks = new tasks.CallAwsService(this, 'DescribeExportTasks', {
160
+ iamResources: ['*'],
161
+ iamAction: 'logs:DescribeExportTasks',
162
+ service: 'cloudwatchlogs',
163
+ action: 'describeExportTasks',
164
+ parameters: {
165
+ 'TaskId.$': '$.TaskId',
166
+ },
167
+ resultPath: '$.Result',
168
+ resultSelector: {
169
+ 'DescribeExportTasksStatus.$': '$.ExportTasks[0].Status.Code',
170
+ },
171
+ });
172
+ invokeLambdaFunction.next(describeExportTasks);
173
+ const exportRunningWait = new sfn.Wait(this, 'ExportRunningWait', {
174
+ time: sfn.WaitTime.duration(aws_cdk_lib_1.Duration.seconds(10)),
175
+ });
176
+ const exportPendingWait = new sfn.Wait(this, 'ExportPendingWait', {
177
+ time: sfn.WaitTime.duration(aws_cdk_lib_1.Duration.seconds(3)),
178
+ });
179
+ // 👇 Export Status Check
180
+ const exportTaskStatusCheck = new sfn.Choice(this, 'ExportTaskStatusCheck')
181
+ .when(sfn.Condition.stringEquals('$.Result.DescribeExportTasksStatus', 'FAILED'), getLogGroupName)
182
+ .when(sfn.Condition.stringEquals('$.Result.DescribeExportTasksStatus', 'RUNNING'), exportRunningWait
183
+ .next(describeExportTasks))
184
+ .when(sfn.Condition.stringEquals('$.Result.DescribeExportTasksStatus', 'PENDING'), exportPendingWait
185
+ .next(describeExportTasks))
186
+ .otherwise(succeed);
187
+ describeExportTasks.next(exportTaskStatusCheck);
188
+ getLogGroupResources.next(logGroupExportMap);
189
+ //
190
+ const machine = new sfn.StateMachine(this, 'StateMachine', {
191
+ stateMachineName: `daily-cw-logs-archive-${randomNameKey}-machine`,
192
+ definition: getLogGroupResources,
193
+ });
194
+ // 👇 auto generated role name & description renaming.
195
+ const role = machine.node.findChild('Role');
196
+ const cfnRole = role.node.defaultChild;
197
+ cfnRole.addPropertyOverride('RoleName', `daily-cw-logs-archive-machine-${randomNameKey}-role`);
198
+ cfnRole.addPropertyOverride('Description', 'daily CloudWatch Logs archive machine role.');
199
+ const policy = role.node.findChild('DefaultPolicy');
200
+ const cfnPolicy = policy.node.defaultChild;
201
+ cfnPolicy.addPropertyOverride('PolicyName', `daily-cw-logs-archive-machine-${randomNameKey}-default-policy`);
202
+ // 👇 EventBridge Scheduler IAM Role (StateMachine Start Execution)
203
+ const schedulerExecutionRole = new iam.Role(this, 'SchedulerExecutionRole', {
204
+ roleName: `daily-cw-logs-archive-${randomNameKey}-schedule-role`,
205
+ description: 'daily CloudWatch Log archive schedule',
206
+ assumedBy: new iam.ServicePrincipal('scheduler.amazonaws.com'),
207
+ inlinePolicies: {
208
+ 'state-machine-exec-policy': new iam.PolicyDocument({
209
+ statements: [
210
+ new iam.PolicyStatement({
211
+ effect: iam.Effect.ALLOW,
212
+ actions: [
213
+ 'states:StartExecution',
214
+ ],
215
+ resources: [
216
+ machine.stateMachineArn,
217
+ ],
218
+ }),
219
+ ],
220
+ }),
221
+ },
222
+ });
223
+ // 👇 Schedule
224
+ new scheduler.CfnSchedule(this, 'Schedule', {
225
+ name: `daily-cw-logs-archive-${randomNameKey}-schedule`,
226
+ description: 'daily CloudWatch Logs archive schedule',
227
+ state: 'ENABLED',
228
+ flexibleTimeWindow: {
229
+ mode: 'OFF',
230
+ },
231
+ scheduleExpressionTimezone: 'UTC',
232
+ scheduleExpression: 'cron(1 13 * * ? *)',
233
+ target: {
234
+ arn: machine.stateMachineArn,
235
+ roleArn: schedulerExecutionRole.roleArn,
236
+ input: JSON.stringify({
237
+ tagKey: props.targetResourceTag.key,
238
+ tagValues: props.targetResourceTag.values,
239
+ }),
240
+ retryPolicy: {
241
+ maximumEventAgeInSeconds: 60,
242
+ maximumRetryAttempts: 0,
243
+ },
244
+ },
245
+ });
246
+ }
247
+ }
248
+ exports.DailyCloudWatchLogsArchiveStack = DailyCloudWatchLogsArchiveStack;
249
+ _a = JSII_RTTI_SYMBOL_1;
250
+ DailyCloudWatchLogsArchiveStack[_a] = { fqn: "@gammarers/aws-daily-cloud-watch-logs-archive-stack.DailyCloudWatchLogsArchiveStack", version: "2.7.0" };
251
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsb0VBQXNFO0FBQ3RFLDRFQUFtRTtBQUNuRSxtQ0FBbUM7QUFDbkMsNkNBQXVDO0FBQ3ZDLDJDQUEyQztBQUMzQyw2Q0FBNkM7QUFDN0MsdURBQXVEO0FBQ3ZELHFEQUFxRDtBQUNyRCw2REFBNkQ7QUFFN0QseUVBQW9FO0FBV3BFLE1BQWEsK0JBQWdDLFNBQVEsR0FBRyxDQUFDLEtBQUs7SUFDNUQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUEyQztRQUNuRixLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUV4QixrQ0FBa0M7UUFDbEMsNkNBQTZDO1FBQzdDLHlEQUF5RDtRQUN6RCwyQ0FBMkM7UUFDM0MsK0JBQStCO1FBQy9CLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFM0IsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsRUFBRSxZQUFZLEVBQUUsQ0FBQyxFQUFFLENBQUM7YUFDckUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUdqQiw2QkFBNkI7UUFDN0IsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLHVDQUFlLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFO1lBQ3JFLFVBQVUsRUFBRSxlQUFlLGFBQWEsRUFBRTtZQUMxQyxVQUFVLEVBQUUsMENBQXNCLENBQUMsVUFBVTtTQUM5QyxDQUFDLENBQUM7UUFDSCxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7WUFDM0QsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FB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TyxFQUFFLHNCQUFzQixDQUFDLE9BQU87Z0JBQ3ZDLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDO29CQUNwQixNQUFNLEVBQUUsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEdBQUc7b0JBQ25DLFNBQVMsRUFBRSxLQUFLLENBQUMsaUJBQWlCLENBQUMsTUFBTTtpQkFDMUMsQ0FBQztnQkFDRixXQUFXLEVBQUU7b0JBQ1gsd0JBQXdCLEVBQUUsRUFBRTtvQkFDNUIsb0JBQW9CLEVBQUUsQ0FBQztpQkFDeEI7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBdFFILDBFQXVRQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgU2VjdXJlQnVja2V0RW5jcnlwdGlvbiB9IGZyb20gJ0BnYW1tYXJlcnMvYXdzLXNlY3VyZS1idWNrZXQnO1xuaW1wb3J0IHsgU2VjdXJlTG9nQnVja2V0IH0gZnJvbSAnQGdhbW1hcmVycy9hd3Mtc2VjdXJlLWxvZy1idWNrZXQnO1xuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBzY2hlZHVsZXIgZnJvbSAnYXdzLWNkay1saWIvYXdzLXNjaGVkdWxlcic7XG5pbXBvcnQgKiBhcyBzZm4gZnJvbSAnYXdzLWNkay1saWIvYXdzLXN0ZXBmdW5jdGlvbnMnO1xuaW1wb3J0ICogYXMgdGFza3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLXN0ZXBmdW5jdGlvbnMtdGFza3MnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBMb2dBcmNoaXZlckZ1bmN0aW9uIH0gZnJvbSAnLi9mdW5jcy9sb2ctYXJjaGl2ZXItZnVuY3Rpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIERhaWx5Q2xvdWRXYXRjaExvZ3NBcmNoaXZlU3RhY2tQcm9wcyBleHRlbmRzIGNkay5TdGFja1Byb3BzIHtcbiAgcmVhZG9ubHkgdGFyZ2V0UmVzb3VyY2VUYWc6IFRhcmdldFJlc291cmNlVGFnUHJvcGVydHk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFyZ2V0UmVzb3VyY2VUYWdQcm9wZXJ0eSB7XG4gIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuICByZWFkb25seSB2YWx1ZXM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY2xhc3MgRGFpbHlDbG91ZFdhdGNoTG9nc0FyY2hpdmVTdGFjayBleHRlbmRzIGNkay5TdGFjayB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBEYWlseUNsb3VkV2F0Y2hMb2dzQXJjaGl2ZVN0YWNrUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIC8vIPCfkYcgR2V0IGN1cnJlbnQgYWNjb3VudCAmIHJlZ2lvblxuICAgIC8vY29uc3QgYWNjb3VudCA9IGNkay5TdGFjay5vZih0aGlzKS5hY2NvdW50O1xuICAgIC8vY29uc3Qgc3RhY2tOYW1lOiBzdHJpbmcgPSBjZGsuU3RhY2sub2YodGhpcykuc3RhY2tOYW1lO1xuICAgIC8vY29uc3QgcmVnaW9uID0gY2RrLlN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcbiAgICAvL2NvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnQ7XG4gICAgY29uc3QgcmVnaW9uID0gdGhpcy5yZWdpb247XG5cbiAgICBjb25zdCByYW5kb21OYW1lS2V5ID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYWtlMjU2JywgeyBvdXRwdXRMZW5ndGg6IDQgfSlcbiAgICAgIC51cGRhdGUoY2RrLk5hbWVzLnVuaXF1ZUlkKHRoaXMpKVxuICAgICAgLmRpZ2VzdCgnaGV4Jyk7XG5cblxuICAgIC8vIPCfkYcgQ3JlYXRlIEJhY2t1cCBTMyBCdWNrZXRcbiAgICBjb25zdCBsb2dBcmNoaXZlQnVja2V0ID0gbmV3IFNlY3VyZUxvZ0J1Y2tldCh0aGlzLCAnTG9nQXJjaGl2ZUJ1Y2tldCcsIHtcbiAgICAgIGJ1Y2tldE5hbWU6IGBsb2ctYXJjaGl2ZS0ke3JhbmRvbU5hbWVLZXl9YCxcbiAgICAgIGVuY3J5cHRpb246IFNlY3VyZUJ1Y2tldEVuY3J5cHRpb24uUzNfTUFOQUdFRCxcbiAgICB9KTtcbiAgICBsb2dBcmNoaXZlQnVja2V0LmFkZFRvUmVzb3VyY2VQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgcHJpbmNpcGFsczogW1xuICAgICAgICBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoYGxvZ3MuJHtyZWdpb259LmFtYXpvbmF3cy5jb21gKSxcbiAgICAgIF0sXG4gICAgICBhY3Rpb25zOiBbXG4gICAgICAgICdzMzpHZXRCdWNrZXRBY2wnLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICBsb2dBcmNoaXZlQnVja2V0LmJ1Y2tldEFybixcbiAgICAgIF0sXG4gICAgfSkpO1xuICAgIGxvZ0FyY2hpdmVCdWNrZXQuYWRkVG9SZXNvdXJjZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICBwcmluY2lwYWxzOiBbXG4gICAgICAgIG5ldyBpYW0uU2VydmljZVByaW5jaXBhbChgbG9ncy4ke3JlZ2lvbn0uYW1hem9uYXdzLmNvbWApLFxuICAgICAgXSxcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3MzOlB1dE9iamVjdCcsXG4gICAgICBdLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIGAke2xvZ0FyY2hpdmVCdWNrZXQuYnVja2V0QXJufS8qYCxcbiAgICAgIF0sXG4gICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgICdzMzp4LWFtei1hY2wnOiAnYnVja2V0LW93bmVyLWZ1bGwtY29udHJvbCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIC8vIPCfkYcgQ3JlYXRlIExhbWJkYSBFeGVjdXRpb24gcm9sZS5cbiAgICBjb25zdCBsYW1iZGFFeGVjdXRpb25Sb2xlID0gbmV3IGlhbS5Sb2xlKHRoaXMsICdMYW1iZGFFeGVjdXRpb25Sb2xlJywge1xuICAgICAgcm9sZU5hbWU6IGBkYWlseS1jdy1sb2dzLWFyY2hpdmUtbGFtYmRhLWV4ZWMtJHtyYW5kb21OYW1lS2V5fS1yb2xlYCxcbiAgICAgIGRlc2NyaXB0aW9uOiAnZGFpbHkgQ2xvdWRXYXRjaCBMb2dzIGFyY2hpdmUgbWFjaGluZSBleGVjIHJvbGUuJyxcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdsYW1iZGEuYW1hem9uYXdzLmNvbScpLFxuICAgICAgbWFuYWdlZFBvbGljaWVzOiBbXG4gICAgICAgIGlhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZSgnc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZScpLFxuICAgICAgXSxcbiAgICAgIGlubGluZVBvbGljaWVzOiB7XG4gICAgICAgIFsnbG9nLWV4cG9ydC1wb2xpY3knXTogbmV3IGlhbS5Qb2xpY3lEb2N1bWVudCh7XG4gICAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgICAnbG9nczpDcmVhdGVFeHBvcnRUYXNrJyxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pLFxuICAgICAgICBbJ3B1dC1idWNrZXQtcG9saWN5J106IG5ldyBpYW0uUG9saWN5RG9jdW1lbnQoe1xuICAgICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgJ3MzOkdldEJ1Y2tldEFjbCcsXG4gICAgICAgICAgICAgICAgJ3MzOlB1dE9iamVjdCcsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICAgIGxvZ0FyY2hpdmVCdWNrZXQuYnVja2V0QXJuLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgXSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8g8J+RhyBDcmVhdGUgTGFtYmRhIEZ1bmN0aW9uXG4gICAgY29uc3QgbGFtYmRhRnVuY3Rpb24gPSBuZXcgTG9nQXJjaGl2ZXJGdW5jdGlvbih0aGlzLCAnTG9nQXJjaGl2ZUZ1bmN0aW9uJywge1xuICAgICAgZnVuY3Rpb25OYW1lOiBgZGFpbHktY3ctbG9ncy1hcmNoaXZlLSR7cmFuZG9tTmFtZUtleX0tZnVuY2AsXG4gICAgICBkZXNjcmlwdGlvbjogJ0EgZnVuY3Rpb24gdG8gYXJjaGl2ZSBsb2dzIHMzIGJ1Y2tldCBmcm9tIENsb3VkV2F0Y2ggTG9ncy4nLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQlVDS0VUX05BTUU6IGxvZ0FyY2hpdmVCdWNrZXQuYnVja2V0TmFtZSxcbiAgICAgIH0sXG4gICAgICByb2xlOiBsYW1iZGFFeGVjdXRpb25Sb2xlLFxuICAgIH0pO1xuXG4gICAgLy8g8J+RhyBDcmVhdGUgTGFtYmRhIEZ1bmN0aW9uIExvZyBHcm91cFxuICAgIG5ldyBsb2dzLkxvZ0dyb3VwKHRoaXMsICdMYW1iZGFGdW5jdGlvbkxvZ0dyb3VwJywge1xuICAgICAgLy8gbG9nR3JvdXBOYW1lOiBsYW1iZGFGdW5jdGlvbi5sb2dHcm91cC5sb2dHcm91cE5hbWUsIC8vIDwtIElmIHlvdSBzcGVjaWZ5IHRoaXMgbGluZSB0byBDdXN0b206TG9nUm90YXRpb24gcmVzb3VyY2UgY3JlYXRlZC5cbiAgICAgIGxvZ0dyb3VwTmFtZTogYC9hd3MvbGFtYmRhLyR7bGFtYmRhRnVuY3Rpb24uZnVuY3Rpb25OYW1lfWAsXG4gICAgICByZXRlbnRpb246IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfTU9OVEgsXG4gICAgICByZW1vdmFsUG9saWN5OiBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc3VjY2VlZCA9IG5ldyBzZm4uU3VjY2VlZCh0aGlzLCAnU3VjY2VlZCcpO1xuXG4gICAgLy8g8J+RhyBHZXQgQ2xvdWRXYXRjaCBMb2dzIFJlc291cmNlc1xuICAgIGNvbnN0IGdldExvZ0dyb3VwUmVzb3VyY2VzID0gbmV3IHRhc2tzLkNhbGxBd3NTZXJ2aWNlKHRoaXMsICdHZXRSZXNvdXJjZXMnLCB7XG4gICAgICBpYW1SZXNvdXJjZXM6IFsnKiddLFxuICAgICAgaWFtQWN0aW9uOiAndGFnOkdldFJlc291cmNlcycsXG4gICAgICBzZXJ2aWNlOiAncmVzb3VyY2Vncm91cHN0YWdnaW5nYXBpJyxcbiAgICAgIGFjdGlvbjogJ2dldFJlc291cmNlcycsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIFJlc291cmNlVHlwZUZpbHRlcnM6IFtcbiAgICAgICAgICAnbG9nczpsb2ctZ3JvdXAnLFxuICAgICAgICBdLFxuICAgICAgICBUYWdGaWx0ZXJzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgJ0tleS4kJzogJyQudGFnS2V5JyxcbiAgICAgICAgICAgICdWYWx1ZXMuJCc6ICckLnRhZ1ZhbHVlcycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICByZXN1bHRQYXRoOiAnJC5SZXN1bHQnLFxuICAgICAgcmVzdWx0U2VsZWN0b3I6IHtcbiAgICAgICAgJ1RhcmdldFJlc291cmNlcy4kJzogJyQuLlJlc291cmNlVGFnTWFwcGluZ0xpc3RbKl0uUmVzb3VyY2VBUk4nLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIExvZyBHcm91cCBFeHBvcnQgTWFwXG4gICAgY29uc3QgbG9nR3JvdXBFeHBvcnRNYXAgPSBuZXcgc2ZuLk1hcCh0aGlzLCAnTG9nR3JvdXBFeHBvcnRNYXAnLCB7XG4gICAgICBpdGVtc1BhdGg6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5SZXN1bHQuVGFyZ2V0UmVzb3VyY2VzJyksXG4gICAgICBtYXhDb25jdXJyZW5jeTogMSxcbiAgICB9KTtcblxuICAgIC8vIPCfkYcgR2V0IExvZyBHcm91cCBOYW1lXG4gICAgY29uc3QgZ2V0TG9nR3JvdXBOYW1lID0gbmV3IHNmbi5QYXNzKHRoaXMsICdHZXRMb2dHcm91cE5hbWUnLCB7XG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICdUYXJnZXRMb2dHcm91cE5hbWUuJCc6IFwiU3RhdGVzLkFycmF5R2V0SXRlbShTdGF0ZXMuU3RyaW5nU3BsaXQoJCwgJzonKSwgNilcIixcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBsb2dHcm91cEV4cG9ydE1hcC5pdGVyYXRvcihnZXRMb2dHcm91cE5hbWUpO1xuXG4gICAgLy8g8J+RhyBJbnZva2UgTGFtYmRhIEZ1bmN0aW9uXG4gICAgY29uc3QgaW52b2tlTGFtYmRhRnVuY3Rpb24gPSBuZXcgdGFza3MuTGFtYmRhSW52b2tlKHRoaXMsICdJbnZva2VMYW1iZGFGdW5jdGlvbicsIHtcbiAgICAgIGxhbWJkYUZ1bmN0aW9uOiBsYW1iZGFGdW5jdGlvbixcbiAgICAgIG91dHB1dFBhdGg6ICckLlBheWxvYWQnLFxuICAgICAgcGF5bG9hZDogc2ZuLlRhc2tJbnB1dC5mcm9tSnNvblBhdGhBdCgnJCcpLFxuICAgICAgcmV0cnlPblNlcnZpY2VFeGNlcHRpb25zOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgZ2V0TG9nR3JvdXBOYW1lLm5leHQoaW52b2tlTGFtYmRhRnVuY3Rpb24pO1xuXG4gICAgLy8g8J+RhyBEZXNjcmliZSBFeHBvcnQgVGFza3NcbiAgICBjb25zdCBkZXNjcmliZUV4cG9ydFRhc2tzID0gbmV3IHRhc2tzLkNhbGxBd3NTZXJ2aWNlKHRoaXMsICdEZXNjcmliZUV4cG9ydFRhc2tzJywge1xuICAgICAgaWFtUmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIGlhbUFjdGlvbjogJ2xvZ3M6RGVzY3JpYmVFeHBvcnRUYXNrcycsXG4gICAgICBzZXJ2aWNlOiAnY2xvdWR3YXRjaGxvZ3MnLFxuICAgICAgYWN0aW9uOiAnZGVzY3JpYmVFeHBvcnRUYXNrcycsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICdUYXNrSWQuJCc6ICckLlRhc2tJZCcsXG4gICAgICB9LFxuICAgICAgcmVzdWx0UGF0aDogJyQuUmVzdWx0JyxcbiAgICAgIHJlc3VsdFNlbGVjdG9yOiB7XG4gICAgICAgICdEZXNjcmliZUV4cG9ydFRhc2tzU3RhdHVzLiQnOiAnJC5FeHBvcnRUYXNrc1swXS5TdGF0dXMuQ29kZScsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaW52b2tlTGFtYmRhRnVuY3Rpb24ubmV4dChkZXNjcmliZUV4cG9ydFRhc2tzKTtcblxuICAgIGNvbnN0IGV4cG9ydFJ1bm5pbmdXYWl0ID0gbmV3IHNmbi5XYWl0KHRoaXMsICdFeHBvcnRSdW5uaW5nV2FpdCcsIHtcbiAgICAgIHRpbWU6IHNmbi5XYWl0VGltZS5kdXJhdGlvbihEdXJhdGlvbi5zZWNvbmRzKDEwKSksXG4gICAgfSk7XG5cbiAgICBjb25zdCBleHBvcnRQZW5kaW5nV2FpdCA9IG5ldyBzZm4uV2FpdCh0aGlzLCAnRXhwb3J0UGVuZGluZ1dhaXQnLCB7XG4gICAgICB0aW1lOiBzZm4uV2FpdFRpbWUuZHVyYXRpb24oRHVyYXRpb24uc2Vjb25kcygzKSksXG4gICAgfSk7XG5cbiAgICAvLyDwn5GHIEV4cG9ydCBTdGF0dXMgQ2hlY2tcbiAgICBjb25zdCBleHBvcnRUYXNrU3RhdHVzQ2hlY2sgPSBuZXcgc2ZuLkNob2ljZSh0aGlzLCAnRXhwb3J0VGFza1N0YXR1c0NoZWNrJylcbiAgICAgIC53aGVuKFxuICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQuRGVzY3JpYmVFeHBvcnRUYXNrc1N0YXR1cycsICdGQUlMRUQnKSxcbiAgICAgICAgZ2V0TG9nR3JvdXBOYW1lLFxuICAgICAgKVxuICAgICAgLndoZW4oXG4gICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLlJlc3VsdC5EZXNjcmliZUV4cG9ydFRhc2tzU3RhdHVzJywgJ1JVTk5JTkcnKSxcbiAgICAgICAgZXhwb3J0UnVubmluZ1dhaXRcbiAgICAgICAgICAubmV4dChkZXNjcmliZUV4cG9ydFRhc2tzKSxcbiAgICAgIClcbiAgICAgIC53aGVuKFxuICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQuRGVzY3JpYmVFeHBvcnRUYXNrc1N0YXR1cycsICdQRU5ESU5HJyksXG4gICAgICAgIGV4cG9ydFBlbmRpbmdXYWl0XG4gICAgICAgICAgLm5leHQoZGVzY3JpYmVFeHBvcnRUYXNrcyksXG4gICAgICApXG4gICAgICAub3RoZXJ3aXNlKHN1Y2NlZWQpO1xuXG4gICAgZGVzY3JpYmVFeHBvcnRUYXNrcy5uZXh0KGV4cG9ydFRhc2tTdGF0dXNDaGVjayk7XG5cbiAgICBnZXRMb2dHcm91cFJlc291cmNlcy5uZXh0KGxvZ0dyb3VwRXhwb3J0TWFwKTtcblxuICAgIC8vXG4gICAgY29uc3QgbWFjaGluZSA9IG5ldyBzZm4uU3RhdGVNYWNoaW5lKHRoaXMsICdTdGF0ZU1hY2hpbmUnLCB7XG4gICAgICBzdGF0ZU1hY2hpbmVOYW1lOiBgZGFpbHktY3ctbG9ncy1hcmNoaXZlLSR7cmFuZG9tTmFtZUtleX0tbWFjaGluZWAsXG4gICAgICBkZWZpbml0aW9uOiBnZXRMb2dHcm91cFJlc291cmNlcyxcbiAgICB9KTtcbiAgICAvLyDwn5GHIGF1dG8gZ2VuZXJhdGVkIHJvbGUgbmFtZSAmIGRlc2NyaXB0aW9uIHJlbmFtaW5nLlxuICAgIGNvbnN0IHJvbGUgPSBtYWNoaW5lLm5vZGUuZmluZENoaWxkKCdSb2xlJykgYXMgaWFtLlJvbGU7XG4gICAgY29uc3QgY2ZuUm9sZSA9IHJvbGUubm9kZS5kZWZhdWx0Q2hpbGQgYXMgaWFtLkNmblJvbGU7XG4gICAgY2ZuUm9sZS5hZGRQcm9wZXJ0eU92ZXJyaWRlKCdSb2xlTmFtZScsIGBkYWlseS1jdy1sb2dzLWFyY2hpdmUtbWFjaGluZS0ke3JhbmRvbU5hbWVLZXl9LXJvbGVgKTtcbiAgICBjZm5Sb2xlLmFkZFByb3BlcnR5T3ZlcnJpZGUoJ0Rlc2NyaXB0aW9uJywgJ2RhaWx5IENsb3VkV2F0Y2ggTG9ncyBhcmNoaXZlIG1hY2hpbmUgcm9sZS4nKTtcbiAgICBjb25zdCBwb2xpY3kgPSByb2xlLm5vZGUuZmluZENoaWxkKCdEZWZhdWx0UG9saWN5JykgYXMgaWFtLlBvbGljeTtcbiAgICBjb25zdCBjZm5Qb2xpY3kgPSBwb2xpY3kubm9kZS5kZWZhdWx0Q2hpbGQgYXMgaWFtLkNmblBvbGljeTtcbiAgICBjZm5Qb2xpY3kuYWRkUHJvcGVydHlPdmVycmlkZSgnUG9saWN5TmFtZScsIGBkYWlseS1jdy1sb2dzLWFyY2hpdmUtbWFjaGluZS0ke3JhbmRvbU5hbWVLZXl9LWRlZmF1bHQtcG9saWN5YCk7XG5cbiAgICAvLyDwn5GHIEV2ZW50QnJpZGdlIFNjaGVkdWxlciBJQU0gUm9sZSAoU3RhdGVNYWNoaW5lIFN0YXJ0IEV4ZWN1dGlvbilcbiAgICBjb25zdCBzY2hlZHVsZXJFeGVjdXRpb25Sb2xlID0gbmV3IGlhbS5Sb2xlKHRoaXMsICdTY2hlZHVsZXJFeGVjdXRpb25Sb2xlJywge1xuICAgICAgcm9sZU5hbWU6IGBkYWlseS1jdy1sb2dzLWFyY2hpdmUtJHtyYW5kb21OYW1lS2V5fS1zY2hlZHVsZS1yb2xlYCxcbiAgICAgIGRlc2NyaXB0aW9uOiAnZGFpbHkgQ2xvdWRXYXRjaCBMb2cgYXJjaGl2ZSBzY2hlZHVsZScsXG4gICAgICBhc3N1bWVkQnk6IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnc2NoZWR1bGVyLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgIGlubGluZVBvbGljaWVzOiB7XG4gICAgICAgICdzdGF0ZS1tYWNoaW5lLWV4ZWMtcG9saWN5JzogbmV3IGlhbS5Qb2xpY3lEb2N1bWVudCh7XG4gICAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgICAnc3RhdGVzOlN0YXJ0RXhlY3V0aW9uJyxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgICAgbWFjaGluZS5zdGF0ZU1hY2hpbmVBcm4sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyDwn5GHIFNjaGVkdWxlXG4gICAgbmV3IHNjaGVkdWxlci5DZm5TY2hlZHVsZSh0aGlzLCAnU2NoZWR1bGUnLCB7XG4gICAgICBuYW1lOiBgZGFpbHktY3ctbG9ncy1hcmNoaXZlLSR7cmFuZG9tTmFtZUtleX0tc2NoZWR1bGVgLFxuICAgICAgZGVzY3JpcHRpb246ICdkYWlseSBDbG91ZFdhdGNoIExvZ3MgYXJjaGl2ZSBzY2hlZHVsZScsXG4gICAgICBzdGF0ZTogJ0VOQUJMRUQnLFxuICAgICAgZmxleGlibGVUaW1lV2luZG93OiB7XG4gICAgICAgIG1vZGU6ICdPRkYnLFxuICAgICAgfSxcbiAgICAgIHNjaGVkdWxlRXhwcmVzc2lvblRpbWV6b25lOiAnVVRDJyxcbiAgICAgIHNjaGVkdWxlRXhwcmVzc2lvbjogJ2Nyb24oMSAxMyAqICogPyAqKScsXG4gICAgICB0YXJnZXQ6IHtcbiAgICAgICAgYXJuOiBtYWNoaW5lLnN0YXRlTWFjaGluZUFybixcbiAgICAgICAgcm9sZUFybjogc2NoZWR1bGVyRXhlY3V0aW9uUm9sZS5yb2xlQXJuLFxuICAgICAgICBpbnB1dDogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIHRhZ0tleTogcHJvcHMudGFyZ2V0UmVzb3VyY2VUYWcua2V5LFxuICAgICAgICAgIHRhZ1ZhbHVlczogcHJvcHMudGFyZ2V0UmVzb3VyY2VUYWcudmFsdWVzLFxuICAgICAgICB9KSxcbiAgICAgICAgcmV0cnlQb2xpY3k6IHtcbiAgICAgICAgICBtYXhpbXVtRXZlbnRBZ2VJblNlY29uZHM6IDYwLFxuICAgICAgICAgIG1heGltdW1SZXRyeUF0dGVtcHRzOiAwLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufSJdfQ==
package/package.json ADDED
@@ -0,0 +1,165 @@
1
+ {
2
+ "name": "@gammarers/aws-daily-cloud-watch-logs-archive-stack",
3
+ "description": "AWS CloudWatch Logs daily archive to s3 bucket",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/gammarers/aws-daily-cloud-watch-logs-archive-stack.git"
7
+ },
8
+ "scripts": {
9
+ "build": "npx projen build",
10
+ "bump": "npx projen bump",
11
+ "bundle": "npx projen bundle",
12
+ "bundle:funcs/log-archiver.lambda": "npx projen bundle:funcs/log-archiver.lambda",
13
+ "bundle:funcs/log-archiver.lambda:watch": "npx projen bundle:funcs/log-archiver.lambda:watch",
14
+ "clobber": "npx projen clobber",
15
+ "compat": "npx projen compat",
16
+ "compile": "npx projen compile",
17
+ "default": "npx projen default",
18
+ "docgen": "npx projen docgen",
19
+ "eject": "npx projen eject",
20
+ "eslint": "npx projen eslint",
21
+ "package": "npx projen package",
22
+ "package-all": "npx projen package-all",
23
+ "package:dotnet": "npx projen package:dotnet",
24
+ "package:js": "npx projen package:js",
25
+ "package:python": "npx projen package:python",
26
+ "post-compile": "npx projen post-compile",
27
+ "post-upgrade": "npx projen post-upgrade",
28
+ "pre-compile": "npx projen pre-compile",
29
+ "release": "npx projen release",
30
+ "test": "npx projen test",
31
+ "test:watch": "npx projen test:watch",
32
+ "unbump": "npx projen unbump",
33
+ "upgrade": "npx projen upgrade",
34
+ "watch": "npx projen watch",
35
+ "projen": "npx projen"
36
+ },
37
+ "author": {
38
+ "name": "yicr",
39
+ "email": "yicr@users.noreply.github.com",
40
+ "organization": false
41
+ },
42
+ "devDependencies": {
43
+ "@aws-sdk/client-cloudwatch-logs": "3.556.x",
44
+ "@gammarer/jest-serializer-aws-cdk-asset-filename-replacer": "^0.4.30",
45
+ "@types/aws-lambda": "^8.10.137",
46
+ "@types/jest": "^29.5.12",
47
+ "@types/node": "^18",
48
+ "@typescript-eslint/eslint-plugin": "^6",
49
+ "@typescript-eslint/parser": "^6",
50
+ "aws-cdk-lib": "2.80.0",
51
+ "aws-sdk-client-mock": "^3",
52
+ "aws-sdk-client-mock-jest": "^3",
53
+ "constructs": "10.0.5",
54
+ "esbuild": "^0.20.2",
55
+ "eslint": "^8",
56
+ "eslint-import-resolver-typescript": "^3.6.1",
57
+ "eslint-plugin-import": "^2.29.1",
58
+ "jest": "^29.7.0",
59
+ "jest-junit": "^15",
60
+ "jsii": "5.2.x",
61
+ "jsii-diff": "^1.97.0",
62
+ "jsii-docgen": "^10.4.1",
63
+ "jsii-pacmak": "^1.97.0",
64
+ "jsii-rosetta": "5.2.x",
65
+ "projen": "^0.81.1",
66
+ "standard-version": "^9",
67
+ "ts-jest": "^29.1.2",
68
+ "ts-node": "^10.9.2",
69
+ "typescript": "5.2.x"
70
+ },
71
+ "peerDependencies": {
72
+ "@gammarers/aws-secure-bucket": "~1.3.3",
73
+ "@gammarers/aws-secure-log-bucket": "~1.6.2",
74
+ "aws-cdk-lib": "^2.80.0",
75
+ "constructs": "^10.0.5"
76
+ },
77
+ "dependencies": {
78
+ "@gammarers/aws-secure-bucket": "~1.3.3",
79
+ "@gammarers/aws-secure-log-bucket": "~1.6.2"
80
+ },
81
+ "keywords": [
82
+ "archive",
83
+ "aws",
84
+ "aws-cdk",
85
+ "bucket",
86
+ "cdk",
87
+ "lambda",
88
+ "s3",
89
+ "scheduler"
90
+ ],
91
+ "engines": {
92
+ "node": ">= 18.0.0"
93
+ },
94
+ "main": "lib/index.js",
95
+ "license": "Apache-2.0",
96
+ "publishConfig": {
97
+ "access": "public"
98
+ },
99
+ "version": "2.7.0",
100
+ "jest": {
101
+ "snapshotSerializers": [
102
+ "<rootDir>/node_modules/@gammarer/jest-serializer-aws-cdk-asset-filename-replacer"
103
+ ],
104
+ "testMatch": [
105
+ "<rootDir>/src/**/__tests__/**/*.ts?(x)",
106
+ "<rootDir>/(test|src)/**/*(*.)@(spec|test).ts?(x)"
107
+ ],
108
+ "clearMocks": true,
109
+ "collectCoverage": true,
110
+ "coverageReporters": [
111
+ "json",
112
+ "lcov",
113
+ "clover",
114
+ "cobertura",
115
+ "text"
116
+ ],
117
+ "coverageDirectory": "coverage",
118
+ "coveragePathIgnorePatterns": [
119
+ "/node_modules/"
120
+ ],
121
+ "testPathIgnorePatterns": [
122
+ "/node_modules/"
123
+ ],
124
+ "watchPathIgnorePatterns": [
125
+ "/node_modules/"
126
+ ],
127
+ "reporters": [
128
+ "default",
129
+ [
130
+ "jest-junit",
131
+ {
132
+ "outputDirectory": "test-reports"
133
+ }
134
+ ]
135
+ ],
136
+ "transform": {
137
+ "^.+\\.[t]sx?$": [
138
+ "ts-jest",
139
+ {
140
+ "tsconfig": "tsconfig.dev.json"
141
+ }
142
+ ]
143
+ }
144
+ },
145
+ "types": "lib/index.d.ts",
146
+ "stability": "stable",
147
+ "jsii": {
148
+ "outdir": "dist",
149
+ "targets": {
150
+ "python": {
151
+ "distName": "gammarers.aws-daily-cloud-watch-logs-archive-stack",
152
+ "module": "gammarers.aws_daily_cloud_watch_logs_archive_stack"
153
+ },
154
+ "dotnet": {
155
+ "namespace": "Gammarers.CDK.AWS",
156
+ "packageId": "Gammarers.CDK.AWS.DailyCloudWatchLogsArchiveStack"
157
+ }
158
+ },
159
+ "tsc": {
160
+ "outDir": "lib",
161
+ "rootDir": "src"
162
+ }
163
+ },
164
+ "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"."
165
+ }