@jaypie/constructs 1.1.48 → 1.1.50
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/JaypieApiGateway.d.ts +1 -0
- package/dist/cjs/JaypieBucketQueuedLambda.d.ts +4 -19
- package/dist/cjs/JaypieDnsRecord.d.ts +45 -0
- package/dist/cjs/JaypieGitHubDeployRole.d.ts +15 -0
- package/dist/cjs/JaypieHostedZone.d.ts +26 -4
- package/dist/cjs/JaypieLambda.d.ts +1 -1
- package/dist/cjs/JaypieQueuedLambda.d.ts +1 -1
- package/dist/cjs/JaypieSsoPermissions.d.ts +95 -0
- package/dist/cjs/JaypieSsoSyncApplication.d.ts +27 -0
- package/dist/cjs/JaypieWebDeploymentBucket.d.ts +1 -0
- package/dist/cjs/__tests__/JaypieSsoSyncApplication.spec.d.ts +1 -0
- package/dist/cjs/helpers/__tests__/resolveDatadogForwarderFunction.spec.d.ts +1 -0
- package/dist/cjs/helpers/__tests__/resolveDatadogLoggingDestination.spec.d.ts +1 -0
- package/dist/cjs/helpers/index.d.ts +2 -0
- package/dist/cjs/helpers/resolveDatadogForwarderFunction.d.ts +7 -0
- package/dist/cjs/helpers/resolveDatadogLoggingDestination.d.ts +4 -0
- package/dist/cjs/index.cjs +599 -308
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +6 -2
- package/dist/esm/JaypieApiGateway.d.ts +1 -0
- package/dist/esm/JaypieBucketQueuedLambda.d.ts +4 -19
- package/dist/esm/JaypieDnsRecord.d.ts +45 -0
- package/dist/esm/JaypieGitHubDeployRole.d.ts +15 -0
- package/dist/esm/JaypieHostedZone.d.ts +26 -4
- package/dist/esm/JaypieLambda.d.ts +1 -1
- package/dist/esm/JaypieQueuedLambda.d.ts +1 -1
- package/dist/esm/JaypieSsoPermissions.d.ts +95 -0
- package/dist/esm/JaypieSsoSyncApplication.d.ts +27 -0
- package/dist/esm/JaypieWebDeploymentBucket.d.ts +1 -0
- package/dist/esm/__tests__/JaypieDnsRecord.spec.d.ts +1 -0
- package/dist/esm/__tests__/JaypieSsoPermissions.spec.d.ts +1 -0
- package/dist/esm/__tests__/JaypieSsoSyncApplication.spec.d.ts +1 -0
- package/dist/esm/helpers/__tests__/resolveDatadogForwarderFunction.spec.d.ts +1 -0
- package/dist/esm/helpers/__tests__/resolveDatadogLoggingDestination.spec.d.ts +1 -0
- package/dist/esm/helpers/index.d.ts +2 -0
- package/dist/esm/helpers/resolveDatadogForwarderFunction.d.ts +7 -0
- package/dist/esm/helpers/resolveDatadogLoggingDestination.d.ts +4 -0
- package/dist/esm/index.d.ts +6 -2
- package/dist/esm/index.js +592 -309
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -2
- package/dist/cjs/JaypieSsoGroups.d.ts +0 -121
- package/dist/esm/JaypieSsoGroups.d.ts +0 -121
- /package/dist/cjs/__tests__/{JaypieSsoGroups.spec.d.ts → JaypieDnsRecord.spec.d.ts} +0 -0
- /package/dist/{esm/__tests__/JaypieSsoGroups.spec.d.ts → cjs/__tests__/JaypieSsoPermissions.spec.d.ts} +0 -0
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var cdk = require('@jaypie/cdk');
|
|
3
4
|
var constructs = require('constructs');
|
|
4
5
|
var cdk$1 = require('aws-cdk-lib');
|
|
5
6
|
var acm = require('aws-cdk-lib/aws-certificatemanager');
|
|
6
7
|
var apiGateway = require('aws-cdk-lib/aws-apigateway');
|
|
7
8
|
var route53 = require('aws-cdk-lib/aws-route53');
|
|
8
9
|
var route53Targets = require('aws-cdk-lib/aws-route53-targets');
|
|
9
|
-
var cdk = require('@jaypie/cdk');
|
|
10
10
|
var secretsmanager = require('aws-cdk-lib/aws-secretsmanager');
|
|
11
11
|
var datadogCdkConstructsV2 = require('datadog-cdk-constructs-v2');
|
|
12
12
|
var lambda = require('aws-cdk-lib/aws-lambda');
|
|
13
|
+
var logDestinations = require('aws-cdk-lib/aws-logs-destinations');
|
|
13
14
|
var s3 = require('aws-cdk-lib/aws-s3');
|
|
14
15
|
var s3n = require('aws-cdk-lib/aws-s3-notifications');
|
|
15
16
|
var sqs = require('aws-cdk-lib/aws-sqs');
|
|
16
17
|
var lambdaEventSources = require('aws-cdk-lib/aws-lambda-event-sources');
|
|
17
18
|
var awsIam = require('aws-cdk-lib/aws-iam');
|
|
18
19
|
var awsLogs = require('aws-cdk-lib/aws-logs');
|
|
19
|
-
var
|
|
20
|
+
var awsSso = require('aws-cdk-lib/aws-sso');
|
|
21
|
+
var awsSam = require('aws-cdk-lib/aws-sam');
|
|
22
|
+
var errors = require('@jaypie/errors');
|
|
20
23
|
var cloudfront = require('aws-cdk-lib/aws-cloudfront');
|
|
21
24
|
var origins = require('aws-cdk-lib/aws-cloudfront-origins');
|
|
22
25
|
|
|
@@ -44,11 +47,11 @@ var route53__namespace = /*#__PURE__*/_interopNamespaceDefault(route53);
|
|
|
44
47
|
var route53Targets__namespace = /*#__PURE__*/_interopNamespaceDefault(route53Targets);
|
|
45
48
|
var secretsmanager__namespace = /*#__PURE__*/_interopNamespaceDefault(secretsmanager);
|
|
46
49
|
var lambda__namespace = /*#__PURE__*/_interopNamespaceDefault(lambda);
|
|
50
|
+
var logDestinations__namespace = /*#__PURE__*/_interopNamespaceDefault(logDestinations);
|
|
47
51
|
var s3__namespace = /*#__PURE__*/_interopNamespaceDefault(s3);
|
|
48
52
|
var s3n__namespace = /*#__PURE__*/_interopNamespaceDefault(s3n);
|
|
49
53
|
var sqs__namespace = /*#__PURE__*/_interopNamespaceDefault(sqs);
|
|
50
54
|
var lambdaEventSources__namespace = /*#__PURE__*/_interopNamespaceDefault(lambdaEventSources);
|
|
51
|
-
var sso__namespace = /*#__PURE__*/_interopNamespaceDefault(sso);
|
|
52
55
|
var cloudfront__namespace = /*#__PURE__*/_interopNamespaceDefault(cloudfront);
|
|
53
56
|
var origins__namespace = /*#__PURE__*/_interopNamespaceDefault(origins);
|
|
54
57
|
|
|
@@ -247,6 +250,33 @@ function jaypieLambdaEnv(options = {}) {
|
|
|
247
250
|
return environment;
|
|
248
251
|
}
|
|
249
252
|
|
|
253
|
+
const DEFAULT_FUNCTION_NAME$1 = "DatadogForwarderFunction";
|
|
254
|
+
// Cache to store resolved functions
|
|
255
|
+
// Using nested structure to support multiple functions per scope with automatic GC
|
|
256
|
+
const functionCache = new WeakMap();
|
|
257
|
+
function resolveDatadogForwarderFunction(scope, options) {
|
|
258
|
+
const { import: importValue, name } = options || {};
|
|
259
|
+
const functionName = name || DEFAULT_FUNCTION_NAME$1;
|
|
260
|
+
const importKey = importValue || cdk.CDK.IMPORT.DATADOG_LOG_FORWARDER;
|
|
261
|
+
// Create a cache key based on name and import
|
|
262
|
+
const cacheKey = `${functionName}:${importKey}`;
|
|
263
|
+
// Get or create scope cache
|
|
264
|
+
let scopeCache = functionCache.get(scope);
|
|
265
|
+
if (!scopeCache) {
|
|
266
|
+
scopeCache = new Map();
|
|
267
|
+
functionCache.set(scope, scopeCache);
|
|
268
|
+
}
|
|
269
|
+
// Return cached function if it exists
|
|
270
|
+
const cachedFunction = scopeCache.get(cacheKey);
|
|
271
|
+
if (cachedFunction) {
|
|
272
|
+
return cachedFunction;
|
|
273
|
+
}
|
|
274
|
+
// Create and cache the function
|
|
275
|
+
const func = lambda__namespace.Function.fromFunctionArn(scope, functionName, cdk__namespace.Fn.importValue(importKey));
|
|
276
|
+
scopeCache.set(cacheKey, func);
|
|
277
|
+
return func;
|
|
278
|
+
}
|
|
279
|
+
|
|
250
280
|
function resolveDatadogLayers(scope, options = {}) {
|
|
251
281
|
const { datadogApiKeyArn, uniqueId } = options;
|
|
252
282
|
let resolvedRegion = cdk$1.Stack.of(scope).region || "us-east-1";
|
|
@@ -266,6 +296,35 @@ function resolveDatadogLayers(scope, options = {}) {
|
|
|
266
296
|
return [datadogNodeLayer, datadogExtensionLayer];
|
|
267
297
|
}
|
|
268
298
|
|
|
299
|
+
const DEFAULT_FUNCTION_NAME = "DatadogForwarderFunction";
|
|
300
|
+
// Cache to store resolved logging destinations
|
|
301
|
+
// Using nested structure to support multiple destinations per scope with automatic GC
|
|
302
|
+
const destinationCache = new WeakMap();
|
|
303
|
+
function resolveDatadogLoggingDestination(scope, options) {
|
|
304
|
+
const { import: importValue, name } = options || {};
|
|
305
|
+
// Create a cache key based on name and import (same as forwarder function)
|
|
306
|
+
const functionName = name || DEFAULT_FUNCTION_NAME;
|
|
307
|
+
const importKey = importValue || cdk.CDK.IMPORT.DATADOG_LOG_FORWARDER;
|
|
308
|
+
const cacheKey = `${functionName}:${importKey}`;
|
|
309
|
+
// Get or create scope cache
|
|
310
|
+
let scopeCache = destinationCache.get(scope);
|
|
311
|
+
if (!scopeCache) {
|
|
312
|
+
scopeCache = new Map();
|
|
313
|
+
destinationCache.set(scope, scopeCache);
|
|
314
|
+
}
|
|
315
|
+
// Return cached destination if it exists
|
|
316
|
+
const cachedDestination = scopeCache.get(cacheKey);
|
|
317
|
+
if (cachedDestination) {
|
|
318
|
+
return cachedDestination;
|
|
319
|
+
}
|
|
320
|
+
// Resolve the Datadog forwarder function
|
|
321
|
+
const datadogForwarderFunction = resolveDatadogForwarderFunction(scope, options);
|
|
322
|
+
// Create and cache the logging destination
|
|
323
|
+
const datadogLoggingDestination = new logDestinations__namespace.LambdaDestination(datadogForwarderFunction);
|
|
324
|
+
scopeCache.set(cacheKey, datadogLoggingDestination);
|
|
325
|
+
return datadogLoggingDestination;
|
|
326
|
+
}
|
|
327
|
+
|
|
269
328
|
function resolveHostedZone(scope, { name = "HostedZone", zone = process.env.CDK_ENV_HOSTED_ZONE, } = {}) {
|
|
270
329
|
if (!zone) {
|
|
271
330
|
throw new cdk.ConfigurationError("No `zone` provided. Set CDK_ENV_HOSTED_ZONE to use environment zone");
|
|
@@ -439,6 +498,11 @@ class JaypieApiGateway extends constructs.Construct {
|
|
|
439
498
|
applyRemovalPolicy(policy) {
|
|
440
499
|
this._api.applyRemovalPolicy(policy);
|
|
441
500
|
}
|
|
501
|
+
get restApiRef() {
|
|
502
|
+
return {
|
|
503
|
+
restApiId: this._api.restApiId,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
442
506
|
}
|
|
443
507
|
|
|
444
508
|
class JaypieStack extends cdk$1.Stack {
|
|
@@ -620,7 +684,10 @@ class JaypieLambda extends constructs.Construct {
|
|
|
620
684
|
return this._reference.resourceArnsForGrantInvoke;
|
|
621
685
|
}
|
|
622
686
|
get functionRef() {
|
|
623
|
-
return
|
|
687
|
+
return {
|
|
688
|
+
functionArn: this._reference.functionArn,
|
|
689
|
+
functionName: this._reference.functionName,
|
|
690
|
+
};
|
|
624
691
|
}
|
|
625
692
|
addEventSource(source) {
|
|
626
693
|
this._reference.addEventSource(source);
|
|
@@ -982,7 +1049,7 @@ class JaypieBucketQueuedLambda extends JaypieQueuedLambda {
|
|
|
982
1049
|
get policy() {
|
|
983
1050
|
return this._bucket.policy;
|
|
984
1051
|
}
|
|
985
|
-
addEventNotification(event, dest, filters) {
|
|
1052
|
+
addEventNotification(event, dest, ...filters) {
|
|
986
1053
|
this._bucket.addEventNotification(event, dest, ...filters);
|
|
987
1054
|
}
|
|
988
1055
|
addObjectCreatedNotification(dest, ...filters) {
|
|
@@ -1000,9 +1067,6 @@ class JaypieBucketQueuedLambda extends JaypieQueuedLambda {
|
|
|
1000
1067
|
enableEventBridgeNotification() {
|
|
1001
1068
|
this._bucket.enableEventBridgeNotification();
|
|
1002
1069
|
}
|
|
1003
|
-
grant(grantee, ...actions) {
|
|
1004
|
-
return this._bucket.grant(grantee, ...actions);
|
|
1005
|
-
}
|
|
1006
1070
|
grantDelete(grantee, objectsKeyPattern) {
|
|
1007
1071
|
return this._bucket.grantDelete(grantee, objectsKeyPattern);
|
|
1008
1072
|
}
|
|
@@ -1045,54 +1109,17 @@ class JaypieBucketQueuedLambda extends JaypieQueuedLambda {
|
|
|
1045
1109
|
virtualHostedUrlForObject(key, options) {
|
|
1046
1110
|
return this._bucket.virtualHostedUrlForObject(key, options);
|
|
1047
1111
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
return this._bucket.metricAllRequests(props);
|
|
1051
|
-
}
|
|
1052
|
-
metricBucketSizeBytes(props) {
|
|
1053
|
-
return this._bucket.metricBucketSizeBytes(props);
|
|
1054
|
-
}
|
|
1055
|
-
metricDeleteRequests(props) {
|
|
1056
|
-
return this._bucket.metricDeleteRequests(props);
|
|
1057
|
-
}
|
|
1058
|
-
metricDownloadBytes(props) {
|
|
1059
|
-
return this._bucket.metricDownloadBytes(props);
|
|
1060
|
-
}
|
|
1061
|
-
metricFirstByteLatency(props) {
|
|
1062
|
-
return this._bucket.metricFirstByteLatency(props);
|
|
1063
|
-
}
|
|
1064
|
-
metricGetRequests(props) {
|
|
1065
|
-
return this._bucket.metricGetRequests(props);
|
|
1066
|
-
}
|
|
1067
|
-
metricHeadRequests(props) {
|
|
1068
|
-
return this._bucket.metricHeadRequests(props);
|
|
1069
|
-
}
|
|
1070
|
-
metricHttpRequests(props) {
|
|
1071
|
-
return this._bucket.metricHttpRequests(props);
|
|
1072
|
-
}
|
|
1073
|
-
metricListRequests(props) {
|
|
1074
|
-
return this._bucket.metricListRequests(props);
|
|
1075
|
-
}
|
|
1076
|
-
metricNumberOfObjects(props) {
|
|
1077
|
-
return this._bucket.metricNumberOfObjects(props);
|
|
1078
|
-
}
|
|
1079
|
-
metricPostRequests(props) {
|
|
1080
|
-
return this._bucket.metricPostRequests(props);
|
|
1081
|
-
}
|
|
1082
|
-
metricPutRequests(props) {
|
|
1083
|
-
return this._bucket.metricPutRequests(props);
|
|
1084
|
-
}
|
|
1085
|
-
metricSelectRequests(props) {
|
|
1086
|
-
return this._bucket.metricSelectRequests(props);
|
|
1087
|
-
}
|
|
1088
|
-
metricSelectScannedBytes(props) {
|
|
1089
|
-
return this._bucket.metricSelectScannedBytes(props);
|
|
1112
|
+
grantReplicationPermission(identity, props) {
|
|
1113
|
+
return this._bucket.grantReplicationPermission(identity, props);
|
|
1090
1114
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1115
|
+
addReplicationPolicy(policy) {
|
|
1116
|
+
this._bucket.addReplicationPolicy(policy);
|
|
1093
1117
|
}
|
|
1094
|
-
|
|
1095
|
-
return
|
|
1118
|
+
get bucketRef() {
|
|
1119
|
+
return {
|
|
1120
|
+
bucketArn: this._bucket.bucketArn,
|
|
1121
|
+
bucketName: this._bucket.bucketName,
|
|
1122
|
+
};
|
|
1096
1123
|
}
|
|
1097
1124
|
// Override applyRemovalPolicy to apply to all resources
|
|
1098
1125
|
applyRemovalPolicy(policy) {
|
|
@@ -1246,6 +1273,164 @@ class JaypieDatadogSecret extends JaypieEnvSecret {
|
|
|
1246
1273
|
}
|
|
1247
1274
|
}
|
|
1248
1275
|
|
|
1276
|
+
class JaypieDnsRecord extends constructs.Construct {
|
|
1277
|
+
constructor(scope, id, props) {
|
|
1278
|
+
super(scope, id);
|
|
1279
|
+
const { comment, recordName, type, values } = props;
|
|
1280
|
+
const ttl = props.ttl || cdk__namespace.Duration.seconds(cdk.CDK.DNS.CONFIG.TTL);
|
|
1281
|
+
// Resolve the hosted zone (supports both string and IHostedZone)
|
|
1282
|
+
const zone = resolveHostedZone(scope, {
|
|
1283
|
+
name: `${id}HostedZone`,
|
|
1284
|
+
zone: props.zone,
|
|
1285
|
+
});
|
|
1286
|
+
// Common properties for all record types
|
|
1287
|
+
const baseProps = {
|
|
1288
|
+
comment,
|
|
1289
|
+
recordName,
|
|
1290
|
+
ttl,
|
|
1291
|
+
zone,
|
|
1292
|
+
};
|
|
1293
|
+
// Create the appropriate record based on type
|
|
1294
|
+
switch (type) {
|
|
1295
|
+
case cdk.CDK.DNS.RECORD.A: {
|
|
1296
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
1297
|
+
throw new cdk.ConfigurationError("A record requires at least one IP address");
|
|
1298
|
+
}
|
|
1299
|
+
this.record = new route53.ARecord(this, "Record", {
|
|
1300
|
+
...baseProps,
|
|
1301
|
+
target: route53.RecordTarget.fromIpAddresses(...values),
|
|
1302
|
+
});
|
|
1303
|
+
break;
|
|
1304
|
+
}
|
|
1305
|
+
case cdk.CDK.DNS.RECORD.CNAME: {
|
|
1306
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
1307
|
+
throw new cdk.ConfigurationError("CNAME record requires a domain name");
|
|
1308
|
+
}
|
|
1309
|
+
this.record = new route53.CnameRecord(this, "Record", {
|
|
1310
|
+
...baseProps,
|
|
1311
|
+
domainName: values[0],
|
|
1312
|
+
});
|
|
1313
|
+
break;
|
|
1314
|
+
}
|
|
1315
|
+
case cdk.CDK.DNS.RECORD.MX: {
|
|
1316
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
1317
|
+
throw new cdk.ConfigurationError("MX record requires at least one mail server");
|
|
1318
|
+
}
|
|
1319
|
+
this.record = new route53.MxRecord(this, "Record", {
|
|
1320
|
+
...baseProps,
|
|
1321
|
+
values: values,
|
|
1322
|
+
});
|
|
1323
|
+
break;
|
|
1324
|
+
}
|
|
1325
|
+
case cdk.CDK.DNS.RECORD.NS: {
|
|
1326
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
1327
|
+
throw new cdk.ConfigurationError("NS record requires at least one name server");
|
|
1328
|
+
}
|
|
1329
|
+
this.record = new route53.NsRecord(this, "Record", {
|
|
1330
|
+
...baseProps,
|
|
1331
|
+
values: values,
|
|
1332
|
+
});
|
|
1333
|
+
break;
|
|
1334
|
+
}
|
|
1335
|
+
case cdk.CDK.DNS.RECORD.TXT: {
|
|
1336
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
1337
|
+
throw new cdk.ConfigurationError("TXT record requires at least one value");
|
|
1338
|
+
}
|
|
1339
|
+
this.record = new route53.TxtRecord(this, "Record", {
|
|
1340
|
+
...baseProps,
|
|
1341
|
+
values: values,
|
|
1342
|
+
});
|
|
1343
|
+
break;
|
|
1344
|
+
}
|
|
1345
|
+
default:
|
|
1346
|
+
throw new cdk.ConfigurationError(`Unsupported DNS record type: ${type}. Supported types: A, CNAME, MX, NS, TXT`);
|
|
1347
|
+
}
|
|
1348
|
+
// Add standard tags to the DNS record
|
|
1349
|
+
cdk__namespace.Tags.of(this.record).add(cdk.CDK.TAG.SERVICE, cdk.CDK.SERVICE.INFRASTRUCTURE);
|
|
1350
|
+
cdk__namespace.Tags.of(this.record).add(cdk.CDK.TAG.ROLE, cdk.CDK.ROLE.NETWORKING);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
class JaypieGitHubDeployRole extends constructs.Construct {
|
|
1355
|
+
constructor(scope, id, props) {
|
|
1356
|
+
super(scope, id);
|
|
1357
|
+
const { accountId, oidcProviderArn = cdk$1.Fn.importValue(cdk.CDK.IMPORT.OIDC_PROVIDER), output = true, repoRestriction: propsRepoRestriction, } = props;
|
|
1358
|
+
// Resolve repoRestriction from props or environment variables
|
|
1359
|
+
let repoRestriction = propsRepoRestriction;
|
|
1360
|
+
if (!repoRestriction) {
|
|
1361
|
+
const envRepo = process.env.CDK_ENV_REPO || process.env.PROJECT_REPO;
|
|
1362
|
+
if (!envRepo) {
|
|
1363
|
+
throw new cdk.ConfigurationError("No repoRestriction provided. Set repoRestriction prop, CDK_ENV_REPO, or PROJECT_REPO environment variable");
|
|
1364
|
+
}
|
|
1365
|
+
// Extract organization from owner/repo format and create org-wide restriction
|
|
1366
|
+
const organization = envRepo.split("/")[0];
|
|
1367
|
+
repoRestriction = `repo:${organization}/*:*`;
|
|
1368
|
+
}
|
|
1369
|
+
// Create the IAM role
|
|
1370
|
+
this._role = new awsIam.Role(this, "GitHubActionsRole", {
|
|
1371
|
+
assumedBy: new awsIam.FederatedPrincipal(oidcProviderArn, {
|
|
1372
|
+
StringLike: {
|
|
1373
|
+
"token.actions.githubusercontent.com:sub": repoRestriction,
|
|
1374
|
+
},
|
|
1375
|
+
}, "sts:AssumeRoleWithWebIdentity"),
|
|
1376
|
+
maxSessionDuration: cdk$1.Duration.hours(1),
|
|
1377
|
+
path: "/",
|
|
1378
|
+
});
|
|
1379
|
+
cdk$1.Tags.of(this._role).add(cdk.CDK.TAG.ROLE, cdk.CDK.ROLE.DEPLOY);
|
|
1380
|
+
// Allow the role to access the GitHub OIDC provider
|
|
1381
|
+
this._role.addToPolicy(new awsIam.PolicyStatement({
|
|
1382
|
+
actions: ["sts:AssumeRoleWithWebIdentity"],
|
|
1383
|
+
resources: [`arn:aws:iam::${accountId}:oidc-provider/*`],
|
|
1384
|
+
}));
|
|
1385
|
+
// Allow the role to deploy CDK apps
|
|
1386
|
+
this._role.addToPolicy(new awsIam.PolicyStatement({
|
|
1387
|
+
actions: [
|
|
1388
|
+
"cloudformation:CreateStack",
|
|
1389
|
+
"cloudformation:DeleteStack",
|
|
1390
|
+
"cloudformation:DescribeStackEvents",
|
|
1391
|
+
"cloudformation:DescribeStackResource",
|
|
1392
|
+
"cloudformation:DescribeStackResources",
|
|
1393
|
+
"cloudformation:DescribeStacks",
|
|
1394
|
+
"cloudformation:GetTemplate",
|
|
1395
|
+
"cloudformation:SetStackPolicy",
|
|
1396
|
+
"cloudformation:UpdateStack",
|
|
1397
|
+
"cloudformation:ValidateTemplate",
|
|
1398
|
+
"iam:PassRole",
|
|
1399
|
+
"route53:ListHostedZones*",
|
|
1400
|
+
"s3:GetObject",
|
|
1401
|
+
"s3:ListBucket",
|
|
1402
|
+
],
|
|
1403
|
+
effect: awsIam.Effect.ALLOW,
|
|
1404
|
+
resources: ["*"],
|
|
1405
|
+
}));
|
|
1406
|
+
this._role.addToPolicy(new awsIam.PolicyStatement({
|
|
1407
|
+
actions: ["iam:PassRole", "sts:AssumeRole"],
|
|
1408
|
+
effect: awsIam.Effect.ALLOW,
|
|
1409
|
+
resources: [
|
|
1410
|
+
"arn:aws:iam::*:role/cdk-hnb659fds-deploy-role-*",
|
|
1411
|
+
"arn:aws:iam::*:role/cdk-hnb659fds-file-publishing-*",
|
|
1412
|
+
"arn:aws:iam::*:role/cdk-readOnlyRole",
|
|
1413
|
+
],
|
|
1414
|
+
}));
|
|
1415
|
+
// Export the ARN of the role
|
|
1416
|
+
if (output !== false) {
|
|
1417
|
+
const outputId = typeof output === "string" ? output : "GitHubActionsRoleArn";
|
|
1418
|
+
new cdk$1.CfnOutput(this, outputId, {
|
|
1419
|
+
value: this._role.roleArn,
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
get role() {
|
|
1424
|
+
return this._role;
|
|
1425
|
+
}
|
|
1426
|
+
get roleArn() {
|
|
1427
|
+
return this._role.roleArn;
|
|
1428
|
+
}
|
|
1429
|
+
get roleName() {
|
|
1430
|
+
return this._role.roleName;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1249
1434
|
class JaypieExpressLambda extends JaypieLambda {
|
|
1250
1435
|
constructor(scope, id, props) {
|
|
1251
1436
|
super(scope, id, {
|
|
@@ -1261,11 +1446,12 @@ const SERVICE = {
|
|
|
1261
1446
|
};
|
|
1262
1447
|
class JaypieHostedZone extends constructs.Construct {
|
|
1263
1448
|
/**
|
|
1264
|
-
* Create a new hosted zone with query logging
|
|
1449
|
+
* Create a new hosted zone with query logging and optional DNS records
|
|
1265
1450
|
*/
|
|
1266
1451
|
constructor(scope, id, props) {
|
|
1267
1452
|
super(scope, id);
|
|
1268
|
-
const {
|
|
1453
|
+
const { zoneName, project } = props;
|
|
1454
|
+
const destination = props.destination ?? true;
|
|
1269
1455
|
const service = props.service || cdk.CDK.SERVICE.INFRASTRUCTURE;
|
|
1270
1456
|
// Create the log group
|
|
1271
1457
|
this.logGroup = new awsLogs.LogGroup(this, "LogGroup", {
|
|
@@ -1282,10 +1468,13 @@ class JaypieHostedZone extends constructs.Construct {
|
|
|
1282
1468
|
}
|
|
1283
1469
|
// Grant Route 53 permissions to write to the log group
|
|
1284
1470
|
this.logGroup.grantWrite(new awsIam.ServicePrincipal(SERVICE.ROUTE53));
|
|
1285
|
-
// Add destination
|
|
1286
|
-
if (destination) {
|
|
1471
|
+
// Add destination based on configuration
|
|
1472
|
+
if (destination !== false) {
|
|
1473
|
+
const lambdaDestination = destination === true
|
|
1474
|
+
? resolveDatadogLoggingDestination(scope)
|
|
1475
|
+
: destination;
|
|
1287
1476
|
this.logGroup.addSubscriptionFilter("DatadogLambdaDestination", {
|
|
1288
|
-
destination,
|
|
1477
|
+
destination: lambdaDestination,
|
|
1289
1478
|
filterPattern: awsLogs.FilterPattern.allEvents(),
|
|
1290
1479
|
});
|
|
1291
1480
|
}
|
|
@@ -1300,6 +1489,21 @@ class JaypieHostedZone extends constructs.Construct {
|
|
|
1300
1489
|
if (project) {
|
|
1301
1490
|
cdk__namespace.Tags.of(this.hostedZone).add(cdk.CDK.TAG.PROJECT, project);
|
|
1302
1491
|
}
|
|
1492
|
+
// Create DNS records if provided
|
|
1493
|
+
this.dnsRecords = [];
|
|
1494
|
+
if (props.records) {
|
|
1495
|
+
props.records.forEach((recordConfig, index) => {
|
|
1496
|
+
const { id, ...recordProps } = recordConfig;
|
|
1497
|
+
// Generate a default ID if not provided
|
|
1498
|
+
const recordId = id ||
|
|
1499
|
+
`${recordProps.type}${recordProps.recordName ? `-${recordProps.recordName}` : ""}-${index}`;
|
|
1500
|
+
const dnsRecord = new JaypieDnsRecord(this, recordId, {
|
|
1501
|
+
...recordProps,
|
|
1502
|
+
zone: this.hostedZone,
|
|
1503
|
+
});
|
|
1504
|
+
this.dnsRecords.push(dnsRecord);
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1303
1507
|
}
|
|
1304
1508
|
}
|
|
1305
1509
|
|
|
@@ -1348,276 +1552,348 @@ class JaypieOpenAiSecret extends JaypieEnvSecret {
|
|
|
1348
1552
|
}
|
|
1349
1553
|
|
|
1350
1554
|
/**
|
|
1351
|
-
*
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
*
|
|
1361
|
-
*
|
|
1362
|
-
*
|
|
1555
|
+
* JaypieSsoPermissions Construct
|
|
1556
|
+
*
|
|
1557
|
+
* Creates and manages AWS IAM Identity Center (SSO) permission sets and assignments
|
|
1558
|
+
*
|
|
1559
|
+
* @example
|
|
1560
|
+
* const permissionSets = new JaypieSsoPermissions(this, "PermissionSets", {
|
|
1561
|
+
* iamIdentityCenterArn: "arn:aws:sso:::instance/...",
|
|
1562
|
+
* administratorGroupId: "b4c8b438-4031-7000-782d-5046945fb956",
|
|
1563
|
+
* analystGroupId: "2488f4e8-d061-708e-abe1-c315f0e30005",
|
|
1564
|
+
* developerGroupId: "b438a4f8-e0e1-707c-c6e8-21841daf9ad1",
|
|
1565
|
+
* administratorAccountAssignments: {
|
|
1566
|
+
* "211125635435": ["Administrator", "Analyst", "Developer"],
|
|
1567
|
+
* "381492033431": ["Administrator", "Analyst"],
|
|
1568
|
+
* },
|
|
1569
|
+
* analystAccountAssignments: {
|
|
1570
|
+
* "211125635435": ["Analyst", "Developer"],
|
|
1571
|
+
* "381492033431": [],
|
|
1572
|
+
* },
|
|
1573
|
+
* developerAccountAssignments: {
|
|
1574
|
+
* "211125635435": ["Analyst", "Developer"],
|
|
1575
|
+
* "381492033431": [],
|
|
1576
|
+
* },
|
|
1577
|
+
* });
|
|
1363
1578
|
*/
|
|
1364
|
-
class
|
|
1579
|
+
class JaypieSsoPermissions extends constructs.Construct {
|
|
1365
1580
|
constructor(scope, id, props) {
|
|
1366
1581
|
super(scope, id);
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
//
|
|
1375
|
-
this.
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1582
|
+
const { iamIdentityCenterArn, administratorGroupId, analystGroupId, developerGroupId, administratorAccountAssignments, analystAccountAssignments, developerAccountAssignments, } = props;
|
|
1583
|
+
if (!iamIdentityCenterArn) {
|
|
1584
|
+
// If no IAM Identity Center ARN provided, skip SSO setup
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1587
|
+
//
|
|
1588
|
+
// Permission Sets
|
|
1589
|
+
//
|
|
1590
|
+
this.administratorPermissionSet = new awsSso.CfnPermissionSet(this, "AdministratorPermissionSet", {
|
|
1591
|
+
// Required
|
|
1592
|
+
instanceArn: iamIdentityCenterArn,
|
|
1593
|
+
name: "Administrator",
|
|
1594
|
+
// Optional
|
|
1595
|
+
description: "Unrestricted access",
|
|
1596
|
+
inlinePolicy: {
|
|
1597
|
+
Version: "2012-10-17",
|
|
1598
|
+
Statement: [
|
|
1599
|
+
{
|
|
1600
|
+
Effect: "Allow",
|
|
1601
|
+
Action: [
|
|
1602
|
+
"aws-portal:ViewUsage",
|
|
1603
|
+
"aws-portal:ViewBilling",
|
|
1604
|
+
"budgets:*",
|
|
1605
|
+
"cur:DescribeReportDefinitions",
|
|
1606
|
+
"cur:PutReportDefinition",
|
|
1607
|
+
"cur:DeleteReportDefinition",
|
|
1608
|
+
"cur:ModifyReportDefinition",
|
|
1609
|
+
],
|
|
1610
|
+
Resource: "*",
|
|
1611
|
+
},
|
|
1612
|
+
],
|
|
1613
|
+
},
|
|
1614
|
+
managedPolicies: [
|
|
1615
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess")
|
|
1616
|
+
.managedPolicyArn,
|
|
1617
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
|
|
1618
|
+
],
|
|
1619
|
+
sessionDuration: cdk$1.Duration.hours(1).toIsoString(),
|
|
1620
|
+
tags: [
|
|
1385
1621
|
{
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
"aws-portal:*",
|
|
1389
|
-
"budgets:*",
|
|
1390
|
-
"ce:*",
|
|
1391
|
-
"cost-optimization-hub:*",
|
|
1392
|
-
],
|
|
1393
|
-
Resource: "*",
|
|
1622
|
+
key: cdk.CDK.TAG.SERVICE,
|
|
1623
|
+
value: cdk.CDK.SERVICE.SSO,
|
|
1394
1624
|
},
|
|
1395
|
-
],
|
|
1396
|
-
};
|
|
1397
|
-
// Merge with any additional policy statements provided for administrators
|
|
1398
|
-
const mergedPolicy = this.mergeInlinePolicies(defaultInlinePolicy, this.props?.inlinePolicyStatements?.administrators);
|
|
1399
|
-
const permissionSet = new sso__namespace.CfnPermissionSet(this, "AdministratorPermissionSet", {
|
|
1400
|
-
instanceArn: this.instanceArn,
|
|
1401
|
-
name: exports.PermissionSetType.ADMINISTRATOR,
|
|
1402
|
-
description: "Full administrative access to all AWS services and resources",
|
|
1403
|
-
sessionDuration: cdk$1.Duration.hours(8).toIsoString(),
|
|
1404
|
-
managedPolicies: ["arn:aws:iam::aws:policy/AdministratorAccess"],
|
|
1405
|
-
inlinePolicy: mergedPolicy,
|
|
1406
|
-
});
|
|
1407
|
-
cdk$1.Tags.of(permissionSet).add(cdk.CDK.TAG.SERVICE, cdk.CDK.SERVICE.SSO);
|
|
1408
|
-
this.permissionSets[exports.PermissionSetType.ADMINISTRATOR] = permissionSet;
|
|
1409
|
-
}
|
|
1410
|
-
/**
|
|
1411
|
-
* Creates the Analyst permission set with ReadOnlyAccess policy
|
|
1412
|
-
* and limited write access
|
|
1413
|
-
*/
|
|
1414
|
-
createAnalystPermissionSet() {
|
|
1415
|
-
const defaultInlinePolicy = {
|
|
1416
|
-
Version: "2012-10-17",
|
|
1417
|
-
Statement: [
|
|
1418
1625
|
{
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
"aws-portal:ViewBilling",
|
|
1422
|
-
"aws-portal:ViewAccount",
|
|
1423
|
-
"budgets:ViewBudget",
|
|
1424
|
-
"cloudwatch:PutDashboard",
|
|
1425
|
-
"cloudwatch:PutMetricData",
|
|
1426
|
-
"s3:PutObject",
|
|
1427
|
-
"s3:GetObject",
|
|
1428
|
-
"s3:ListBucket",
|
|
1429
|
-
],
|
|
1430
|
-
Resource: "*",
|
|
1626
|
+
key: cdk.CDK.TAG.ROLE,
|
|
1627
|
+
value: cdk.CDK.ROLE.SECURITY,
|
|
1431
1628
|
},
|
|
1432
1629
|
],
|
|
1433
|
-
};
|
|
1434
|
-
// Merge with any additional policy statements provided for analysts
|
|
1435
|
-
const mergedPolicy = this.mergeInlinePolicies(defaultInlinePolicy, this.props?.inlinePolicyStatements?.analysts);
|
|
1436
|
-
const permissionSet = new sso__namespace.CfnPermissionSet(this, "AnalystPermissionSet", {
|
|
1437
|
-
instanceArn: this.instanceArn,
|
|
1438
|
-
name: exports.PermissionSetType.ANALYST,
|
|
1439
|
-
description: "Read-only access with billing visibility and limited write access",
|
|
1440
|
-
sessionDuration: cdk$1.Duration.hours(4).toIsoString(),
|
|
1441
|
-
managedPolicies: ["arn:aws:iam::aws:policy/ReadOnlyAccess"],
|
|
1442
|
-
inlinePolicy: mergedPolicy,
|
|
1443
1630
|
});
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1631
|
+
this.analystPermissionSet = new awsSso.CfnPermissionSet(this, "AnalystPermissionSet", {
|
|
1632
|
+
// Required
|
|
1633
|
+
instanceArn: iamIdentityCenterArn,
|
|
1634
|
+
name: "Analyst",
|
|
1635
|
+
// Optional
|
|
1636
|
+
description: "Read-only access; may expand to limited write access",
|
|
1637
|
+
inlinePolicy: {
|
|
1638
|
+
Version: "2012-10-17",
|
|
1639
|
+
Statement: [
|
|
1640
|
+
{
|
|
1641
|
+
Effect: "Allow",
|
|
1642
|
+
Action: [
|
|
1643
|
+
"aws-portal:ViewUsage",
|
|
1644
|
+
"aws-portal:ViewBilling",
|
|
1645
|
+
"budgets:Describe*",
|
|
1646
|
+
"budgets:View*",
|
|
1647
|
+
"ce:Get*",
|
|
1648
|
+
"ce:List*",
|
|
1649
|
+
"cloudformation:Describe*",
|
|
1650
|
+
"cloudformation:Get*",
|
|
1651
|
+
"cloudformation:List*",
|
|
1652
|
+
"cloudwatch:BatchGet*",
|
|
1653
|
+
"cloudwatch:Get*",
|
|
1654
|
+
"cloudwatch:List*",
|
|
1655
|
+
"cost-optimization-hub:Get*",
|
|
1656
|
+
"cost-optimization-hub:List*",
|
|
1657
|
+
"ec2:Describe*",
|
|
1658
|
+
"ec2:Get*",
|
|
1659
|
+
"ec2:List*",
|
|
1660
|
+
"ec2:Search*",
|
|
1661
|
+
"iam:Get*",
|
|
1662
|
+
"iam:List*",
|
|
1663
|
+
"iam:PassRole",
|
|
1664
|
+
"lambda:Get*",
|
|
1665
|
+
"lambda:List*",
|
|
1666
|
+
"logs:Describe*",
|
|
1667
|
+
"logs:Get*",
|
|
1668
|
+
"logs:List*",
|
|
1669
|
+
"pipes:Describe*",
|
|
1670
|
+
"pipes:List*",
|
|
1671
|
+
"s3:Get*",
|
|
1672
|
+
"s3:List*",
|
|
1673
|
+
"secretsmanager:GetRandomPassword",
|
|
1674
|
+
"secretsmanager:GetResourcePolicy",
|
|
1675
|
+
"secretsmanager:List*",
|
|
1676
|
+
"securityhub:Describe*",
|
|
1677
|
+
"securityhub:Get*",
|
|
1678
|
+
"securityhub:List*",
|
|
1679
|
+
"servicecatalog:Describe*",
|
|
1680
|
+
"sns:Get*",
|
|
1681
|
+
"sns:List*",
|
|
1682
|
+
"sqs:Get*",
|
|
1683
|
+
"sqs:List*",
|
|
1684
|
+
"states:Describe*",
|
|
1685
|
+
"states:Get*",
|
|
1686
|
+
"states:List*",
|
|
1687
|
+
"tag:*",
|
|
1688
|
+
"xray:*",
|
|
1689
|
+
],
|
|
1690
|
+
Resource: "*",
|
|
1691
|
+
},
|
|
1692
|
+
],
|
|
1693
|
+
},
|
|
1694
|
+
managedPolicies: [
|
|
1695
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("AmazonQDeveloperAccess")
|
|
1696
|
+
.managedPolicyArn,
|
|
1697
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
|
|
1698
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess")
|
|
1699
|
+
.managedPolicyArn,
|
|
1700
|
+
],
|
|
1701
|
+
sessionDuration: cdk$1.Duration.hours(12).toIsoString(),
|
|
1702
|
+
tags: [
|
|
1455
1703
|
{
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
"cloudwatch:*",
|
|
1459
|
-
"logs:*",
|
|
1460
|
-
"lambda:*",
|
|
1461
|
-
"apigateway:*",
|
|
1462
|
-
"dynamodb:*",
|
|
1463
|
-
"s3:*",
|
|
1464
|
-
"sns:*",
|
|
1465
|
-
"sqs:*",
|
|
1466
|
-
"events:*",
|
|
1467
|
-
"ecr:*",
|
|
1468
|
-
"ecs:*",
|
|
1469
|
-
"codebuild:*",
|
|
1470
|
-
],
|
|
1471
|
-
Resource: "*",
|
|
1704
|
+
key: cdk.CDK.TAG.SERVICE,
|
|
1705
|
+
value: cdk.CDK.SERVICE.SSO,
|
|
1472
1706
|
},
|
|
1473
1707
|
{
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
"iam:*User*",
|
|
1477
|
-
"iam:*Role*",
|
|
1478
|
-
"iam:*Policy*",
|
|
1479
|
-
"organizations:*",
|
|
1480
|
-
"account:*",
|
|
1481
|
-
],
|
|
1482
|
-
Resource: "*",
|
|
1708
|
+
key: cdk.CDK.TAG.ROLE,
|
|
1709
|
+
value: cdk.CDK.ROLE.SECURITY,
|
|
1483
1710
|
},
|
|
1484
1711
|
],
|
|
1485
|
-
};
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
description: "
|
|
1492
|
-
|
|
1712
|
+
});
|
|
1713
|
+
this.developerPermissionSet = new awsSso.CfnPermissionSet(this, "DeveloperPermissionSet", {
|
|
1714
|
+
// Required
|
|
1715
|
+
instanceArn: iamIdentityCenterArn,
|
|
1716
|
+
name: "Developer",
|
|
1717
|
+
// Optional
|
|
1718
|
+
description: "Administrative access with limited restrictions",
|
|
1719
|
+
inlinePolicy: {
|
|
1720
|
+
Version: "2012-10-17",
|
|
1721
|
+
Statement: [
|
|
1722
|
+
{
|
|
1723
|
+
Effect: "Allow",
|
|
1724
|
+
Action: [
|
|
1725
|
+
"budgets:*",
|
|
1726
|
+
"ce:*",
|
|
1727
|
+
"cloudformation:*",
|
|
1728
|
+
"cloudwatch:*",
|
|
1729
|
+
"cost-optimization-hub:*",
|
|
1730
|
+
"ec2:*",
|
|
1731
|
+
"iam:Get*",
|
|
1732
|
+
"iam:List*",
|
|
1733
|
+
"iam:PassRole",
|
|
1734
|
+
"lambda:*",
|
|
1735
|
+
"logs:*",
|
|
1736
|
+
"pipes:*",
|
|
1737
|
+
"s3:*",
|
|
1738
|
+
"secretsmanager:*",
|
|
1739
|
+
"securityhub:*",
|
|
1740
|
+
"servicecatalog:*",
|
|
1741
|
+
"sns:*",
|
|
1742
|
+
"sqs:*",
|
|
1743
|
+
"states:*",
|
|
1744
|
+
"tag:*",
|
|
1745
|
+
"xray:*",
|
|
1746
|
+
],
|
|
1747
|
+
Resource: "*",
|
|
1748
|
+
},
|
|
1749
|
+
],
|
|
1750
|
+
},
|
|
1493
1751
|
managedPolicies: [
|
|
1494
|
-
"
|
|
1752
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("AmazonQDeveloperAccess")
|
|
1753
|
+
.managedPolicyArn,
|
|
1754
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
|
|
1755
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess")
|
|
1756
|
+
.managedPolicyArn,
|
|
1757
|
+
awsIam.ManagedPolicy.fromAwsManagedPolicyName("job-function/SystemAdministrator").managedPolicyArn,
|
|
1758
|
+
],
|
|
1759
|
+
sessionDuration: cdk$1.Duration.hours(4).toIsoString(),
|
|
1760
|
+
tags: [
|
|
1761
|
+
{
|
|
1762
|
+
key: cdk.CDK.TAG.SERVICE,
|
|
1763
|
+
value: cdk.CDK.SERVICE.SSO,
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
key: cdk.CDK.TAG.ROLE,
|
|
1767
|
+
value: cdk.CDK.ROLE.SECURITY,
|
|
1768
|
+
},
|
|
1495
1769
|
],
|
|
1496
|
-
inlinePolicy: mergedPolicy,
|
|
1497
1770
|
});
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1771
|
+
// Map permission set names to their ARNs and labels
|
|
1772
|
+
const permissionSetMap = {
|
|
1773
|
+
Administrator: {
|
|
1774
|
+
arn: this.administratorPermissionSet.attrPermissionSetArn,
|
|
1775
|
+
label: "Administrator",
|
|
1776
|
+
},
|
|
1777
|
+
Analyst: {
|
|
1778
|
+
arn: this.analystPermissionSet.attrPermissionSetArn,
|
|
1779
|
+
label: "Analyst",
|
|
1780
|
+
},
|
|
1781
|
+
Developer: {
|
|
1782
|
+
arn: this.developerPermissionSet.attrPermissionSetArn,
|
|
1783
|
+
label: "Developer",
|
|
1784
|
+
},
|
|
1785
|
+
};
|
|
1786
|
+
//
|
|
1787
|
+
// Assignments
|
|
1788
|
+
//
|
|
1789
|
+
// Helper function to create assignments for a group
|
|
1790
|
+
const createAssignments = (groupId, accountAssignments) => {
|
|
1791
|
+
if (!groupId || !accountAssignments) {
|
|
1792
|
+
return; // Skip if group ID or assignments not provided
|
|
1793
|
+
}
|
|
1794
|
+
Object.keys(accountAssignments).forEach((accountId) => {
|
|
1795
|
+
const permissionSetNames = accountAssignments[accountId];
|
|
1796
|
+
permissionSetNames.forEach((permissionSetName) => {
|
|
1797
|
+
const permissionSet = permissionSetMap[permissionSetName];
|
|
1798
|
+
if (!permissionSet) {
|
|
1799
|
+
throw new cdk.ConfigurationError(`Unknown permission set: ${permissionSetName}. Valid options: ${Object.keys(permissionSetMap).join(", ")}`);
|
|
1800
|
+
}
|
|
1801
|
+
const accountAssignment = new awsSso.CfnAssignment(this, `AccountAssignment-${accountId}-${permissionSet.label}Role-${groupId}Group`, {
|
|
1802
|
+
// Required
|
|
1803
|
+
instanceArn: iamIdentityCenterArn,
|
|
1804
|
+
permissionSetArn: permissionSet.arn,
|
|
1805
|
+
principalId: groupId,
|
|
1806
|
+
principalType: cdk.CDK.PRINCIPAL_TYPE.GROUP,
|
|
1807
|
+
targetId: accountId,
|
|
1808
|
+
targetType: cdk.CDK.TARGET_TYPE.AWS_ACCOUNT,
|
|
1809
|
+
});
|
|
1810
|
+
cdk$1.Tags.of(accountAssignment).add(cdk.CDK.TAG.SERVICE, cdk.CDK.SERVICE.SSO);
|
|
1811
|
+
cdk$1.Tags.of(accountAssignment).add(cdk.CDK.TAG.ROLE, cdk.CDK.ROLE.SECURITY);
|
|
1812
|
+
});
|
|
1813
|
+
});
|
|
1814
|
+
};
|
|
1815
|
+
// Create assignments for each group
|
|
1816
|
+
createAssignments(administratorGroupId, administratorAccountAssignments);
|
|
1817
|
+
createAssignments(analystGroupId, analystAccountAssignments);
|
|
1818
|
+
createAssignments(developerGroupId, developerAccountAssignments);
|
|
1506
1819
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
//
|
|
1823
|
+
//
|
|
1824
|
+
// Constants
|
|
1825
|
+
//
|
|
1826
|
+
const DEFAULT_APPLICATION_ID = "arn:aws:serverlessrepo:us-east-2:004480582608:applications/SSOSync";
|
|
1827
|
+
const DEFAULT_APPLICATION_VERSION = "2.3.3";
|
|
1828
|
+
const DEFAULT_GOOGLE_GROUP_MATCH = "name:AWS*";
|
|
1829
|
+
//
|
|
1830
|
+
//
|
|
1831
|
+
// Class
|
|
1832
|
+
//
|
|
1833
|
+
class JaypieSsoSyncApplication extends constructs.Construct {
|
|
1834
|
+
constructor(scope, id = "SSOSyncApplication", props = {}) {
|
|
1835
|
+
super(scope, id);
|
|
1836
|
+
const { googleAdminEmail, googleAdminEmailEnvKey = "CDK_ENV_SSOSYNC_GOOGLE_ADMIN_EMAIL", googleCredentials, googleCredentialsEnvKey = "CDK_ENV_SSOSYNC_GOOGLE_CREDENTIALS", googleGroupMatch, googleGroupMatchEnvKey = "CDK_ENV_SSOSYNC_GOOGLE_GROUP_MATCH", identityStoreId, identityStoreIdEnvKey = "CDK_ENV_SSOSYNC_IDENTITY_STORE_ID", scimEndpointAccessToken, scimEndpointAccessTokenEnvKey = "CDK_ENV_SCIM_ENDPOINT_ACCESS_TOKEN", scimEndpointUrl, scimEndpointUrlEnvKey = "CDK_ENV_SSOSYNC_SCIM_ENDPOINT_URL", semanticVersion, semanticVersionEnvKey = "CDK_ENV_SSOSYNC_SEMANTIC_VERSION", ssoSyncApplicationId = DEFAULT_APPLICATION_ID, tags, } = props;
|
|
1837
|
+
// Resolve all values from props or environment variables
|
|
1838
|
+
const resolvedGoogleAdminEmail = googleAdminEmail || process.env[googleAdminEmailEnvKey];
|
|
1839
|
+
const resolvedGoogleCredentials = googleCredentials || process.env[googleCredentialsEnvKey];
|
|
1840
|
+
const resolvedGoogleGroupMatch = googleGroupMatch ||
|
|
1841
|
+
process.env[googleGroupMatchEnvKey] ||
|
|
1842
|
+
DEFAULT_GOOGLE_GROUP_MATCH;
|
|
1843
|
+
const resolvedIdentityStoreId = identityStoreId || process.env[identityStoreIdEnvKey];
|
|
1844
|
+
const resolvedScimEndpointAccessToken = scimEndpointAccessToken || process.env[scimEndpointAccessTokenEnvKey];
|
|
1845
|
+
const resolvedScimEndpointUrl = scimEndpointUrl || process.env[scimEndpointUrlEnvKey];
|
|
1846
|
+
const resolvedSemanticVersion = semanticVersion ||
|
|
1847
|
+
process.env[semanticVersionEnvKey] ||
|
|
1848
|
+
DEFAULT_APPLICATION_VERSION;
|
|
1849
|
+
// Validate required parameters
|
|
1850
|
+
const missingParams = [];
|
|
1851
|
+
if (!resolvedGoogleAdminEmail) {
|
|
1852
|
+
missingParams.push(`googleAdminEmail or ${googleAdminEmailEnvKey} environment variable`);
|
|
1517
1853
|
}
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
//
|
|
1535
|
-
this.
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
...props.accountMap.operations,
|
|
1550
|
-
...props.accountMap.production,
|
|
1551
|
-
...props.accountMap.sandbox,
|
|
1552
|
-
...props.accountMap.security,
|
|
1553
|
-
...props.accountMap.stage,
|
|
1554
|
-
];
|
|
1555
|
-
// Create assignments for each account
|
|
1556
|
-
allAccounts.forEach((accountId, index) => {
|
|
1557
|
-
const assignment = new sso__namespace.CfnAssignment(this, `AdministratorAssignment${index}`, {
|
|
1558
|
-
instanceArn: this.instanceArn,
|
|
1559
|
-
permissionSetArn: administratorPermissionSet.attrPermissionSetArn,
|
|
1560
|
-
principalId: administratorGroup,
|
|
1561
|
-
principalType: "GROUP",
|
|
1562
|
-
targetId: accountId,
|
|
1563
|
-
targetType: "AWS_ACCOUNT",
|
|
1564
|
-
});
|
|
1565
|
-
cdk$1.Tags.of(assignment).add(cdk.CDK.TAG.SERVICE, cdk.CDK.SERVICE.SSO);
|
|
1566
|
-
cdk$1.Tags.of(assignment).add("Group", "administrators");
|
|
1854
|
+
if (!resolvedGoogleCredentials) {
|
|
1855
|
+
missingParams.push(`googleCredentials or ${googleCredentialsEnvKey} environment variable`);
|
|
1856
|
+
}
|
|
1857
|
+
if (!resolvedIdentityStoreId) {
|
|
1858
|
+
missingParams.push(`identityStoreId or ${identityStoreIdEnvKey} environment variable`);
|
|
1859
|
+
}
|
|
1860
|
+
if (!resolvedScimEndpointAccessToken) {
|
|
1861
|
+
missingParams.push(`scimEndpointAccessToken or ${scimEndpointAccessTokenEnvKey} environment variable`);
|
|
1862
|
+
}
|
|
1863
|
+
if (!resolvedScimEndpointUrl) {
|
|
1864
|
+
missingParams.push(`scimEndpointUrl or ${scimEndpointUrlEnvKey} environment variable`);
|
|
1865
|
+
}
|
|
1866
|
+
if (missingParams.length > 0) {
|
|
1867
|
+
throw new errors.ConfigurationError(`JaypieSsoSyncApplication missing required configuration: ${missingParams.join(", ")}`);
|
|
1868
|
+
}
|
|
1869
|
+
// Create the SSO Sync Application
|
|
1870
|
+
// Type assertion is safe because we validated all required values above
|
|
1871
|
+
this._application = new awsSam.CfnApplication(this, "Application", {
|
|
1872
|
+
location: {
|
|
1873
|
+
applicationId: ssoSyncApplicationId,
|
|
1874
|
+
semanticVersion: resolvedSemanticVersion,
|
|
1875
|
+
},
|
|
1876
|
+
parameters: {
|
|
1877
|
+
GoogleAdminEmail: resolvedGoogleAdminEmail,
|
|
1878
|
+
GoogleCredentials: resolvedGoogleCredentials,
|
|
1879
|
+
GoogleGroupMatch: resolvedGoogleGroupMatch,
|
|
1880
|
+
IdentityStoreID: resolvedIdentityStoreId,
|
|
1881
|
+
Region: cdk$1.Stack.of(this).region,
|
|
1882
|
+
SCIMEndpointAccessToken: resolvedScimEndpointAccessToken,
|
|
1883
|
+
SCIMEndpointUrl: resolvedScimEndpointUrl,
|
|
1884
|
+
},
|
|
1567
1885
|
});
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
// Analysts get access to development, management, sandbox, and stage accounts
|
|
1576
|
-
const analystAccounts = [
|
|
1577
|
-
...props.accountMap.development,
|
|
1578
|
-
...props.accountMap.management,
|
|
1579
|
-
...props.accountMap.sandbox,
|
|
1580
|
-
...props.accountMap.stage,
|
|
1581
|
-
];
|
|
1582
|
-
// Create assignments for each account
|
|
1583
|
-
analystAccounts.forEach((accountId, index) => {
|
|
1584
|
-
const assignment = new sso__namespace.CfnAssignment(this, `AnalystAssignment${index}`, {
|
|
1585
|
-
instanceArn: this.instanceArn,
|
|
1586
|
-
permissionSetArn: analystPermissionSet.attrPermissionSetArn,
|
|
1587
|
-
principalId: analystGroup,
|
|
1588
|
-
principalType: "GROUP",
|
|
1589
|
-
targetId: accountId,
|
|
1590
|
-
targetType: "AWS_ACCOUNT",
|
|
1591
|
-
});
|
|
1592
|
-
cdk$1.Tags.of(assignment).add(cdk.CDK.TAG.SERVICE, cdk.CDK.SERVICE.SSO);
|
|
1593
|
-
cdk$1.Tags.of(assignment).add("Group", "analysts");
|
|
1886
|
+
// Add tags
|
|
1887
|
+
const defaultTags = {
|
|
1888
|
+
[cdk.CDK.TAG.ROLE]: cdk.CDK.ROLE.SECURITY,
|
|
1889
|
+
};
|
|
1890
|
+
const allTags = { ...defaultTags, ...tags };
|
|
1891
|
+
Object.entries(allTags).forEach(([key, value]) => {
|
|
1892
|
+
cdk$1.Tags.of(this._application).add(key, value);
|
|
1594
1893
|
});
|
|
1595
1894
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
*/
|
|
1599
|
-
assignDeveloperPermissions(props) {
|
|
1600
|
-
const developerGroup = props.groupMap.developers;
|
|
1601
|
-
const developerPermissionSet = this.permissionSets[exports.PermissionSetType.DEVELOPER];
|
|
1602
|
-
// Developers get access to development, sandbox, and stage accounts
|
|
1603
|
-
const developerAccounts = [
|
|
1604
|
-
...props.accountMap.development,
|
|
1605
|
-
...props.accountMap.sandbox,
|
|
1606
|
-
...props.accountMap.stage,
|
|
1607
|
-
];
|
|
1608
|
-
// Create assignments for each account
|
|
1609
|
-
developerAccounts.forEach((accountId, index) => {
|
|
1610
|
-
const assignment = new sso__namespace.CfnAssignment(this, `DeveloperAssignment${index}`, {
|
|
1611
|
-
instanceArn: this.instanceArn,
|
|
1612
|
-
permissionSetArn: developerPermissionSet.attrPermissionSetArn,
|
|
1613
|
-
principalId: developerGroup,
|
|
1614
|
-
principalType: "GROUP",
|
|
1615
|
-
targetId: accountId,
|
|
1616
|
-
targetType: "AWS_ACCOUNT",
|
|
1617
|
-
});
|
|
1618
|
-
cdk$1.Tags.of(assignment).add(cdk.CDK.TAG.SERVICE, cdk.CDK.SERVICE.SSO);
|
|
1619
|
-
cdk$1.Tags.of(assignment).add("Group", "developers");
|
|
1620
|
-
});
|
|
1895
|
+
get application() {
|
|
1896
|
+
return this._application;
|
|
1621
1897
|
}
|
|
1622
1898
|
}
|
|
1623
1899
|
|
|
@@ -1879,21 +2155,34 @@ class JaypieWebDeploymentBucket extends constructs.Construct {
|
|
|
1879
2155
|
applyRemovalPolicy(policy) {
|
|
1880
2156
|
this.bucket.applyRemovalPolicy(policy);
|
|
1881
2157
|
}
|
|
2158
|
+
get bucketRef() {
|
|
2159
|
+
return {
|
|
2160
|
+
bucketArn: this.bucket.bucketArn,
|
|
2161
|
+
bucketName: this.bucket.bucketName,
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
1882
2164
|
}
|
|
1883
2165
|
|
|
2166
|
+
Object.defineProperty(exports, "CDK", {
|
|
2167
|
+
enumerable: true,
|
|
2168
|
+
get: function () { return cdk.CDK; }
|
|
2169
|
+
});
|
|
1884
2170
|
exports.JaypieApiGateway = JaypieApiGateway;
|
|
1885
2171
|
exports.JaypieAppStack = JaypieAppStack;
|
|
1886
2172
|
exports.JaypieBucketQueuedLambda = JaypieBucketQueuedLambda;
|
|
1887
2173
|
exports.JaypieDatadogSecret = JaypieDatadogSecret;
|
|
2174
|
+
exports.JaypieDnsRecord = JaypieDnsRecord;
|
|
1888
2175
|
exports.JaypieEnvSecret = JaypieEnvSecret;
|
|
1889
2176
|
exports.JaypieExpressLambda = JaypieExpressLambda;
|
|
2177
|
+
exports.JaypieGitHubDeployRole = JaypieGitHubDeployRole;
|
|
1890
2178
|
exports.JaypieHostedZone = JaypieHostedZone;
|
|
1891
2179
|
exports.JaypieInfrastructureStack = JaypieInfrastructureStack;
|
|
1892
2180
|
exports.JaypieLambda = JaypieLambda;
|
|
1893
2181
|
exports.JaypieMongoDbSecret = JaypieMongoDbSecret;
|
|
1894
2182
|
exports.JaypieOpenAiSecret = JaypieOpenAiSecret;
|
|
1895
2183
|
exports.JaypieQueuedLambda = JaypieQueuedLambda;
|
|
1896
|
-
exports.
|
|
2184
|
+
exports.JaypieSsoPermissions = JaypieSsoPermissions;
|
|
2185
|
+
exports.JaypieSsoSyncApplication = JaypieSsoSyncApplication;
|
|
1897
2186
|
exports.JaypieStack = JaypieStack;
|
|
1898
2187
|
exports.JaypieTraceSigningKeySecret = JaypieTraceSigningKeySecret;
|
|
1899
2188
|
exports.JaypieWebDeploymentBucket = JaypieWebDeploymentBucket;
|
|
@@ -1906,7 +2195,9 @@ exports.isEnv = isEnv;
|
|
|
1906
2195
|
exports.isProductionEnv = isProductionEnv;
|
|
1907
2196
|
exports.isSandboxEnv = isSandboxEnv;
|
|
1908
2197
|
exports.jaypieLambdaEnv = jaypieLambdaEnv;
|
|
2198
|
+
exports.resolveDatadogForwarderFunction = resolveDatadogForwarderFunction;
|
|
1909
2199
|
exports.resolveDatadogLayers = resolveDatadogLayers;
|
|
2200
|
+
exports.resolveDatadogLoggingDestination = resolveDatadogLoggingDestination;
|
|
1910
2201
|
exports.resolveHostedZone = resolveHostedZone;
|
|
1911
2202
|
exports.resolveParamsAndSecrets = resolveParamsAndSecrets;
|
|
1912
2203
|
//# sourceMappingURL=index.cjs.map
|