@jaypie/constructs 1.2.47 → 1.2.49
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/dist/cjs/JaypieDistribution.d.ts +24 -0
- package/dist/cjs/JaypieHostedZone.d.ts +9 -0
- package/dist/cjs/helpers/ensureRoute53QueryLoggingPolicy.d.ts +12 -0
- package/dist/cjs/helpers/index.d.ts +1 -0
- package/dist/cjs/index.cjs +47 -8
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/JaypieDistribution.d.ts +24 -0
- package/dist/esm/JaypieHostedZone.d.ts +9 -0
- package/dist/esm/helpers/ensureRoute53QueryLoggingPolicy.d.ts +12 -0
- package/dist/esm/helpers/index.d.ts +1 -0
- package/dist/esm/index.js +47 -9
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -42,6 +42,30 @@ export interface JaypieWafConfig {
|
|
|
42
42
|
* }
|
|
43
43
|
*/
|
|
44
44
|
managedRuleOverrides?: Record<string, wafv2.CfnWebACL.RuleActionOverrideProperty[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Optional scope-down statements per managed rule group. When supplied,
|
|
47
|
+
* the managed rule group only evaluates requests that match the
|
|
48
|
+
* scope-down statement. Key is the managed rule group name; value is a
|
|
49
|
+
* `CfnWebACL.StatementProperty`.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // Only run AWSManagedRulesCommonRuleSet for non-/chat paths
|
|
53
|
+
* managedRuleScopeDowns: {
|
|
54
|
+
* AWSManagedRulesCommonRuleSet: {
|
|
55
|
+
* notStatement: {
|
|
56
|
+
* statement: {
|
|
57
|
+
* byteMatchStatement: {
|
|
58
|
+
* fieldToMatch: { uriPath: {} },
|
|
59
|
+
* positionalConstraint: "STARTS_WITH",
|
|
60
|
+
* searchString: "/chat",
|
|
61
|
+
* textTransformations: [{ priority: 0, type: "NONE" }],
|
|
62
|
+
* },
|
|
63
|
+
* },
|
|
64
|
+
* },
|
|
65
|
+
* },
|
|
66
|
+
* }
|
|
67
|
+
*/
|
|
68
|
+
managedRuleScopeDowns?: Record<string, wafv2.CfnWebACL.StatementProperty>;
|
|
45
69
|
/**
|
|
46
70
|
* Managed rule group names to apply
|
|
47
71
|
* @default ["AWSManagedRulesCommonRuleSet", "AWSManagedRulesKnownBadInputsRuleSet"]
|
|
@@ -46,6 +46,15 @@ interface JaypieHostedZoneProps {
|
|
|
46
46
|
* Each record will be created as a JaypieDnsRecord construct
|
|
47
47
|
*/
|
|
48
48
|
records?: JaypieHostedZoneRecordProps[];
|
|
49
|
+
/**
|
|
50
|
+
* Control the CloudWatch Logs resource policy that grants Route53 permission
|
|
51
|
+
* to write query logs. Defaults to `true`, which ensures a single
|
|
52
|
+
* stack-level wildcard policy covering every `/aws/route53/*` log group.
|
|
53
|
+
* Set to `false` to skip creating a managed policy (useful when an
|
|
54
|
+
* account-wide policy is provisioned externally).
|
|
55
|
+
* @default true
|
|
56
|
+
*/
|
|
57
|
+
queryLoggingPolicy?: boolean;
|
|
49
58
|
}
|
|
50
59
|
export declare class JaypieHostedZone extends Construct {
|
|
51
60
|
readonly hostedZone: IHostedZone;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CfnResourcePolicy } from "aws-cdk-lib/aws-logs";
|
|
2
|
+
import { Construct } from "constructs";
|
|
3
|
+
/**
|
|
4
|
+
* Create (or return the existing) stack-level CloudWatch Logs resource policy
|
|
5
|
+
* that grants Route53 permission to write query logs to any `/aws/route53/*`
|
|
6
|
+
* log group in the stack's account and region.
|
|
7
|
+
*
|
|
8
|
+
* Consolidates what would otherwise be one `AWS::Logs::ResourcePolicy` per
|
|
9
|
+
* hosted zone into a single wildcard policy, keeping the stack well clear of
|
|
10
|
+
* the 10-resource-policy-per-region account quota.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ensureRoute53QueryLoggingPolicy(scope: Construct): CfnResourcePolicy;
|
|
@@ -5,6 +5,7 @@ export { constructTagger } from "./constructTagger";
|
|
|
5
5
|
export { envHostname, HostConfig } from "./envHostname";
|
|
6
6
|
export { extendDatadogRole, ExtendDatadogRoleOptions, } from "./extendDatadogRole";
|
|
7
7
|
export { clearAllCertificateCaches, clearCertificateCache, resolveCertificate, ResolveCertificateOptions, } from "./resolveCertificate";
|
|
8
|
+
export { ensureRoute53QueryLoggingPolicy } from "./ensureRoute53QueryLoggingPolicy";
|
|
8
9
|
export { isEnv, isProductionEnv, isSandboxEnv } from "./isEnv";
|
|
9
10
|
export { isValidHostname } from "./isValidHostname";
|
|
10
11
|
export { isValidSubdomain } from "./isValidSubdomain";
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -11,12 +11,12 @@ var datadogCdkConstructsV2 = require('datadog-cdk-constructs-v2');
|
|
|
11
11
|
var errors = require('@jaypie/errors');
|
|
12
12
|
var awsIam = require('aws-cdk-lib/aws-iam');
|
|
13
13
|
var acm = require('aws-cdk-lib/aws-certificatemanager');
|
|
14
|
+
var logs = require('aws-cdk-lib/aws-logs');
|
|
14
15
|
var lambda = require('aws-cdk-lib/aws-lambda');
|
|
15
16
|
var logDestinations = require('aws-cdk-lib/aws-logs-destinations');
|
|
16
17
|
var s3n = require('aws-cdk-lib/aws-s3-notifications');
|
|
17
18
|
var sqs = require('aws-cdk-lib/aws-sqs');
|
|
18
19
|
var lambdaEventSources = require('aws-cdk-lib/aws-lambda-event-sources');
|
|
19
|
-
var logs = require('aws-cdk-lib/aws-logs');
|
|
20
20
|
var awsEvents = require('aws-cdk-lib/aws-events');
|
|
21
21
|
var awsEventsTargets = require('aws-cdk-lib/aws-events-targets');
|
|
22
22
|
var cloudfront = require('aws-cdk-lib/aws-cloudfront');
|
|
@@ -57,12 +57,12 @@ var route53__namespace = /*#__PURE__*/_interopNamespaceDefault(route53);
|
|
|
57
57
|
var route53Targets__namespace = /*#__PURE__*/_interopNamespaceDefault(route53Targets);
|
|
58
58
|
var secretsmanager__namespace = /*#__PURE__*/_interopNamespaceDefault(secretsmanager);
|
|
59
59
|
var acm__namespace = /*#__PURE__*/_interopNamespaceDefault(acm);
|
|
60
|
+
var logs__namespace = /*#__PURE__*/_interopNamespaceDefault(logs);
|
|
60
61
|
var lambda__namespace = /*#__PURE__*/_interopNamespaceDefault(lambda);
|
|
61
62
|
var logDestinations__namespace = /*#__PURE__*/_interopNamespaceDefault(logDestinations);
|
|
62
63
|
var s3n__namespace = /*#__PURE__*/_interopNamespaceDefault(s3n);
|
|
63
64
|
var sqs__namespace = /*#__PURE__*/_interopNamespaceDefault(sqs);
|
|
64
65
|
var lambdaEventSources__namespace = /*#__PURE__*/_interopNamespaceDefault(lambdaEventSources);
|
|
65
|
-
var logs__namespace = /*#__PURE__*/_interopNamespaceDefault(logs);
|
|
66
66
|
var cloudfront__namespace = /*#__PURE__*/_interopNamespaceDefault(cloudfront);
|
|
67
67
|
var origins__namespace = /*#__PURE__*/_interopNamespaceDefault(origins);
|
|
68
68
|
var wafv2__namespace = /*#__PURE__*/_interopNamespaceDefault(wafv2);
|
|
@@ -587,6 +587,40 @@ function clearAllCertificateCaches() {
|
|
|
587
587
|
// but stacks going out of scope will be garbage collected anyway
|
|
588
588
|
}
|
|
589
589
|
|
|
590
|
+
const SINGLETON_ID = "JaypieRoute53QueryLoggingPolicy";
|
|
591
|
+
const ROUTE53_LOG_GROUP_PREFIX = "/aws/route53";
|
|
592
|
+
const ROUTE53_SERVICE_PRINCIPAL = "route53.amazonaws.com";
|
|
593
|
+
/**
|
|
594
|
+
* Create (or return the existing) stack-level CloudWatch Logs resource policy
|
|
595
|
+
* that grants Route53 permission to write query logs to any `/aws/route53/*`
|
|
596
|
+
* log group in the stack's account and region.
|
|
597
|
+
*
|
|
598
|
+
* Consolidates what would otherwise be one `AWS::Logs::ResourcePolicy` per
|
|
599
|
+
* hosted zone into a single wildcard policy, keeping the stack well clear of
|
|
600
|
+
* the 10-resource-policy-per-region account quota.
|
|
601
|
+
*/
|
|
602
|
+
function ensureRoute53QueryLoggingPolicy(scope) {
|
|
603
|
+
const stack = cdk.Stack.of(scope);
|
|
604
|
+
const existing = stack.node.tryFindChild(SINGLETON_ID);
|
|
605
|
+
if (existing)
|
|
606
|
+
return existing;
|
|
607
|
+
const policyDocument = {
|
|
608
|
+
Version: "2012-10-17",
|
|
609
|
+
Statement: [
|
|
610
|
+
{
|
|
611
|
+
Effect: "Allow",
|
|
612
|
+
Principal: { Service: ROUTE53_SERVICE_PRINCIPAL },
|
|
613
|
+
Action: ["logs:CreateLogStream", "logs:PutLogEvents"],
|
|
614
|
+
Resource: `arn:${stack.partition}:logs:${stack.region}:${stack.account}:log-group:${ROUTE53_LOG_GROUP_PREFIX}/*:*`,
|
|
615
|
+
},
|
|
616
|
+
],
|
|
617
|
+
};
|
|
618
|
+
return new logs.CfnResourcePolicy(stack, SINGLETON_ID, {
|
|
619
|
+
policyName: `${stack.stackName}-Route53QueryLogging`,
|
|
620
|
+
policyDocument: JSON.stringify(policyDocument),
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
590
624
|
/**
|
|
591
625
|
* Check if the current environment matches the given environment
|
|
592
626
|
*/
|
|
@@ -2655,12 +2689,13 @@ class JaypieDistribution extends constructs.Construct {
|
|
|
2655
2689
|
}
|
|
2656
2690
|
else {
|
|
2657
2691
|
// Create new WebACL
|
|
2658
|
-
const { managedRuleOverrides, managedRules = DEFAULT_MANAGED_RULES, rateLimitPerIp = DEFAULT_RATE_LIMIT, } = wafConfig;
|
|
2692
|
+
const { managedRuleOverrides, managedRuleScopeDowns, managedRules = DEFAULT_MANAGED_RULES, rateLimitPerIp = DEFAULT_RATE_LIMIT, } = wafConfig;
|
|
2659
2693
|
let priority = 0;
|
|
2660
2694
|
const rules = [];
|
|
2661
2695
|
// Add managed rule groups
|
|
2662
2696
|
for (const ruleName of managedRules) {
|
|
2663
2697
|
const ruleActionOverrides = managedRuleOverrides?.[ruleName];
|
|
2698
|
+
const scopeDownStatement = managedRuleScopeDowns?.[ruleName];
|
|
2664
2699
|
rules.push({
|
|
2665
2700
|
name: ruleName,
|
|
2666
2701
|
priority: priority++,
|
|
@@ -2670,6 +2705,7 @@ class JaypieDistribution extends constructs.Construct {
|
|
|
2670
2705
|
name: ruleName,
|
|
2671
2706
|
vendorName: "AWS",
|
|
2672
2707
|
...(ruleActionOverrides && { ruleActionOverrides }),
|
|
2708
|
+
...(scopeDownStatement && { scopeDownStatement }),
|
|
2673
2709
|
},
|
|
2674
2710
|
},
|
|
2675
2711
|
visibilityConfig: {
|
|
@@ -3342,9 +3378,6 @@ class JaypieGitHubDeployRole extends constructs.Construct {
|
|
|
3342
3378
|
}
|
|
3343
3379
|
}
|
|
3344
3380
|
|
|
3345
|
-
const SERVICE = {
|
|
3346
|
-
ROUTE53: "route53.amazonaws.com",
|
|
3347
|
-
};
|
|
3348
3381
|
/**
|
|
3349
3382
|
* Check if a string is a valid hostname
|
|
3350
3383
|
*/
|
|
@@ -3410,8 +3443,13 @@ class JaypieHostedZone extends constructs.Construct {
|
|
|
3410
3443
|
if (project) {
|
|
3411
3444
|
cdk__namespace.Tags.of(this.logGroup).add(CDK$2.TAG.PROJECT, project);
|
|
3412
3445
|
}
|
|
3413
|
-
// Grant
|
|
3414
|
-
|
|
3446
|
+
// Grant Route53 permission to write query logs via a single stack-level
|
|
3447
|
+
// resource policy. Per-zone policies exhaust the CloudWatch Logs
|
|
3448
|
+
// 10-policy-per-region account quota (issue #311).
|
|
3449
|
+
const queryLoggingPolicy = props.queryLoggingPolicy ?? true;
|
|
3450
|
+
if (queryLoggingPolicy) {
|
|
3451
|
+
ensureRoute53QueryLoggingPolicy(this);
|
|
3452
|
+
}
|
|
3415
3453
|
// Add destination based on configuration
|
|
3416
3454
|
if (destination !== false) {
|
|
3417
3455
|
const lambdaDestination = destination === true
|
|
@@ -4899,6 +4937,7 @@ exports.clearSecretsCache = clearSecretsCache;
|
|
|
4899
4937
|
exports.constructEnvName = constructEnvName;
|
|
4900
4938
|
exports.constructStackName = constructStackName;
|
|
4901
4939
|
exports.constructTagger = constructTagger;
|
|
4940
|
+
exports.ensureRoute53QueryLoggingPolicy = ensureRoute53QueryLoggingPolicy;
|
|
4902
4941
|
exports.envHostname = envHostname;
|
|
4903
4942
|
exports.extendDatadogRole = extendDatadogRole;
|
|
4904
4943
|
exports.isEnv = isEnv;
|