@gradientedge/cdk-utils 8.97.0 → 8.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ export declare enum SiteResponseHeaderPolicyType {
2
+ ORIGIN = "origin",
3
+ STATIC = "static"
4
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SiteResponseHeaderPolicyType = void 0;
4
+ var SiteResponseHeaderPolicyType;
5
+ (function (SiteResponseHeaderPolicyType) {
6
+ SiteResponseHeaderPolicyType["ORIGIN"] = "origin";
7
+ SiteResponseHeaderPolicyType["STATIC"] = "static";
8
+ })(SiteResponseHeaderPolicyType || (exports.SiteResponseHeaderPolicyType = SiteResponseHeaderPolicyType = {}));
@@ -1,2 +1,3 @@
1
+ export * from './constants';
1
2
  export * from './main';
2
3
  export * from './types';
@@ -14,5 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./constants"), exports);
17
18
  __exportStar(require("./main"), exports);
18
19
  __exportStar(require("./types"), exports);
@@ -1,3 +1,4 @@
1
+ import * as cdk from 'aws-cdk-lib';
1
2
  import * as certificateManager from 'aws-cdk-lib/aws-certificatemanager';
2
3
  import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
3
4
  import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
@@ -11,7 +12,7 @@ import * as s3 from 'aws-cdk-lib/aws-s3';
11
12
  import * as efs from 'aws-cdk-lib/aws-efs';
12
13
  import { Construct } from 'constructs';
13
14
  import { CommonConstruct } from '../../common';
14
- import { SiteWithEcsBackendProps } from './types';
15
+ import { SiteWithEcsBackendProps, SiteResponseHeadersPolicyProps } from './types';
15
16
  /**
16
17
  * @classdesc Provides a construct to create and deploy a site hosted with an clustered ECS/ELB backend
17
18
  * @example
@@ -58,6 +59,8 @@ export declare class SiteWithEcsBackend extends CommonConstruct {
58
59
  siteDomainNames: string[];
59
60
  siteCloudfrontFunction: cloudfront.Function;
60
61
  siteFunctionAssociations: cloudfront.FunctionAssociation[];
62
+ siteOriginRequestPolicy: cloudfront.OriginRequestPolicy;
63
+ siteOriginResponseHeadersPolicy?: cloudfront.ResponseHeadersPolicy;
61
64
  constructor(parent: Construct, id: string, props: SiteWithEcsBackendProps);
62
65
  /**
63
66
  * @summary Initialise and provision resources
@@ -122,6 +125,9 @@ export declare class SiteWithEcsBackend extends CommonConstruct {
122
125
  * Method to create log bucket for site distribution
123
126
  */
124
127
  protected createSiteLogBucket(): void;
128
+ protected createSiteOriginRequestPolicy(): void;
129
+ protected createResponseHeaderPolicy(props: SiteResponseHeadersPolicyProps): cdk.aws_cloudfront.ResponseHeadersPolicy | undefined;
130
+ protected createSiteOriginResponseHeadersPolicy(): void;
125
131
  protected createSiteOrigin(): void;
126
132
  /**
127
133
  * @summary Method to create a site cloudfront function
@@ -24,6 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.SiteWithEcsBackend = void 0;
27
+ const _ = __importStar(require("lodash"));
27
28
  const cdk = __importStar(require("aws-cdk-lib"));
28
29
  const cloudfront = __importStar(require("aws-cdk-lib/aws-cloudfront"));
29
30
  const origins = __importStar(require("aws-cdk-lib/aws-cloudfront-origins"));
@@ -77,6 +78,8 @@ class SiteWithEcsBackend extends common_1.CommonConstruct {
77
78
  siteDomainNames;
78
79
  siteCloudfrontFunction;
79
80
  siteFunctionAssociations;
81
+ siteOriginRequestPolicy;
82
+ siteOriginResponseHeadersPolicy;
80
83
  constructor(parent, id, props) {
81
84
  super(parent, id, props);
82
85
  this.props = props;
@@ -100,6 +103,8 @@ class SiteWithEcsBackend extends common_1.CommonConstruct {
100
103
  this.createEcsBuildArgs();
101
104
  this.createEcsContainerImage();
102
105
  this.createEcsService();
106
+ this.createSiteOriginRequestPolicy();
107
+ this.createSiteOriginResponseHeadersPolicy();
103
108
  this.createSiteOrigin();
104
109
  this.createSiteCloudfrontFunction();
105
110
  this.resolveSiteFunctionAssociations();
@@ -340,9 +345,47 @@ class SiteWithEcsBackend extends common_1.CommonConstruct {
340
345
  createSiteLogBucket() {
341
346
  this.siteLogBucket = this.s3Manager.createS3Bucket(`${this.id}-site-logs`, this, this.props.siteLogBucket);
342
347
  }
348
+ createSiteOriginRequestPolicy() {
349
+ if (!this.props.siteOriginRequestPolicy)
350
+ return;
351
+ this.siteOriginRequestPolicy = new cloudfront.OriginRequestPolicy(this, `${this.id}-sorp`, {
352
+ comment: `Request Policy for ${this.id}-distribution - ${this.props.stage} stage`,
353
+ cookieBehavior: this.props.siteOriginRequestPolicy.cookieBehavior,
354
+ headerBehavior: this.props.siteOriginRequestPolicy.headerBehavior,
355
+ originRequestPolicyName: `${this.id}-origin-request`,
356
+ queryStringBehavior: this.props.siteOriginRequestPolicy.queryStringBehavior,
357
+ });
358
+ _.assign(this.props.siteDistribution.defaultBehavior, {
359
+ originRequestPolicy: this.siteOriginRequestPolicy,
360
+ });
361
+ }
362
+ createResponseHeaderPolicy(props) {
363
+ if (!props)
364
+ return undefined;
365
+ return new cloudfront.ResponseHeadersPolicy(this, `${this.id}-${props.type}-srhp`, {
366
+ ...props,
367
+ comment: `Response Header Policy for ${props.type} for ${this.id}-distribution - ${this.props.stage} stage`,
368
+ responseHeadersPolicyName: `${this.id}-${props.type}-response`,
369
+ securityHeadersBehavior: {
370
+ strictTransportSecurity: {
371
+ ...props.securityHeadersBehavior?.strictTransportSecurity,
372
+ accessControlMaxAge: cdk.Duration.seconds(props.securityHeadersBehavior?.strictTransportSecurity?.accessControlMaxAgeInSeconds),
373
+ },
374
+ },
375
+ });
376
+ }
377
+ createSiteOriginResponseHeadersPolicy() {
378
+ if (!this.props.siteOriginResponseHeadersPolicy)
379
+ return;
380
+ this.siteOriginResponseHeadersPolicy = this.createResponseHeaderPolicy(this.props.siteOriginResponseHeadersPolicy);
381
+ _.assign(this.props.siteDistribution.defaultBehavior, {
382
+ responseHeadersPolicy: this.siteOriginResponseHeadersPolicy,
383
+ });
384
+ }
343
385
  createSiteOrigin() {
344
386
  this.siteOrigin = new origins.HttpOrigin(this.siteInternalDomainName, {
345
387
  httpPort: this.props.siteTask.listenerPort,
388
+ originId: `${this.id}-server`,
346
389
  protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY,
347
390
  });
348
391
  }
@@ -1,6 +1,8 @@
1
1
  import { CommonStackProps } from '../../common';
2
2
  import { AcmProps, CloudfrontFunctionProps, DistributionProps, EcsApplicationLoadBalancedFargateServiceProps, EcsClusterProps, EfsAccessPointOptions, EfsFileSystemProps, HealthCheck, LogProps, S3BucketProps } from '../../services';
3
3
  import { VpcProps } from 'aws-cdk-lib/aws-ec2';
4
+ import { OriginRequestPolicyProps, ResponseHeadersStrictTransportSecurity, ResponseSecurityHeadersBehavior, ResponseHeadersPolicyProps } from 'aws-cdk-lib/aws-cloudfront';
5
+ import { SiteResponseHeaderPolicyType } from './constants';
4
6
  /**
5
7
  */
6
8
  export interface SiteWithEcsBackendProps extends CommonStackProps {
@@ -18,6 +20,8 @@ export interface SiteWithEcsBackendProps extends CommonStackProps {
18
20
  siteHealthCheck: HealthCheck;
19
21
  siteLog: LogProps;
20
22
  siteLogBucket: S3BucketProps;
23
+ siteOriginRequestPolicy: OriginRequestPolicyProps;
24
+ siteOriginResponseHeadersPolicy: SiteResponseHeadersPolicyProps;
21
25
  siteRecordName?: string;
22
26
  siteRegionalCertificate: AcmProps;
23
27
  siteSubDomain: string;
@@ -27,3 +31,13 @@ export interface SiteWithEcsBackendProps extends CommonStackProps {
27
31
  useExistingHostedZone: boolean;
28
32
  useExistingVpc: boolean;
29
33
  }
34
+ export interface SiteResponseHeadersStrictTransportSecurity extends ResponseHeadersStrictTransportSecurity {
35
+ accessControlMaxAgeInSeconds: number;
36
+ }
37
+ export interface SiteSecurityHeadersBehavior extends ResponseSecurityHeadersBehavior {
38
+ strictTransportSecurity: SiteResponseHeadersStrictTransportSecurity;
39
+ }
40
+ export interface SiteResponseHeadersPolicyProps extends ResponseHeadersPolicyProps {
41
+ securityHeadersBehavior: SiteSecurityHeadersBehavior;
42
+ type: SiteResponseHeaderPolicyType;
43
+ }
@@ -1,5 +1,3 @@
1
- import { SecretsManager as SM } from '@aws-sdk/client-secrets-manager';
2
- import * as cdk from 'aws-cdk-lib';
3
1
  import * as secretsManager from 'aws-cdk-lib/aws-secretsmanager';
4
2
  import { CommonConstruct } from '../../../common';
5
3
  /**
@@ -19,30 +17,18 @@ import { CommonConstruct } from '../../../common';
19
17
  * @see [CDK Secrets Manager Module]{@link https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_secretsmanager-readme.html}
20
18
  */
21
19
  export declare class SecretsManager {
22
- /**
23
- *
24
- * @param region
25
- */
26
- getAwsSecretsManager(region: string): SM;
27
- /**
28
- * @summary Method to load a secret from secrets manager
29
- * @param secretName
30
- * @param region
31
- */
32
- loadSecret(secretName: string, region: string): Promise<any>;
33
- /**
34
- * @summary Method to retrieve a secret from secrets manager with a cloudformation export
35
- * @param id
36
- * @param scope
37
- * @param stackName
38
- * @param exportName
39
- */
40
- retrieveSecretFromSecretsManager(id: string, scope: CommonConstruct, stackName: string, exportName: string): cdk.aws_secretsmanager.ISecret;
41
20
  /**
42
21
  * @summary Method to create a secret
43
22
  * @param id scoped id of the resource
44
23
  * @param scope scope in which this resource is defined
45
24
  * @param props the secret properties
46
25
  */
47
- createSecret(id: string, scope: CommonConstruct, props: secretsManager.SecretProps): cdk.aws_secretsmanager.Secret;
26
+ createSecret(id: string, scope: CommonConstruct, props: secretsManager.SecretProps): secretsManager.Secret;
27
+ /**
28
+ * @summary Method to resolve secret value from a secret using AWS SDK
29
+ * @param scope scope in which this resource is defined
30
+ * @param secretId the secret name/ARN
31
+ * @param secretKey the secret key to resolve the value for
32
+ */
33
+ resolveSecretValue(scope: CommonConstruct, secretId: string, secretKey: string): Promise<any>;
48
34
  }
@@ -25,7 +25,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.SecretsManager = void 0;
27
27
  const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager");
28
- const cdk = __importStar(require("aws-cdk-lib"));
29
28
  const secretsManager = __importStar(require("aws-cdk-lib/aws-secretsmanager"));
30
29
  const utils = __importStar(require("../../../utils"));
31
30
  /**
@@ -45,33 +44,6 @@ const utils = __importStar(require("../../../utils"));
45
44
  * @see [CDK Secrets Manager Module]{@link https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_secretsmanager-readme.html}
46
45
  */
47
46
  class SecretsManager {
48
- /**
49
- *
50
- * @param region
51
- */
52
- getAwsSecretsManager(region) {
53
- return new client_secrets_manager_1.SecretsManager({ region: region });
54
- }
55
- /**
56
- * @summary Method to load a secret from secrets manager
57
- * @param secretName
58
- * @param region
59
- */
60
- async loadSecret(secretName, region) {
61
- const secretsManager = this.getAwsSecretsManager(region);
62
- const secret = await Promise.all([secretsManager.getSecretValue({ SecretId: secretName })]);
63
- return secret ? JSON.parse(secret[0].SecretString) : {};
64
- }
65
- /**
66
- * @summary Method to retrieve a secret from secrets manager with a cloudformation export
67
- * @param id
68
- * @param scope
69
- * @param stackName
70
- * @param exportName
71
- */
72
- retrieveSecretFromSecretsManager(id, scope, stackName, exportName) {
73
- return secretsManager.Secret.fromSecretNameV2(scope, `${id}`, cdk.Fn.importValue(`${stackName}-${scope.props.stage}-${exportName}`));
74
- }
75
47
  /**
76
48
  * @summary Method to create a secret
77
49
  * @param id scoped id of the resource
@@ -87,5 +59,25 @@ class SecretsManager {
87
59
  utils.createCfnOutput(`${id}-secretArn`, scope, secret.secretArn);
88
60
  return secret;
89
61
  }
62
+ /**
63
+ * @summary Method to resolve secret value from a secret using AWS SDK
64
+ * @param scope scope in which this resource is defined
65
+ * @param secretId the secret name/ARN
66
+ * @param secretKey the secret key to resolve the value for
67
+ */
68
+ async resolveSecretValue(scope, secretId, secretKey) {
69
+ const client = new client_secrets_manager_1.SecretsManagerClient({
70
+ credentials: utils.determineCredentials(),
71
+ region: scope.props.region,
72
+ });
73
+ const command = new client_secrets_manager_1.GetSecretValueCommand({
74
+ SecretId: secretId,
75
+ });
76
+ const response = await client.send(command);
77
+ if (!response.SecretString)
78
+ throw `Unable to resolve secret for ${secretId}`;
79
+ const secretString = JSON.parse(response.SecretString);
80
+ return secretString[secretKey];
81
+ }
90
82
  }
91
83
  exports.SecretsManager = SecretsManager;
@@ -1,5 +1,6 @@
1
1
  import * as cdk from 'aws-cdk-lib';
2
2
  import { CommonConstruct } from '../../common';
3
+ import { AwsCredentialIdentityProvider } from '@aws-sdk/types';
3
4
  /**
4
5
  * @summary Helper method to add CloudFormation outputs from the construct
5
6
  * @param id scoped id of the resource
@@ -10,3 +11,4 @@ import { CommonConstruct } from '../../common';
10
11
  * @returns The CloudFormation output
11
12
  */
12
13
  export declare function createCfnOutput(id: string, scope: CommonConstruct, value?: string, description?: string, overrideId?: boolean): cdk.CfnOutput;
14
+ export declare function determineCredentials(): AwsCredentialIdentityProvider;
@@ -23,9 +23,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.createCfnOutput = void 0;
26
+ exports.determineCredentials = exports.createCfnOutput = void 0;
27
27
  const cdk = __importStar(require("aws-cdk-lib"));
28
28
  const _ = __importStar(require("lodash"));
29
+ const credential_providers_1 = require("@aws-sdk/credential-providers");
29
30
  /**
30
31
  * @summary Helper method to add CloudFormation outputs from the construct
31
32
  * @param id scoped id of the resource
@@ -48,3 +49,9 @@ function createCfnOutput(id, scope, value, description, overrideId = true) {
48
49
  return output;
49
50
  }
50
51
  exports.createCfnOutput = createCfnOutput;
52
+ function determineCredentials() {
53
+ if (process.env.AWS_PROFILE)
54
+ return (0, credential_providers_1.fromIni)();
55
+ return (0, credential_providers_1.fromEnv)();
56
+ }
57
+ exports.determineCredentials = determineCredentials;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradientedge/cdk-utils",
3
- "version": "8.97.0",
3
+ "version": "8.99.0",
4
4
  "description": "Utilities for AWS CDK provisioning",
5
5
  "main": "dist/index.js",
6
6
  "engines": {
@@ -30,10 +30,10 @@
30
30
  "build:production": "rimraf dist/ && npx tsc -p tsconfig.prd.json && pnpm -r build",
31
31
  "ci": "pnpm install --frozen-lockfile && pnpm build && pnpm validate && pnpm run docs",
32
32
  "cz": "npx cz",
33
- "override:plugin:docs": "cp theme/type-converter.js node_modules/better-docs/typescript",
34
33
  "docs": "npx rimraf api-docs && pnpm override:plugin:docs && npx jsdoc --pedantic -c jsdoc.json .",
35
- "lint": "pnpm prettify && eslint **/*.ts --cache --max-warnings=0",
36
34
  "fix": "pnpm prettify && eslint --fix **/*.ts",
35
+ "lint": "pnpm prettify && eslint **/*.ts --cache --max-warnings=0",
36
+ "override:plugin:docs": "cp theme/type-converter.js node_modules/better-docs/typescript",
37
37
  "prettier": "npx prettier --cache --check \"**/*.{ts,json,md}\"",
38
38
  "prettify": "npx prettier --cache --write \"**/*.{ts,json,md}\"",
39
39
  "test": "npx rimraf coverage && npx jest --ci --maxWorkers=100%",
@@ -46,13 +46,15 @@
46
46
  }
47
47
  },
48
48
  "dependencies": {
49
- "@aws-sdk/client-secrets-manager": "^3.354.0",
49
+ "@aws-sdk/client-secrets-manager": "^3.357.0",
50
+ "@aws-sdk/credential-providers": "^3.357.0",
51
+ "@aws-sdk/types": "^3.357.0",
50
52
  "@types/lodash": "^4.14.195",
51
53
  "@types/node": "^20.3.1",
52
54
  "@types/uuid": "^9.0.2",
53
55
  "app-root-path": "^3.1.0",
54
- "aws-cdk-lib": "^2.84.0",
55
- "constructs": "^10.2.54",
56
+ "aws-cdk-lib": "^2.85.0",
57
+ "constructs": "^10.2.56",
56
58
  "lodash": "^4.17.21",
57
59
  "moment": "^2.29.4",
58
60
  "nconf": "^0.12.0",
@@ -65,9 +67,9 @@
65
67
  "@babel/eslint-parser": "^7.22.5",
66
68
  "@babel/plugin-proposal-class-properties": "^7.18.6",
67
69
  "@types/jest": "^29.5.2",
68
- "@typescript-eslint/eslint-plugin": "^5.59.11",
69
- "@typescript-eslint/parser": "^5.59.11",
70
- "aws-cdk": "^2.84.0",
70
+ "@typescript-eslint/eslint-plugin": "^5.60.0",
71
+ "@typescript-eslint/parser": "^5.60.0",
72
+ "aws-cdk": "^2.85.0",
71
73
  "better-docs": "^2.7.2",
72
74
  "codecov": "^3.8.3",
73
75
  "commitizen": "^4.3.0",
@@ -84,8 +86,8 @@
84
86
  "jsdoc": "^4.0.2",
85
87
  "jsdoc-babel": "^0.5.0",
86
88
  "jsdoc-mermaid": "^1.0.0",
87
- "jsdoc-to-markdown": "^8.0.0",
88
89
  "jsdoc-plugin-typescript": "^2.2.1",
90
+ "jsdoc-to-markdown": "^8.0.0",
89
91
  "prettier": "^2.8.8",
90
92
  "prettier-plugin-organize-imports": "^3.2.2",
91
93
  "rimraf": "^5.0.1",
@@ -0,0 +1,4 @@
1
+ export enum SiteResponseHeaderPolicyType {
2
+ ORIGIN = 'origin',
3
+ STATIC = 'static',
4
+ }
@@ -1,2 +1,3 @@
1
+ export * from './constants'
1
2
  export * from './main'
2
3
  export * from './types'
@@ -1,3 +1,4 @@
1
+ import * as _ from 'lodash'
1
2
  import * as cdk from 'aws-cdk-lib'
2
3
  import * as certificateManager from 'aws-cdk-lib/aws-certificatemanager'
3
4
  import * as cloudfront from 'aws-cdk-lib/aws-cloudfront'
@@ -13,7 +14,7 @@ import * as s3 from 'aws-cdk-lib/aws-s3'
13
14
  import * as efs from 'aws-cdk-lib/aws-efs'
14
15
  import { Construct } from 'constructs'
15
16
  import { CommonConstruct } from '../../common'
16
- import { SiteWithEcsBackendProps } from './types'
17
+ import { SiteWithEcsBackendProps, SiteResponseHeadersPolicyProps } from './types'
17
18
 
18
19
  /**
19
20
  * @classdesc Provides a construct to create and deploy a site hosted with an clustered ECS/ELB backend
@@ -62,6 +63,8 @@ export class SiteWithEcsBackend extends CommonConstruct {
62
63
  siteDomainNames: string[]
63
64
  siteCloudfrontFunction: cloudfront.Function
64
65
  siteFunctionAssociations: cloudfront.FunctionAssociation[]
66
+ siteOriginRequestPolicy: cloudfront.OriginRequestPolicy
67
+ siteOriginResponseHeadersPolicy?: cloudfront.ResponseHeadersPolicy
65
68
 
66
69
  constructor(parent: Construct, id: string, props: SiteWithEcsBackendProps) {
67
70
  super(parent, id, props)
@@ -88,6 +91,8 @@ export class SiteWithEcsBackend extends CommonConstruct {
88
91
  this.createEcsBuildArgs()
89
92
  this.createEcsContainerImage()
90
93
  this.createEcsService()
94
+ this.createSiteOriginRequestPolicy()
95
+ this.createSiteOriginResponseHeadersPolicy()
91
96
  this.createSiteOrigin()
92
97
  this.createSiteCloudfrontFunction()
93
98
  this.resolveSiteFunctionAssociations()
@@ -402,9 +407,50 @@ export class SiteWithEcsBackend extends CommonConstruct {
402
407
  this.siteLogBucket = this.s3Manager.createS3Bucket(`${this.id}-site-logs`, this, this.props.siteLogBucket)
403
408
  }
404
409
 
410
+ protected createSiteOriginRequestPolicy() {
411
+ if (!this.props.siteOriginRequestPolicy) return
412
+ this.siteOriginRequestPolicy = new cloudfront.OriginRequestPolicy(this, `${this.id}-sorp`, {
413
+ comment: `Request Policy for ${this.id}-distribution - ${this.props.stage} stage`,
414
+ cookieBehavior: this.props.siteOriginRequestPolicy.cookieBehavior,
415
+ headerBehavior: this.props.siteOriginRequestPolicy.headerBehavior,
416
+ originRequestPolicyName: `${this.id}-origin-request`,
417
+ queryStringBehavior: this.props.siteOriginRequestPolicy.queryStringBehavior,
418
+ })
419
+
420
+ _.assign(this.props.siteDistribution.defaultBehavior, {
421
+ originRequestPolicy: this.siteOriginRequestPolicy,
422
+ })
423
+ }
424
+
425
+ protected createResponseHeaderPolicy(props: SiteResponseHeadersPolicyProps) {
426
+ if (!props) return undefined
427
+ return new cloudfront.ResponseHeadersPolicy(this, `${this.id}-${props.type}-srhp`, {
428
+ ...props,
429
+ comment: `Response Header Policy for ${props.type} for ${this.id}-distribution - ${this.props.stage} stage`,
430
+ responseHeadersPolicyName: `${this.id}-${props.type}-response`,
431
+ securityHeadersBehavior: {
432
+ strictTransportSecurity: {
433
+ ...props.securityHeadersBehavior?.strictTransportSecurity,
434
+ accessControlMaxAge: cdk.Duration.seconds(
435
+ props.securityHeadersBehavior?.strictTransportSecurity?.accessControlMaxAgeInSeconds
436
+ ),
437
+ },
438
+ },
439
+ })
440
+ }
441
+
442
+ protected createSiteOriginResponseHeadersPolicy() {
443
+ if (!this.props.siteOriginResponseHeadersPolicy) return
444
+ this.siteOriginResponseHeadersPolicy = this.createResponseHeaderPolicy(this.props.siteOriginResponseHeadersPolicy)
445
+ _.assign(this.props.siteDistribution.defaultBehavior, {
446
+ responseHeadersPolicy: this.siteOriginResponseHeadersPolicy,
447
+ })
448
+ }
449
+
405
450
  protected createSiteOrigin() {
406
451
  this.siteOrigin = new origins.HttpOrigin(this.siteInternalDomainName, {
407
452
  httpPort: this.props.siteTask.listenerPort,
453
+ originId: `${this.id}-server`,
408
454
  protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY,
409
455
  })
410
456
  }
@@ -12,6 +12,13 @@ import {
12
12
  S3BucketProps,
13
13
  } from '../../services'
14
14
  import { VpcProps } from 'aws-cdk-lib/aws-ec2'
15
+ import {
16
+ OriginRequestPolicyProps,
17
+ ResponseHeadersStrictTransportSecurity,
18
+ ResponseSecurityHeadersBehavior,
19
+ ResponseHeadersPolicyProps,
20
+ } from 'aws-cdk-lib/aws-cloudfront'
21
+ import { SiteResponseHeaderPolicyType } from './constants'
15
22
 
16
23
  /**
17
24
  */
@@ -30,6 +37,8 @@ export interface SiteWithEcsBackendProps extends CommonStackProps {
30
37
  siteHealthCheck: HealthCheck
31
38
  siteLog: LogProps
32
39
  siteLogBucket: S3BucketProps
40
+ siteOriginRequestPolicy: OriginRequestPolicyProps
41
+ siteOriginResponseHeadersPolicy: SiteResponseHeadersPolicyProps
33
42
  siteRecordName?: string
34
43
  siteRegionalCertificate: AcmProps
35
44
  siteSubDomain: string
@@ -39,3 +48,16 @@ export interface SiteWithEcsBackendProps extends CommonStackProps {
39
48
  useExistingHostedZone: boolean
40
49
  useExistingVpc: boolean
41
50
  }
51
+
52
+ export interface SiteResponseHeadersStrictTransportSecurity extends ResponseHeadersStrictTransportSecurity {
53
+ accessControlMaxAgeInSeconds: number
54
+ }
55
+
56
+ export interface SiteSecurityHeadersBehavior extends ResponseSecurityHeadersBehavior {
57
+ strictTransportSecurity: SiteResponseHeadersStrictTransportSecurity
58
+ }
59
+
60
+ export interface SiteResponseHeadersPolicyProps extends ResponseHeadersPolicyProps {
61
+ securityHeadersBehavior: SiteSecurityHeadersBehavior
62
+ type: SiteResponseHeaderPolicyType
63
+ }
@@ -1,5 +1,4 @@
1
- import { SecretsManager as SM } from '@aws-sdk/client-secrets-manager'
2
- import * as cdk from 'aws-cdk-lib'
1
+ import { GetSecretValueCommand, SecretsManagerClient } from '@aws-sdk/client-secrets-manager'
3
2
  import * as secretsManager from 'aws-cdk-lib/aws-secretsmanager'
4
3
  import * as utils from '../../../utils'
5
4
  import { CommonConstruct } from '../../../common'
@@ -21,40 +20,6 @@ import { CommonConstruct } from '../../../common'
21
20
  * @see [CDK Secrets Manager Module]{@link https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_secretsmanager-readme.html}
22
21
  */
23
22
  export class SecretsManager {
24
- /**
25
- *
26
- * @param region
27
- */
28
- public getAwsSecretsManager(region: string) {
29
- return new SM({ region: region })
30
- }
31
-
32
- /**
33
- * @summary Method to load a secret from secrets manager
34
- * @param secretName
35
- * @param region
36
- */
37
- public async loadSecret(secretName: string, region: string) {
38
- const secretsManager = this.getAwsSecretsManager(region)
39
- const secret: any = await Promise.all([secretsManager.getSecretValue({ SecretId: secretName })])
40
- return secret ? JSON.parse(secret[0].SecretString) : {}
41
- }
42
-
43
- /**
44
- * @summary Method to retrieve a secret from secrets manager with a cloudformation export
45
- * @param id
46
- * @param scope
47
- * @param stackName
48
- * @param exportName
49
- */
50
- public retrieveSecretFromSecretsManager(id: string, scope: CommonConstruct, stackName: string, exportName: string) {
51
- return secretsManager.Secret.fromSecretNameV2(
52
- scope,
53
- `${id}`,
54
- cdk.Fn.importValue(`${stackName}-${scope.props.stage}-${exportName}`)
55
- )
56
- }
57
-
58
23
  /**
59
24
  * @summary Method to create a secret
60
25
  * @param id scoped id of the resource
@@ -72,4 +37,25 @@ export class SecretsManager {
72
37
 
73
38
  return secret
74
39
  }
40
+
41
+ /**
42
+ * @summary Method to resolve secret value from a secret using AWS SDK
43
+ * @param scope scope in which this resource is defined
44
+ * @param secretId the secret name/ARN
45
+ * @param secretKey the secret key to resolve the value for
46
+ */
47
+ public async resolveSecretValue(scope: CommonConstruct, secretId: string, secretKey: string) {
48
+ const client = new SecretsManagerClient({
49
+ credentials: utils.determineCredentials(),
50
+ region: scope.props.region,
51
+ })
52
+ const command = new GetSecretValueCommand({
53
+ SecretId: secretId,
54
+ })
55
+ const response = await client.send(command)
56
+ if (!response.SecretString) throw `Unable to resolve secret for ${secretId}`
57
+ const secretString = JSON.parse(response.SecretString)
58
+
59
+ return secretString[secretKey]
60
+ }
75
61
  }
@@ -1,6 +1,8 @@
1
1
  import * as cdk from 'aws-cdk-lib'
2
2
  import * as _ from 'lodash'
3
3
  import { CommonConstruct } from '../../common'
4
+ import { fromEnv, fromIni } from '@aws-sdk/credential-providers'
5
+ import { AwsCredentialIdentityProvider } from '@aws-sdk/types'
4
6
 
5
7
  /**
6
8
  * @summary Helper method to add CloudFormation outputs from the construct
@@ -29,3 +31,8 @@ export function createCfnOutput(
29
31
  }
30
32
  return output
31
33
  }
34
+
35
+ export function determineCredentials(): AwsCredentialIdentityProvider {
36
+ if (process.env.AWS_PROFILE) return fromIni()
37
+ return fromEnv()
38
+ }