@fjall/components-infrastructure 0.96.0 → 0.99.3
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/lib/app.d.ts +68 -1
- package/dist/lib/app.js +113 -4
- package/dist/lib/config/aws/__t17fixture.d.ts +1 -0
- package/dist/lib/config/aws/__t17fixture.js +3 -0
- package/dist/lib/config/aws/__t17fixtureType.d.ts +2 -0
- package/dist/lib/config/aws/__t17fixtureType.js +1 -0
- package/dist/lib/config/aws/alarmTopic.js +8 -4
- package/dist/lib/config/aws/cloudTrail.js +1 -1
- package/dist/lib/config/aws/disasterRecovery.js +11 -16
- package/dist/lib/config/aws/ecrDefaultImage.d.ts +0 -1
- package/dist/lib/config/aws/ecrDefaultImage.js +13 -23
- package/dist/lib/config/aws/identityCenter.d.ts +10 -3
- package/dist/lib/config/aws/identityCenter.js +101 -37
- package/dist/lib/config/aws/identityCenterGroupMembership.js +8 -2
- package/dist/lib/config/aws/identityCenterMembership.d.ts +11 -0
- package/dist/lib/config/aws/identityCenterMembership.js +61 -0
- package/dist/lib/config/aws/index.d.ts +1 -1
- package/dist/lib/config/aws/index.js +1 -1
- package/dist/lib/config/aws/ipam.js +6 -11
- package/dist/lib/config/aws/oidcConnector.js +5 -1
- package/dist/lib/config/aws/scpPreset.js +4 -1
- package/dist/lib/patterns/aws/_eslint_test_tmp/leak.d.ts +1 -0
- package/dist/lib/patterns/aws/_eslint_test_tmp/leak.js +4 -0
- package/dist/lib/patterns/aws/account.js +2 -4
- package/dist/lib/patterns/aws/apexDomainPattern.js +10 -10
- package/dist/lib/patterns/aws/bastionFactory.d.ts +10 -0
- package/dist/lib/patterns/aws/bastionFactory.js +29 -0
- package/dist/lib/patterns/aws/buildkite.d.ts +2 -2
- package/dist/lib/patterns/aws/buildkite.js +51 -97
- package/dist/lib/patterns/aws/cdn.js +1 -1
- package/dist/lib/patterns/aws/clickhouseDatabase.d.ts +173 -0
- package/dist/lib/patterns/aws/clickhouseDatabase.js +601 -0
- package/dist/lib/patterns/aws/compute.d.ts +4 -6
- package/dist/lib/patterns/aws/compute.js +7 -13
- package/dist/lib/patterns/aws/computeEcs.d.ts +93 -5
- package/dist/lib/patterns/aws/computeEcs.js +867 -37
- package/dist/lib/patterns/aws/computeEcsTypes.d.ts +528 -25
- package/dist/lib/patterns/aws/computeEcsTypes.js +10 -0
- package/dist/lib/patterns/aws/computeLambda.d.ts +0 -5
- package/dist/lib/patterns/aws/computeLambda.js +1 -2
- package/dist/lib/patterns/aws/database.d.ts +50 -8
- package/dist/lib/patterns/aws/database.js +183 -27
- package/dist/lib/patterns/aws/domain.js +6 -4
- package/dist/lib/patterns/aws/index.d.ts +1 -0
- package/dist/lib/patterns/aws/index.js +1 -0
- package/dist/lib/patterns/aws/interfaces/compute.d.ts +7 -1
- package/dist/lib/patterns/aws/interfaces/database.d.ts +187 -8
- package/dist/lib/patterns/aws/interfaces/database.js +17 -3
- package/dist/lib/patterns/aws/interfaces/index.d.ts +2 -1
- package/dist/lib/patterns/aws/interfaces/index.js +3 -1
- package/dist/lib/patterns/aws/interfaces/messaging.d.ts +7 -0
- package/dist/lib/patterns/aws/interfaces/migrationContributor.d.ts +47 -0
- package/dist/lib/patterns/aws/interfaces/migrationContributor.js +9 -0
- package/dist/lib/patterns/aws/messaging.d.ts +66 -10
- package/dist/lib/patterns/aws/messaging.js +115 -20
- package/dist/lib/patterns/aws/network.js +16 -7
- package/dist/lib/patterns/aws/organisation.d.ts +4 -0
- package/dist/lib/patterns/aws/organisation.js +22 -4
- package/dist/lib/patterns/aws/storage.d.ts +1 -2
- package/dist/lib/patterns/aws/storage.js +3 -2
- package/dist/lib/patterns/aws/vpcPeer.js +3 -1
- package/dist/lib/resources/aws/analytics/clickhouse.js +18 -9
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.d.ts +24 -9
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.js +61 -10
- package/dist/lib/resources/aws/analytics/clickhouseConstants.d.ts +3 -3
- package/dist/lib/resources/aws/analytics/clickhouseConstants.js +3 -3
- package/dist/lib/resources/aws/analytics/clickhouseTypes.d.ts +7 -1
- package/dist/lib/resources/aws/analytics/clickhouseUserData.d.ts +1 -1
- package/dist/lib/resources/aws/analytics/clickhouseUserData.js +53 -3
- package/dist/lib/resources/aws/base/awsStack.js +4 -2
- package/dist/lib/resources/aws/compute/__tmp__/regression-shape.d.ts +2 -0
- package/dist/lib/resources/aws/compute/__tmp__/regression-shape.js +11 -0
- package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.d.ts +52 -0
- package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.js +60 -0
- package/dist/lib/resources/aws/compute/blockDeviceVolume.d.ts +8 -0
- package/dist/lib/resources/aws/compute/blockDeviceVolume.js +10 -0
- package/dist/lib/resources/aws/compute/ec2.d.ts +132 -12
- package/dist/lib/resources/aws/compute/ec2.js +163 -23
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.d.ts +41 -0
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.js +194 -0
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs +458 -0
- package/dist/lib/resources/aws/compute/ecs.d.ts +27 -1
- package/dist/lib/resources/aws/compute/ecs.js +42 -2
- package/dist/lib/resources/aws/compute/ecsConstants.d.ts +9 -0
- package/dist/lib/resources/aws/compute/ecsConstants.js +16 -0
- package/dist/lib/resources/aws/compute/ecsImages.js +32 -20
- package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.d.ts +96 -0
- package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.js +113 -0
- package/dist/lib/resources/aws/compute/ecsNetworking.d.ts +2 -1
- package/dist/lib/resources/aws/compute/ecsNetworking.js +18 -6
- package/dist/lib/resources/aws/compute/ecsServiceFactory.d.ts +13 -4
- package/dist/lib/resources/aws/compute/ecsServiceFactory.js +155 -33
- package/dist/lib/resources/aws/compute/ecsTaskDefinition.d.ts +31 -1
- package/dist/lib/resources/aws/compute/ecsTaskDefinition.js +102 -6
- package/dist/lib/resources/aws/compute/ecsTypes.d.ts +173 -13
- package/dist/lib/resources/aws/compute/ecsValidation.d.ts +9 -0
- package/dist/lib/resources/aws/compute/ecsValidation.js +63 -0
- package/dist/lib/resources/aws/compute/index.d.ts +2 -0
- package/dist/lib/resources/aws/compute/index.js +2 -0
- package/dist/lib/resources/aws/compute/lambda.d.ts +7 -13
- package/dist/lib/resources/aws/compute/lambda.js +30 -38
- package/dist/lib/resources/aws/compute/lifecycleHookLambda.source.cjs +192 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.d.ts +104 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.js +245 -0
- package/dist/lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs +398 -0
- package/dist/lib/resources/aws/compute/samApplication.d.ts +15 -0
- package/dist/lib/resources/aws/compute/samApplication.js +27 -0
- package/dist/lib/resources/aws/database/clickhouseConstants.d.ts +159 -0
- package/dist/lib/resources/aws/database/clickhouseConstants.js +181 -0
- package/dist/lib/resources/aws/database/clickhouseSchemas.d.ts +71 -0
- package/dist/lib/resources/aws/database/clickhouseSchemas.js +160 -0
- package/dist/lib/resources/aws/database/clickhouseSecurityGroup.d.ts +14 -0
- package/dist/lib/resources/aws/database/clickhouseSecurityGroup.js +23 -0
- package/dist/lib/resources/aws/database/clickhouseUserData.d.ts +69 -0
- package/dist/lib/resources/aws/database/clickhouseUserData.js +371 -0
- package/dist/lib/resources/aws/database/clickhouseXmlRenderer.d.ts +56 -0
- package/dist/lib/resources/aws/database/clickhouseXmlRenderer.js +112 -0
- package/dist/lib/resources/aws/database/rdsAurora.d.ts +8 -1
- package/dist/lib/resources/aws/database/rdsAurora.js +42 -32
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.d.ts +15 -2
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +39 -43
- package/dist/lib/resources/aws/database/rdsDefaults.d.ts +6 -0
- package/dist/lib/resources/aws/database/rdsDefaults.js +7 -1
- package/dist/lib/resources/aws/database/rdsHelpers.d.ts +3 -3
- package/dist/lib/resources/aws/database/rdsHelpers.js +1 -0
- package/dist/lib/resources/aws/database/rdsInstance.d.ts +8 -1
- package/dist/lib/resources/aws/database/rdsInstance.js +51 -34
- package/dist/lib/resources/aws/database/rdsProxyOutput.d.ts +1 -1
- package/dist/lib/resources/aws/database/rdsProxyOutput.js +1 -1
- package/dist/lib/resources/aws/iam/delegationRole.js +1 -1
- package/dist/lib/resources/aws/iam/identityCenter/groupMembership.d.ts +9 -0
- package/dist/lib/resources/aws/iam/identityCenter/groupMembership.js +12 -0
- package/dist/lib/resources/aws/iam/identityCenter/index.d.ts +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/index.js +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/permissionSet.d.ts +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/permissionSet.js +1 -0
- package/dist/lib/resources/aws/logging/logGroup.d.ts +0 -8
- package/dist/lib/resources/aws/logging/logGroup.js +0 -11
- package/dist/lib/resources/aws/messaging/defaultEventBus.d.ts +7 -0
- package/dist/lib/resources/aws/messaging/defaultEventBus.js +21 -0
- package/dist/lib/resources/aws/messaging/eventBridgeRule.d.ts +96 -0
- package/dist/lib/resources/aws/messaging/eventBridgeRule.js +110 -0
- package/dist/lib/resources/aws/messaging/eventTargets.d.ts +84 -0
- package/dist/lib/resources/aws/messaging/eventTargets.js +152 -0
- package/dist/lib/resources/aws/messaging/eventbridge.d.ts +25 -2
- package/dist/lib/resources/aws/messaging/eventbridge.js +22 -10
- package/dist/lib/resources/aws/messaging/index.d.ts +5 -0
- package/dist/lib/resources/aws/messaging/index.js +2 -0
- package/dist/lib/resources/aws/messaging/schedule.d.ts +118 -0
- package/dist/lib/resources/aws/messaging/schedule.js +64 -0
- package/dist/lib/resources/aws/messaging/sns.d.ts +2 -1
- package/dist/lib/resources/aws/messaging/sqs.d.ts +2 -1
- package/dist/lib/resources/aws/messaging/subscription.d.ts +112 -0
- package/dist/lib/resources/aws/messaging/subscription.js +67 -0
- package/dist/lib/resources/aws/messaging/utils.d.ts +6 -0
- package/dist/lib/resources/aws/messaging/utils.js +10 -0
- package/dist/lib/resources/aws/monitoring/clickhouseAlarms.d.ts +60 -0
- package/dist/lib/resources/aws/monitoring/clickhouseAlarms.js +139 -0
- package/dist/lib/resources/aws/monitoring/index.d.ts +2 -0
- package/dist/lib/resources/aws/monitoring/index.js +2 -0
- package/dist/lib/resources/aws/monitoring/scheduleAlarms.d.ts +47 -0
- package/dist/lib/resources/aws/monitoring/scheduleAlarms.js +106 -0
- package/dist/lib/resources/aws/networking/crossAccountDelegationRecord.js +6 -4
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.js +17 -13
- package/dist/lib/resources/aws/networking/dnsRecord/dnsRecordBase.js +7 -5
- package/dist/lib/resources/aws/networking/domainCertificate.d.ts +2 -2
- package/dist/lib/resources/aws/networking/domainCertificate.js +6 -4
- package/dist/lib/resources/aws/networking/hostedZone.js +6 -5
- package/dist/lib/resources/aws/networking/serviceDiscovery.d.ts +96 -0
- package/dist/lib/resources/aws/networking/serviceDiscovery.js +96 -0
- package/dist/lib/resources/aws/networking/vpc.d.ts +4 -1
- package/dist/lib/resources/aws/networking/vpc.js +4 -1
- package/dist/lib/resources/aws/networking/vpcPeeringConnection.js +21 -3
- package/dist/lib/resources/aws/organisation/costAllocationTagActivator.d.ts +16 -5
- package/dist/lib/resources/aws/organisation/costAllocationTagActivator.js +17 -3
- package/dist/lib/resources/aws/organisation/index.d.ts +1 -1
- package/dist/lib/resources/aws/organisation/organisationPolicy.d.ts +2 -0
- package/dist/lib/resources/aws/organisation/organisationPolicy.js +3 -2
- package/dist/lib/resources/aws/secrets/secret.d.ts +7 -0
- package/dist/lib/resources/aws/secrets/secret.js +4 -3
- package/dist/lib/resources/aws/storage/bucketDeployment.d.ts +16 -0
- package/dist/lib/resources/aws/storage/bucketDeployment.js +17 -0
- package/dist/lib/resources/aws/storage/ecr.js +5 -5
- package/dist/lib/resources/aws/storage/index.d.ts +1 -0
- package/dist/lib/resources/aws/storage/index.js +1 -0
- package/dist/lib/resources/aws/storage/s3.js +10 -3
- package/dist/lib/resources/aws/utilities/customResource.js +18 -9
- package/dist/lib/synth_dump.d.ts +1 -0
- package/dist/lib/synth_dump.js +42 -0
- package/dist/lib/utils/cdkContext.d.ts +2 -0
- package/dist/lib/utils/cdkContext.js +4 -2
- package/dist/lib/utils/connections.js +6 -0
- package/dist/lib/utils/connector.d.ts +12 -0
- package/dist/lib/utils/costAllocationTags.d.ts +9 -0
- package/dist/lib/utils/costAllocationTags.js +11 -1
- package/dist/lib/utils/databaseTypes.d.ts +14 -0
- package/dist/lib/utils/getConfig.d.ts +2 -0
- package/dist/lib/utils/getConfig.js +2 -0
- package/dist/lib/utils/index.d.ts +1 -0
- package/dist/lib/utils/index.js +1 -0
- package/dist/lib/utils/manifestWriter.d.ts +6 -89
- package/dist/lib/utils/manifestWriter.js +36 -23
- package/dist/lib/utils/migrationVersionResolvers.d.ts +2 -0
- package/dist/lib/utils/migrationVersionResolvers.js +2 -0
- package/dist/lib/utils/orgConfigParser.js +2 -1
- package/dist/lib/utils/resolveAlertsTopic.d.ts +14 -0
- package/dist/lib/utils/resolveAlertsTopic.js +30 -0
- package/dist/lib/utils/validationLogger.js +6 -3
- package/package.json +22 -19
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { CLICKHOUSE_DATA_MOUNT_PATH, CLICKHOUSE_EBS_DEVICE_NAME, CLICKHOUSE_CONFIG_SUBDIR, CLICKHOUSE_USERS_SUBDIR, CLICKHOUSE_HTTP_PORT, CLICKHOUSE_PROMETHEUS_PORT, clickHousePasswordSha256Snippet } from "./clickhouseConstants.js";
|
|
2
|
+
import { renderUsersXml } from "./clickhouseXmlRenderer.js";
|
|
3
|
+
export function generateServerConfigXml(options) {
|
|
4
|
+
const { backupBucketName, backupBucketRegion, coldTier } = options;
|
|
5
|
+
const storageBlock = coldTier !== undefined
|
|
6
|
+
? ` <storage_configuration>
|
|
7
|
+
<!-- Same CH 26 rule as the no-cold-tier branch: a <local_ssd> disk
|
|
8
|
+
whose path equals the global <path> trips UNKNOWN_ELEMENT_IN_CONFIG
|
|
9
|
+
at boot. Use the implicit <default> disk for hot tier; only S3
|
|
10
|
+
cold needs an explicit <disks> entry. -->
|
|
11
|
+
<disks>
|
|
12
|
+
<s3_cold>
|
|
13
|
+
<type>s3</type>
|
|
14
|
+
<endpoint>https://${coldTier.bucketName}.s3.${coldTier.region}.amazonaws.com/cold/</endpoint>
|
|
15
|
+
<use_environment_credentials>true</use_environment_credentials>
|
|
16
|
+
<metadata_path>/var/lib/clickhouse/disks/s3_cold/</metadata_path>
|
|
17
|
+
</s3_cold>
|
|
18
|
+
</disks>
|
|
19
|
+
<policies>
|
|
20
|
+
<tiered>
|
|
21
|
+
<volumes>
|
|
22
|
+
<hot>
|
|
23
|
+
<disk>default</disk>
|
|
24
|
+
</hot>
|
|
25
|
+
<cold>
|
|
26
|
+
<disk>s3_cold</disk>
|
|
27
|
+
</cold>
|
|
28
|
+
</volumes>
|
|
29
|
+
<move_factor>0.05</move_factor>
|
|
30
|
+
</tiered>
|
|
31
|
+
<local_only>
|
|
32
|
+
<volumes>
|
|
33
|
+
<default>
|
|
34
|
+
<disk>default</disk>
|
|
35
|
+
</default>
|
|
36
|
+
</volumes>
|
|
37
|
+
</local_only>
|
|
38
|
+
</policies>
|
|
39
|
+
</storage_configuration>`
|
|
40
|
+
: ` <storage_configuration>
|
|
41
|
+
<!-- CH 26.x reserves the implicit <default> disk and rejects any
|
|
42
|
+
explicit <disks><default>...</default></disks> override whose
|
|
43
|
+
resolved path equals the global <path>:
|
|
44
|
+
"Disk path ('/var/lib/clickhouse/') cannot be equal to <path>.
|
|
45
|
+
Use <default> disk instead. (UNKNOWN_ELEMENT_IN_CONFIG)"
|
|
46
|
+
So we drop the <disks> block entirely; policies referencing
|
|
47
|
+
<disk>default</disk> resolve to CH's built-in default. -->
|
|
48
|
+
<policies>
|
|
49
|
+
<!-- Single-volume tiered policy: 11 schema tables hardcode
|
|
50
|
+
storage_policy='tiered'. -->
|
|
51
|
+
<tiered>
|
|
52
|
+
<volumes>
|
|
53
|
+
<hot>
|
|
54
|
+
<disk>default</disk>
|
|
55
|
+
</hot>
|
|
56
|
+
</volumes>
|
|
57
|
+
</tiered>
|
|
58
|
+
<local_only>
|
|
59
|
+
<volumes>
|
|
60
|
+
<default>
|
|
61
|
+
<disk>default</disk>
|
|
62
|
+
</default>
|
|
63
|
+
</volumes>
|
|
64
|
+
</local_only>
|
|
65
|
+
</policies>
|
|
66
|
+
</storage_configuration>`;
|
|
67
|
+
const backupEndpointBlock = ` <s3>
|
|
68
|
+
<backup_endpoint>
|
|
69
|
+
<endpoint>https://${backupBucketName}.s3.${backupBucketRegion}.amazonaws.com/</endpoint>
|
|
70
|
+
<use_environment_credentials>true</use_environment_credentials>
|
|
71
|
+
</backup_endpoint>
|
|
72
|
+
</s3>`;
|
|
73
|
+
return `<clickhouse>
|
|
74
|
+
<logger>
|
|
75
|
+
<level>warning</level>
|
|
76
|
+
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
|
|
77
|
+
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
|
|
78
|
+
<size>100M</size>
|
|
79
|
+
<count>3</count>
|
|
80
|
+
<!-- Mirror to stderr so the awslogs driver captures startup +
|
|
81
|
+
crash banners. File-only logs die with the container. -->
|
|
82
|
+
<console>1</console>
|
|
83
|
+
</logger>
|
|
84
|
+
<!-- Bind to all IPv4 addresses. CH 26 defaults its listener set to
|
|
85
|
+
include \`[::1]\` (IPv6 loopback). Under awsvpc that fails because
|
|
86
|
+
the ENI has no IPv6 loopback assigned (errno 99 EADDRNOTAVAIL on
|
|
87
|
+
8123 / 9000 / 9004 / 9005 / 9009 / 9363); under host mode it would
|
|
88
|
+
work, but explicit beats implicit and keeps the listener identical
|
|
89
|
+
across network modes. -->
|
|
90
|
+
<listen_host>0.0.0.0</listen_host>
|
|
91
|
+
<!-- m7g.medium tuning philosophy: 1 vCPU sustained / 4 GB / 3 GB container.
|
|
92
|
+
Single-thread CPU has no headroom (raising max_threads beyond 1 just
|
|
93
|
+
oversubscribes the kernel scheduler), so we trade RAM for CPU — size
|
|
94
|
+
caches generously so dashboard reads hit cache rather than rescanning,
|
|
95
|
+
and let a single query use most of the budget if needed.
|
|
96
|
+
Re-tune these in lockstep when DEFAULT_CLICKHOUSE_INSTANCE_TYPE moves
|
|
97
|
+
to a larger box. -->
|
|
98
|
+
<!-- 0.75 ratio gives the kernel ~750 MB cushion on the 3 GB cgroup for
|
|
99
|
+
CH's untracked allocations (libc allocator, executable image, malloc
|
|
100
|
+
fragmentation, jemalloc virtual reservations on ARM64). The default
|
|
101
|
+
0.9 left only ~300 MB and OOM-killed the process at boot when cache
|
|
102
|
+
+ thread init pushed the cgroup over the limit (exit 137 in CW).
|
|
103
|
+
Computed at runtime from the cgroup limit so it tracks instance size
|
|
104
|
+
when DEFAULT_CLICKHOUSE_INSTANCE_TYPE moves to a larger box. -->
|
|
105
|
+
<max_server_memory_usage_to_ram_ratio>0.75</max_server_memory_usage_to_ram_ratio>
|
|
106
|
+
<!-- Per-query caps (max_memory_usage, max_bytes_before_external_sort,
|
|
107
|
+
max_bytes_before_external_group_by) live in the profile blocks of
|
|
108
|
+
users.xml — ClickHouse 26.3.10 rejects them at top level with
|
|
109
|
+
UNKNOWN_ELEMENT_IN_CONFIG. The default localhost user inherits
|
|
110
|
+
ClickHouse's built-in defaults; workload users (app_writer,
|
|
111
|
+
audit_writer, backup_reader, schema_admin) carry explicit caps. -->
|
|
112
|
+
<!-- 384 MB mark cache + 128 MB index mark cache. CH counts these against
|
|
113
|
+
max_server_memory_usage, so the read-cache footprint is 512 MB total
|
|
114
|
+
(~17% of the budget). On a single-tenant dashboard workload this
|
|
115
|
+
pays back fast — same queries repeat, mark hits avoid index re-scans. -->
|
|
116
|
+
<mark_cache_size>402653184</mark_cache_size>
|
|
117
|
+
<index_mark_cache_size>134217728</index_mark_cache_size>
|
|
118
|
+
<!-- Filesystem page cache handles uncompressed-block warmth on the
|
|
119
|
+
host side; an in-CH uncompressed cache would just duplicate it. -->
|
|
120
|
+
<uncompressed_cache_size>0</uncompressed_cache_size>
|
|
121
|
+
<!-- Sized for m7g.medium (1 vCPU sustained). 4 concurrent queries is the
|
|
122
|
+
sweet spot: enough headroom for the OPTIMIZE FINAL sidecar + a single
|
|
123
|
+
dashboard read + one async insert + one ad-hoc, but low enough that
|
|
124
|
+
context switching does not dominate at the kernel scheduler level.
|
|
125
|
+
Bump in lockstep with instance size if DEFAULT_CLICKHOUSE_INSTANCE_TYPE
|
|
126
|
+
moves to a >=2 vCPU host. -->
|
|
127
|
+
<max_concurrent_queries>4</max_concurrent_queries>
|
|
128
|
+
<background_pool_size>2</background_pool_size>
|
|
129
|
+
<background_schedule_pool_size>2</background_schedule_pool_size>
|
|
130
|
+
<background_merges_mutations_concurrency_ratio>2</background_merges_mutations_concurrency_ratio>
|
|
131
|
+
<background_move_pool_size>1</background_move_pool_size>
|
|
132
|
+
<background_fetches_pool_size>1</background_fetches_pool_size>
|
|
133
|
+
<background_message_broker_schedule_pool_size>1</background_message_broker_schedule_pool_size>
|
|
134
|
+
<merge_tree>
|
|
135
|
+
<max_suspicious_broken_parts>5</max_suspicious_broken_parts>
|
|
136
|
+
<parts_to_delay_insert>150</parts_to_delay_insert>
|
|
137
|
+
<parts_to_throw_insert>300</parts_to_throw_insert>
|
|
138
|
+
<!-- ClickHouse 26.3.10 sanity-checks the free-pool thresholds against
|
|
139
|
+
background_pool_size * background_merges_mutations_concurrency_ratio
|
|
140
|
+
(= 2 * 2 = 4 here). The defaults (20 / 8 / 25) all exceed 4 and
|
|
141
|
+
trip BAD_ARGUMENTS at startup on a 1 vCPU m7g.medium. Lower each
|
|
142
|
+
to 1 so a mutation/merge/optimise can begin as soon as one pool
|
|
143
|
+
slot is free — appropriate for the small instance footprint. -->
|
|
144
|
+
<number_of_free_entries_in_pool_to_execute_mutation>1</number_of_free_entries_in_pool_to_execute_mutation>
|
|
145
|
+
<number_of_free_entries_in_pool_to_lower_max_size_of_merge>1</number_of_free_entries_in_pool_to_lower_max_size_of_merge>
|
|
146
|
+
<number_of_free_entries_in_pool_to_execute_optimize_entire_partition>1</number_of_free_entries_in_pool_to_execute_optimize_entire_partition>
|
|
147
|
+
</merge_tree>
|
|
148
|
+
<http_port>${CLICKHOUSE_HTTP_PORT}</http_port>
|
|
149
|
+
<custom_settings_prefixes>current_</custom_settings_prefixes>
|
|
150
|
+
<!-- HTTP keep-alive window. Must exceed @clickhouse/client idle_socket_ttl (15 s)
|
|
151
|
+
so the client always closes the socket first. Prevents ECONNRESET on reuse. -->
|
|
152
|
+
<keep_alive_timeout>30</keep_alive_timeout>
|
|
153
|
+
<query_log>
|
|
154
|
+
<database>system</database>
|
|
155
|
+
<table>query_log</table>
|
|
156
|
+
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
157
|
+
<ttl>event_date + INTERVAL 14 DAY DELETE</ttl>
|
|
158
|
+
</query_log>
|
|
159
|
+
<!-- All system log tables need bounded retention on 80GB EBS (mirror query_log's 14-day policy). -->
|
|
160
|
+
<asynchronous_metric_log>
|
|
161
|
+
<database>system</database>
|
|
162
|
+
<table>asynchronous_metric_log</table>
|
|
163
|
+
<ttl>event_date + INTERVAL 14 DAY DELETE</ttl>
|
|
164
|
+
</asynchronous_metric_log>
|
|
165
|
+
<metric_log>
|
|
166
|
+
<database>system</database>
|
|
167
|
+
<table>metric_log</table>
|
|
168
|
+
<ttl>event_date + INTERVAL 14 DAY DELETE</ttl>
|
|
169
|
+
</metric_log>
|
|
170
|
+
<part_log>
|
|
171
|
+
<database>system</database>
|
|
172
|
+
<table>part_log</table>
|
|
173
|
+
<ttl>event_date + INTERVAL 14 DAY DELETE</ttl>
|
|
174
|
+
</part_log>
|
|
175
|
+
<error_log>
|
|
176
|
+
<database>system</database>
|
|
177
|
+
<table>error_log</table>
|
|
178
|
+
<ttl>event_date + INTERVAL 14 DAY DELETE</ttl>
|
|
179
|
+
</error_log>
|
|
180
|
+
${storageBlock}
|
|
181
|
+
${backupEndpointBlock}
|
|
182
|
+
<!-- 256 MB query cache. Single-tenant dashboard pattern means the same
|
|
183
|
+
queries repeat at fixed cadences (5/15min refresh, manual reloads);
|
|
184
|
+
a hit returns in microseconds instead of re-scanning. Sized generously
|
|
185
|
+
relative to other caches because the workload pattern is uniquely
|
|
186
|
+
cache-friendly. -->
|
|
187
|
+
<query_cache>
|
|
188
|
+
<max_size_in_bytes>268435456</max_size_in_bytes>
|
|
189
|
+
<max_entries>1024</max_entries>
|
|
190
|
+
<max_entry_size_in_bytes>1048576</max_entry_size_in_bytes>
|
|
191
|
+
</query_cache>
|
|
192
|
+
<prometheus>
|
|
193
|
+
<endpoint>/metrics</endpoint>
|
|
194
|
+
<port>${CLICKHOUSE_PROMETHEUS_PORT}</port>
|
|
195
|
+
<metrics>true</metrics>
|
|
196
|
+
<events>true</events>
|
|
197
|
+
<asynchronous_metrics>true</asynchronous_metrics>
|
|
198
|
+
</prometheus>
|
|
199
|
+
<query_thread_log remove="1"/>
|
|
200
|
+
<opentelemetry_span_log remove="1"/>
|
|
201
|
+
<processors_profile_log remove="1"/>
|
|
202
|
+
</clickhouse>`;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Construct-side thin wrapper around `renderUsersXml`. Always emits the
|
|
206
|
+
* prod shape: loopback-only `<default>` user, `from_env=` sha256 password
|
|
207
|
+
* directives. The container entrypoint wrapper (see
|
|
208
|
+
* `buildClickHouseEntrypointWrapper`) resolves the `USER_<NAME>_SHA256` env
|
|
209
|
+
* vars at server start from `sha256sum` of each ECS-injected plaintext.
|
|
210
|
+
*
|
|
211
|
+
* TODO secondary CIDRs: props.vpc.vpcCidrBlock returns only the primary CIDR.
|
|
212
|
+
* BYOC consumers with multi-CIDR VPCs need a per-CIDR `<ip>` emitter — see
|
|
213
|
+
* designs/2026-05-12-clickhouse-construct-leak-fixes.md § "Phase 1.5".
|
|
214
|
+
*/
|
|
215
|
+
export function generateUsersConfigXml(options) {
|
|
216
|
+
return renderUsersXml({
|
|
217
|
+
schemaAdmin: options.schemaAdmin,
|
|
218
|
+
profiles: options.profiles,
|
|
219
|
+
vpcCidr: options.vpcCidr,
|
|
220
|
+
defaultUserAccess: "loopback-only",
|
|
221
|
+
passwordSource: { mode: "from_env" }
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
// EC2 LaunchTemplate UserData is capped at 16,384 bytes; the pretty-printed
|
|
225
|
+
// source overflows once XML/bash comments are included.
|
|
226
|
+
function compactUserDataScript(script) {
|
|
227
|
+
return script
|
|
228
|
+
.replace(/<!--[\s\S]*?-->/g, "")
|
|
229
|
+
.split("\n")
|
|
230
|
+
.map((line) => {
|
|
231
|
+
const trimmed = line.replace(/\s+$/, "").replace(/^\s+/, "");
|
|
232
|
+
if (trimmed.startsWith("#") && !trimmed.startsWith("#!"))
|
|
233
|
+
return "";
|
|
234
|
+
return trimmed;
|
|
235
|
+
})
|
|
236
|
+
.filter((line, index, all) => line !== "" || (index > 0 && all[index - 1] !== ""))
|
|
237
|
+
.join("\n");
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Build the EC2 user-data script that bootstraps ClickHouse on the ASG instance.
|
|
241
|
+
*
|
|
242
|
+
* Per design D27 + D12: cold-storage and backups authenticate to S3 via IAM
|
|
243
|
+
* (the EC2 instance role's grants), not via env-var access keys. The rendered
|
|
244
|
+
* output contains zero `R2_*` / `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY`
|
|
245
|
+
* references — `<use_environment_credentials>true</use_environment_credentials>`
|
|
246
|
+
* tells ClickHouse to use the IMDS-derived credentials instead.
|
|
247
|
+
*/
|
|
248
|
+
export function buildClickHouseUserData(options) {
|
|
249
|
+
const serverConfigXml = generateServerConfigXml(options);
|
|
250
|
+
const script = `#!/bin/bash
|
|
251
|
+
set -euo pipefail
|
|
252
|
+
|
|
253
|
+
DEVICE="${CLICKHOUSE_EBS_DEVICE_NAME}"
|
|
254
|
+
MOUNT_POINT="${CLICKHOUSE_DATA_MOUNT_PATH}"
|
|
255
|
+
|
|
256
|
+
# Host kernel tuning for ClickHouse. Applied before the container starts so
|
|
257
|
+
# the settings are inherited via the docker daemon.
|
|
258
|
+
#
|
|
259
|
+
# 1. Transparent Huge Pages → madvise. ClickHouse explicitly recommends
|
|
260
|
+
# 'madvise' over 'always': 'always' triggers latency spikes from khugepaged
|
|
261
|
+
# rewriting hot pages; 'never' loses the THP win on large allocations
|
|
262
|
+
# (mark/group-by hash tables). 'madvise' is the documented sweet spot.
|
|
263
|
+
# https://clickhouse.com/docs/operations/tips#transparenthugepages
|
|
264
|
+
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled || true
|
|
265
|
+
echo madvise > /sys/kernel/mm/transparent_hugepage/defrag || true
|
|
266
|
+
|
|
267
|
+
# 2. Raise file-descriptor ceiling for the docker daemon (and therefore the
|
|
268
|
+
# CH container). CH's default config requests 500K+ FDs for distributed
|
|
269
|
+
# table caches, S3 backup readers, and per-tenant connection pools; the
|
|
270
|
+
# default 1024 ulimit causes 'too many open files' under load. Set the
|
|
271
|
+
# systemd override before docker starts so the limit is in place when the
|
|
272
|
+
# ECS agent launches the CH task.
|
|
273
|
+
mkdir -p /etc/systemd/system/docker.service.d
|
|
274
|
+
cat > /etc/systemd/system/docker.service.d/override.conf << 'DOCKEROVERRIDE'
|
|
275
|
+
[Service]
|
|
276
|
+
LimitNOFILE=1048576
|
|
277
|
+
LimitNPROC=unlimited
|
|
278
|
+
DOCKEROVERRIDE
|
|
279
|
+
systemctl daemon-reload
|
|
280
|
+
systemctl restart docker || true
|
|
281
|
+
|
|
282
|
+
# Wait for the EBS volume to be attached (up to 60 seconds)
|
|
283
|
+
for i in $(seq 1 60); do
|
|
284
|
+
if [ -b "$DEVICE" ]; then
|
|
285
|
+
break
|
|
286
|
+
fi
|
|
287
|
+
sleep 1
|
|
288
|
+
done
|
|
289
|
+
|
|
290
|
+
if [ ! -b "$DEVICE" ]; then
|
|
291
|
+
echo "ERROR: EBS volume $DEVICE not found after 60 seconds" >&2
|
|
292
|
+
exit 1
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
# Format only if not already formatted (idempotent)
|
|
296
|
+
if ! blkid "$DEVICE" | grep -q ext4; then
|
|
297
|
+
mkfs.ext4 -m 0 "$DEVICE"
|
|
298
|
+
fi
|
|
299
|
+
|
|
300
|
+
# Mount
|
|
301
|
+
mkdir -p "$MOUNT_POINT"
|
|
302
|
+
mount "$DEVICE" "$MOUNT_POINT"
|
|
303
|
+
|
|
304
|
+
# Persist across reboots
|
|
305
|
+
if ! grep -q "$MOUNT_POINT" /etc/fstab; then
|
|
306
|
+
echo "$DEVICE $MOUNT_POINT ext4 defaults,nofail 0 2" >> /etc/fstab
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
# Write ClickHouse server config (memory limits, storage policies, Prometheus)
|
|
310
|
+
mkdir -p "$MOUNT_POINT/${CLICKHOUSE_CONFIG_SUBDIR}"
|
|
311
|
+
cat > "$MOUNT_POINT/${CLICKHOUSE_CONFIG_SUBDIR}/fjall.xml" << 'CONFIGEOF'
|
|
312
|
+
${serverConfigXml}
|
|
313
|
+
CONFIGEOF
|
|
314
|
+
|
|
315
|
+
# Pull ClickHouse users config from S3 (BucketDeployment uploads it to
|
|
316
|
+
# s3://<backup-bucket>/config/users.d.xml at synth time). Retry up to 90×2s
|
|
317
|
+
# to absorb BucketDeployment Lambda cold-start (~60-120s observed).
|
|
318
|
+
mkdir -p "$MOUNT_POINT/${CLICKHOUSE_USERS_SUBDIR}"
|
|
319
|
+
USERS_CONFIG_RETRIEVED=0
|
|
320
|
+
for i in $(seq 1 90); do
|
|
321
|
+
if aws s3 cp "s3://${options.backupBucketName}/config/users.d.xml" \\
|
|
322
|
+
"$MOUNT_POINT/${CLICKHOUSE_USERS_SUBDIR}/fjall.xml.new" 2>/dev/null; then
|
|
323
|
+
mv "$MOUNT_POINT/${CLICKHOUSE_USERS_SUBDIR}/fjall.xml.new" \\
|
|
324
|
+
"$MOUNT_POINT/${CLICKHOUSE_USERS_SUBDIR}/fjall.xml"
|
|
325
|
+
USERS_CONFIG_RETRIEVED=1
|
|
326
|
+
break
|
|
327
|
+
fi
|
|
328
|
+
sleep 2
|
|
329
|
+
done
|
|
330
|
+
if [ "$USERS_CONFIG_RETRIEVED" != "1" ]; then
|
|
331
|
+
echo "ERROR: users.d/fjall.xml not retrieved from s3://${options.backupBucketName}/config/users.d.xml after 180s" >&2
|
|
332
|
+
exit 1
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
chown -R 101:101 "$MOUNT_POINT"
|
|
336
|
+
`;
|
|
337
|
+
return compactUserDataScript(script);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Build the bash wrapper executed as the CH container's entrypoint.
|
|
341
|
+
*
|
|
342
|
+
* The CH server reads `users.d/fjall.xml`, which carries
|
|
343
|
+
* `<password_sha256_hex from_env="USER_<NAME>_SHA256"/>` directives, and
|
|
344
|
+
* resolves those `from_env=` lookups against the server process's
|
|
345
|
+
* environment at startup. ECS injects the plaintext password for each user
|
|
346
|
+
* as `USER_<NAME>_PASSWORD` via `secretsImport`; this wrapper derives the
|
|
347
|
+
* matching `USER_<NAME>_SHA256` env var (via the same SHA-256 pipeline as
|
|
348
|
+
* the EC2 user-data loop in `buildClickHouseUserData()`) and then `exec`s
|
|
349
|
+
* the stock CH entrypoint so the server inherits the derived vars after
|
|
350
|
+
* the gosu privilege drop.
|
|
351
|
+
*
|
|
352
|
+
* Pure-bash iteration via `${!USER_@}` avoids spawning `env`/`grep` and
|
|
353
|
+
* guarantees only ECS-injected secrets are considered. The `case` filter
|
|
354
|
+
* skips any future `USER_*_HOST`/`USER_*_PORT` envs that don't match the
|
|
355
|
+
* password convention.
|
|
356
|
+
*/
|
|
357
|
+
export function buildClickHouseEntrypointWrapper() {
|
|
358
|
+
// `pipefail` so `printf | sha256sum | awk` aborts on mid-pipeline failure
|
|
359
|
+
// instead of exporting an empty hash; parity with the SSM live-reload script.
|
|
360
|
+
return `set -euo pipefail
|
|
361
|
+
for var in "\${!USER_@}"; do
|
|
362
|
+
case "$var" in
|
|
363
|
+
*_PASSWORD)
|
|
364
|
+
base=\${var%_PASSWORD}
|
|
365
|
+
hash=$(${clickHousePasswordSha256Snippet('"${!var}"')})
|
|
366
|
+
export "\${base}_SHA256=$hash"
|
|
367
|
+
;;
|
|
368
|
+
esac
|
|
369
|
+
done
|
|
370
|
+
exec /entrypoint.sh`;
|
|
371
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ClickHouseSchemaAdmin, ProfileSpec } from "./clickhouseSchemas.js";
|
|
2
|
+
/**
|
|
3
|
+
* Pure helper for rendering the `users.d/fjall.xml` ClickHouse users config.
|
|
4
|
+
*
|
|
5
|
+
* Two callers, two shapes:
|
|
6
|
+
* - **Prod** (construct): `passwordSource: { mode: "from_env" }`,
|
|
7
|
+
* `defaultUserAccess: "loopback-only"`. The XML emits
|
|
8
|
+
* `<password_sha256_hex from_env="USER_<NAME>_SHA256"/>` directives; the
|
|
9
|
+
* EC2 user-data resolves these from env vars set by computing `sha256sum`
|
|
10
|
+
* of each plaintext fetched from Secrets Manager at boot.
|
|
11
|
+
* - **Dev** (gen-script): `passwordSource: { mode: "literal-hashes", hashes }`,
|
|
12
|
+
* `defaultUserAccess: "permissive"`. The XML embeds the pre-computed
|
|
13
|
+
* sha256 hex literally; the `<default>` user accepts RFC1918 + loopback so
|
|
14
|
+
* docker-compose sidecars on the bridge network can authenticate.
|
|
15
|
+
*
|
|
16
|
+
* Only the schema-admin user is emitted into the XML — managed-password
|
|
17
|
+
* workload users are created at runtime by the migration helper and bind
|
|
18
|
+
* their profiles via customer SQL. The schema admin's profile is bound here,
|
|
19
|
+
* in the XML, because it must be live before any SQL runs.
|
|
20
|
+
*/
|
|
21
|
+
export interface RenderUsersXmlOptions {
|
|
22
|
+
schemaAdmin: ClickHouseSchemaAdmin;
|
|
23
|
+
profiles: Record<string, ProfileSpec>;
|
|
24
|
+
/**
|
|
25
|
+
* Primary VPC CIDR block — emitted into the schema admin's `<networks><ip>`.
|
|
26
|
+
* In prod the construct passes `props.vpc.vpcCidrBlock` (a CDK Token that
|
|
27
|
+
* resolves at deploy time); in dev the gen-script passes `"0.0.0.0/0"`
|
|
28
|
+
* because dev access is gated by `defaultUserAccess: "permissive"` on the
|
|
29
|
+
* `<default>` user.
|
|
30
|
+
*/
|
|
31
|
+
vpcCidr: string;
|
|
32
|
+
defaultUserAccess: "loopback-only" | "permissive";
|
|
33
|
+
passwordSource: {
|
|
34
|
+
mode: "from_env";
|
|
35
|
+
} | {
|
|
36
|
+
mode: "literal-hashes";
|
|
37
|
+
hashes: Record<string, string>;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Pure renderer. Validates that `schemaAdmin.profile` exists in `profiles`,
|
|
42
|
+
* and (in literal-hashes mode) that the schema admin has a hash entry. No
|
|
43
|
+
* CDK dependency — the construct passes `vpc.vpcCidrBlock` as a string-valued
|
|
44
|
+
* Token that resolves through CFN at deploy time.
|
|
45
|
+
*
|
|
46
|
+
* **Schema-admin-only emission.** Only the schema admin lands in the XML.
|
|
47
|
+
* Managed-password workload users are created at runtime by the migration
|
|
48
|
+
* helper (`@fjall/clickhouse-migrations § provisionUsersFromEnv`) — they
|
|
49
|
+
* authenticate via plaintext from `USER_<NAME>_PASSWORD` env vars at runtime
|
|
50
|
+
* and bind their profiles via customer SQL.
|
|
51
|
+
*
|
|
52
|
+
* Quotas are SQL-managed. No `<quotas>` block is emitted — the schema admin
|
|
53
|
+
* references CH's built-in `default` quota at boot; SQL-defined quotas take
|
|
54
|
+
* over post-migration.
|
|
55
|
+
*/
|
|
56
|
+
export declare function renderUsersXml(opts: RenderUsersXmlOptions): string;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
function camelToSnakeCase(input) {
|
|
2
|
+
return input.replace(/[A-Z]/g, (m) => "_" + m.toLowerCase());
|
|
3
|
+
}
|
|
4
|
+
function renderProfileSpec(spec) {
|
|
5
|
+
const lines = [];
|
|
6
|
+
for (const [key, value] of Object.entries(spec)) {
|
|
7
|
+
if (value === undefined)
|
|
8
|
+
continue;
|
|
9
|
+
const xmlName = camelToSnakeCase(key);
|
|
10
|
+
const xmlValue = typeof value === "boolean" ? (value ? "1" : "0") : String(value);
|
|
11
|
+
lines.push(` <${xmlName}>${xmlValue}</${xmlName}>`);
|
|
12
|
+
}
|
|
13
|
+
return lines.join("\n");
|
|
14
|
+
}
|
|
15
|
+
function renderDefaultUserBlock(access) {
|
|
16
|
+
if (access === "loopback-only") {
|
|
17
|
+
return ` <default>
|
|
18
|
+
<networks>
|
|
19
|
+
<ip>127.0.0.1</ip>
|
|
20
|
+
<ip>::1</ip>
|
|
21
|
+
</networks>
|
|
22
|
+
</default>`;
|
|
23
|
+
}
|
|
24
|
+
return ` <default>
|
|
25
|
+
<password></password>
|
|
26
|
+
<networks>
|
|
27
|
+
<ip>127.0.0.1</ip>
|
|
28
|
+
<ip>::1</ip>
|
|
29
|
+
<ip>172.16.0.0/12</ip>
|
|
30
|
+
<ip>10.0.0.0/8</ip>
|
|
31
|
+
<ip>192.168.0.0/16</ip>
|
|
32
|
+
</networks>
|
|
33
|
+
<access_management>1</access_management>
|
|
34
|
+
</default>`;
|
|
35
|
+
}
|
|
36
|
+
function renderPasswordElement(name, passwordSource) {
|
|
37
|
+
if (passwordSource.mode === "from_env") {
|
|
38
|
+
const envName = `USER_${name.toUpperCase()}_SHA256`;
|
|
39
|
+
return `<password_sha256_hex from_env="${envName}"/>`;
|
|
40
|
+
}
|
|
41
|
+
const hash = passwordSource.hashes[name];
|
|
42
|
+
if (hash === undefined) {
|
|
43
|
+
throw new Error(`renderUsersXml: literal-hashes mode missing hash for user '${name}'`);
|
|
44
|
+
}
|
|
45
|
+
return `<password_sha256_hex>${hash}</password_sha256_hex>`;
|
|
46
|
+
}
|
|
47
|
+
function renderSchemaAdminBlock(schemaAdmin, vpcCidr, passwordSource) {
|
|
48
|
+
const passwordElement = renderPasswordElement(schemaAdmin.name, passwordSource);
|
|
49
|
+
return ` <${schemaAdmin.name}>
|
|
50
|
+
${passwordElement}
|
|
51
|
+
<networks>
|
|
52
|
+
<ip>${vpcCidr}</ip>
|
|
53
|
+
</networks>
|
|
54
|
+
<profile>${schemaAdmin.profile}</profile>
|
|
55
|
+
<quota>default</quota>
|
|
56
|
+
<access_management>1</access_management>
|
|
57
|
+
<named_collection_control>1</named_collection_control>
|
|
58
|
+
<show_named_collections>1</show_named_collections>
|
|
59
|
+
<show_named_collections_secrets>1</show_named_collections_secrets>
|
|
60
|
+
</${schemaAdmin.name}>`;
|
|
61
|
+
}
|
|
62
|
+
function renderProfileBlock(name, spec) {
|
|
63
|
+
const body = renderProfileSpec(spec);
|
|
64
|
+
return ` <${name}>
|
|
65
|
+
${body}
|
|
66
|
+
</${name}>`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Pure renderer. Validates that `schemaAdmin.profile` exists in `profiles`,
|
|
70
|
+
* and (in literal-hashes mode) that the schema admin has a hash entry. No
|
|
71
|
+
* CDK dependency — the construct passes `vpc.vpcCidrBlock` as a string-valued
|
|
72
|
+
* Token that resolves through CFN at deploy time.
|
|
73
|
+
*
|
|
74
|
+
* **Schema-admin-only emission.** Only the schema admin lands in the XML.
|
|
75
|
+
* Managed-password workload users are created at runtime by the migration
|
|
76
|
+
* helper (`@fjall/clickhouse-migrations § provisionUsersFromEnv`) — they
|
|
77
|
+
* authenticate via plaintext from `USER_<NAME>_PASSWORD` env vars at runtime
|
|
78
|
+
* and bind their profiles via customer SQL.
|
|
79
|
+
*
|
|
80
|
+
* Quotas are SQL-managed. No `<quotas>` block is emitted — the schema admin
|
|
81
|
+
* references CH's built-in `default` quota at boot; SQL-defined quotas take
|
|
82
|
+
* over post-migration.
|
|
83
|
+
*/
|
|
84
|
+
export function renderUsersXml(opts) {
|
|
85
|
+
if (!(opts.schemaAdmin.profile in opts.profiles)) {
|
|
86
|
+
throw new Error(`renderUsersXml: schemaAdmin '${opts.schemaAdmin.name}' references unknown profile '${opts.schemaAdmin.profile}'. ` +
|
|
87
|
+
`Known profiles: ${Object.keys(opts.profiles).join(", ")}`);
|
|
88
|
+
}
|
|
89
|
+
const defaultBlock = renderDefaultUserBlock(opts.defaultUserAccess);
|
|
90
|
+
const adminBlock = renderSchemaAdminBlock(opts.schemaAdmin, opts.vpcCidr, opts.passwordSource);
|
|
91
|
+
const defaultProfileBlock = ` <default>
|
|
92
|
+
<optimize_move_to_prewhere>1</optimize_move_to_prewhere>
|
|
93
|
+
<!-- ALTER TABLE ... MODIFY TTL on a 30-day-partitioned table would otherwise
|
|
94
|
+
trigger an immediate full-table rewrite (default = 1). On the m7g.medium
|
|
95
|
+
box that's a merge-pool starvation event. Keep TTL changes lazy: parts
|
|
96
|
+
re-evaluate TTL on their next natural merge, no forced rewrite. -->
|
|
97
|
+
<materialize_ttl_after_modify>0</materialize_ttl_after_modify>
|
|
98
|
+
</default>`;
|
|
99
|
+
const profileBlocks = Object.entries(opts.profiles)
|
|
100
|
+
.map(([name, spec]) => renderProfileBlock(name, spec))
|
|
101
|
+
.join("\n");
|
|
102
|
+
return `<clickhouse>
|
|
103
|
+
<users>
|
|
104
|
+
${defaultBlock}
|
|
105
|
+
${adminBlock}
|
|
106
|
+
</users>
|
|
107
|
+
<profiles>
|
|
108
|
+
${defaultProfileBlock}
|
|
109
|
+
${profileBlocks}
|
|
110
|
+
</profiles>
|
|
111
|
+
</clickhouse>`;
|
|
112
|
+
}
|
|
@@ -5,7 +5,7 @@ import { Construct } from "constructs";
|
|
|
5
5
|
import { Secret } from "../secrets/index.js";
|
|
6
6
|
import type { ITopic } from "aws-cdk-lib/aws-sns";
|
|
7
7
|
import { type RdsAlarmThresholds } from "../monitoring/index.js";
|
|
8
|
-
import { type EngineConfig, type ProxyConfig, type CredentialsConfig, type AuroraEncryptionConfig, type AuroraWriterConfig, type AuroraReadersConfig, type DatabaseInsightsConfig } from "../../../utils/databaseTypes.js";
|
|
8
|
+
import { type EngineConfig, type ProxyConfig, type CredentialsConfig, type AuroraEncryptionConfig, type AuroraWriterConfig, type AuroraReadersConfig, type DatabaseInsightsConfig, type SnapshotTarget } from "../../../utils/databaseTypes.js";
|
|
9
9
|
interface RdsProps {
|
|
10
10
|
vpc: IVpc;
|
|
11
11
|
databaseName?: string;
|
|
@@ -61,6 +61,7 @@ export declare class RdsAurora extends Construct implements IConnectable {
|
|
|
61
61
|
private databaseProxy?;
|
|
62
62
|
private databaseCredentials;
|
|
63
63
|
private cfnCluster?;
|
|
64
|
+
private databaseNameValue;
|
|
64
65
|
constructor(scope: Construct, id: string, props: RdsProps);
|
|
65
66
|
private buildReaders;
|
|
66
67
|
private addProxy;
|
|
@@ -68,6 +69,12 @@ export declare class RdsAurora extends Construct implements IConnectable {
|
|
|
68
69
|
getHostEndpoint(): string;
|
|
69
70
|
getHostPort(): string;
|
|
70
71
|
getCredentials(): Secret;
|
|
72
|
+
getClusterIdentifier(): string;
|
|
73
|
+
getSnapshotTarget(): Extract<SnapshotTarget, {
|
|
74
|
+
kind: "cluster";
|
|
75
|
+
}>;
|
|
76
|
+
getDatabaseName(): string;
|
|
77
|
+
getConnectionString(): string;
|
|
71
78
|
getCfnCluster(): CfnDBCluster | undefined;
|
|
72
79
|
getDatabaseCluster(): DatabaseCluster;
|
|
73
80
|
}
|