@studion/infra-code-blocks 2.0.0-alpha.4 → 2.0.0-alpha.6

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.
Files changed (28) hide show
  1. package/dist/components/acm-certificate/index.js +6 -1
  2. package/dist/components/cloudfront/index.d.ts.map +1 -1
  3. package/dist/components/cloudfront/index.js +97 -55
  4. package/dist/components/cloudfront/lb-cache-strategy.js +9 -1
  5. package/dist/components/cloudfront/s3-cache-strategy.js +12 -4
  6. package/dist/components/database/builder.js +34 -7
  7. package/dist/components/database/database-replica.js +27 -3
  8. package/dist/components/database/ec2-ssm-connect.d.ts +2 -1
  9. package/dist/components/database/ec2-ssm-connect.d.ts.map +1 -1
  10. package/dist/components/database/ec2-ssm-connect.js +33 -16
  11. package/dist/components/database/index.js +55 -7
  12. package/dist/components/ecs-service/index.js +70 -28
  13. package/dist/components/grafana/dashboards/panels.js +23 -17
  14. package/dist/components/grafana/dashboards/web-server-slo.js +4 -1
  15. package/dist/components/password/index.js +7 -1
  16. package/dist/components/prometheus/queries.test.js +10 -19
  17. package/dist/components/redis/elasticache-redis.js +6 -1
  18. package/dist/components/redis/upstash-redis.js +8 -2
  19. package/dist/components/static-site/index.js +7 -1
  20. package/dist/components/static-site/s3-assets.js +4 -1
  21. package/dist/components/vpc/index.js +2 -1
  22. package/dist/components/web-server/builder.js +32 -6
  23. package/dist/components/web-server/index.js +47 -15
  24. package/dist/components/web-server/load-balancer.js +13 -3
  25. package/dist/otel/builder.js +4 -1
  26. package/dist/otel/config.js +11 -14
  27. package/dist/otel/index.js +7 -3
  28. package/package.json +36 -44
@@ -39,8 +39,21 @@ const defaults = {
39
39
  },
40
40
  };
41
41
  class EcsService extends pulumi.ComponentResource {
42
+ name;
43
+ vpc;
44
+ logGroup;
45
+ taskDefinition;
46
+ taskExecutionRole;
47
+ taskRole;
48
+ service;
49
+ securityGroups;
50
+ serviceDiscoveryService;
51
+ persistentStorage;
42
52
  constructor(name, args, opts = {}) {
43
- super('studion:ecs-service:EcsService', name, {}, Object.assign(Object.assign({}, opts), { aliases: [...(opts.aliases || []), { type: 'studion:ecs:Service' }] }));
53
+ super('studion:ecs-service:EcsService', name, {}, {
54
+ ...opts,
55
+ aliases: [...(opts.aliases || []), { type: 'studion:ecs:Service' }],
56
+ });
44
57
  const argsWithDefaults = (0, merge_with_defaults_1.mergeWithDefaults)(defaults, args);
45
58
  const taskExecutionRoleInlinePolicies = pulumi.output(args.taskExecutionRoleInlinePolicies ||
46
59
  defaults.taskExecutionRoleInlinePolicies);
@@ -56,7 +69,7 @@ class EcsService extends pulumi.ComponentResource {
56
69
  this.persistentStorage = this.createPersistentStorage(this.vpc);
57
70
  }
58
71
  });
59
- this.taskDefinition = this.createTaskDefinition(argsWithDefaults.containers, pulumi.output(argsWithDefaults.volumes), this.taskExecutionRole, this.taskRole, argsWithDefaults.family, argsWithDefaults.size, Object.assign(Object.assign({}, common_tags_1.commonTags), argsWithDefaults.tags));
72
+ this.taskDefinition = this.createTaskDefinition(argsWithDefaults.containers, pulumi.output(argsWithDefaults.volumes), this.taskExecutionRole, this.taskRole, argsWithDefaults.family, argsWithDefaults.size, { ...common_tags_1.commonTags, ...argsWithDefaults.tags });
60
73
  if (argsWithDefaults.enableServiceAutoDiscovery) {
61
74
  this.serviceDiscoveryService = this.createServiceDiscovery();
62
75
  }
@@ -76,7 +89,7 @@ class EcsService extends pulumi.ComponentResource {
76
89
  createLogGroup(namePrefix) {
77
90
  const logGroup = new aws.cloudwatch.LogGroup(`${this.name}-log-group`, {
78
91
  retentionInDays: 14,
79
- namePrefix: namePrefix !== null && namePrefix !== void 0 ? namePrefix : `/ecs/${this.name}-`,
92
+ namePrefix: namePrefix ?? `/ecs/${this.name}-`,
80
93
  tags: common_tags_1.commonTags,
81
94
  }, { parent: this });
82
95
  return logGroup;
@@ -90,8 +103,18 @@ class EcsService extends pulumi.ComponentResource {
90
103
  const taskDefinitionVolumes = this.createTaskDefinitionVolumes(volumes);
91
104
  return pulumi.all(containerDefinitions).apply(containerDefinitions => {
92
105
  return taskDefinitionVolumes.apply(volumes => {
93
- return new aws.ecs.TaskDefinition(`${this.name}-task-definition`, Object.assign(Object.assign({ family: family !== null && family !== void 0 ? family : `${this.name}-task-definition-${stack}`, networkMode: 'awsvpc', executionRoleArn: taskExecutionRole.arn, taskRoleArn: taskRole.arn, cpu,
94
- memory, requiresCompatibilities: ['FARGATE'], containerDefinitions: JSON.stringify(containerDefinitions) }, ((volumes === null || volumes === void 0 ? void 0 : volumes.length) ? { volumes } : {})), { tags: Object.assign(Object.assign({}, common_tags_1.commonTags), tags) }), { parent: this });
106
+ return new aws.ecs.TaskDefinition(`${this.name}-task-definition`, {
107
+ family: family ?? `${this.name}-task-definition-${stack}`,
108
+ networkMode: 'awsvpc',
109
+ executionRoleArn: taskExecutionRole.arn,
110
+ taskRoleArn: taskRole.arn,
111
+ cpu,
112
+ memory,
113
+ requiresCompatibilities: ['FARGATE'],
114
+ containerDefinitions: JSON.stringify(containerDefinitions),
115
+ ...(volumes?.length ? { volumes } : {}),
116
+ tags: { ...common_tags_1.commonTags, ...tags },
117
+ }, { parent: this });
95
118
  });
96
119
  });
97
120
  }
@@ -113,26 +136,31 @@ class EcsService extends pulumi.ComponentResource {
113
136
  });
114
137
  }
115
138
  createContainerDefinition(container) {
116
- return this.logGroup.name.apply(logGroupName => (Object.assign(Object.assign(Object.assign(Object.assign({}, container), { readonlyRootFilesystem: false }), (container.mountPoints && {
117
- mountPoints: container.mountPoints.map(mountPoint => pulumi
118
- .all([
119
- mountPoint.sourceVolume,
120
- mountPoint.containerPath,
121
- mountPoint.readOnly,
122
- ])
123
- .apply(([sourceVolume, containerPath, readOnly]) => ({
124
- containerPath,
125
- sourceVolume,
126
- readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : false,
127
- }))),
128
- })), { logConfiguration: {
139
+ return this.logGroup.name.apply(logGroupName => ({
140
+ ...container,
141
+ readonlyRootFilesystem: false,
142
+ ...(container.mountPoints && {
143
+ mountPoints: container.mountPoints.map(mountPoint => pulumi
144
+ .all([
145
+ mountPoint.sourceVolume,
146
+ mountPoint.containerPath,
147
+ mountPoint.readOnly,
148
+ ])
149
+ .apply(([sourceVolume, containerPath, readOnly]) => ({
150
+ containerPath,
151
+ sourceVolume,
152
+ readOnly: readOnly ?? false,
153
+ }))),
154
+ }),
155
+ logConfiguration: {
129
156
  logDriver: 'awslogs',
130
157
  options: {
131
158
  'awslogs-group': logGroupName,
132
159
  'awslogs-region': awsRegion,
133
160
  'awslogs-stream-prefix': 'ecs',
134
161
  },
135
- } })));
162
+ },
163
+ }));
136
164
  }
137
165
  createTaskExecutionRole(inlinePolicies) {
138
166
  const secretManagerSecretsInlinePolicy = {
@@ -221,7 +249,6 @@ class EcsService extends pulumi.ComponentResource {
221
249
  this.addSecurityGroup(securityGroup);
222
250
  }
223
251
  createEcsService(ecsServiceArgs) {
224
- var _a;
225
252
  if (ecsServiceArgs.securityGroup) {
226
253
  this.addSecurityGroup(ecsServiceArgs.securityGroup);
227
254
  }
@@ -237,13 +264,25 @@ class EcsService extends pulumi.ComponentResource {
237
264
  .all(this.securityGroups)
238
265
  .apply(groups => groups.map(it => it.id)),
239
266
  };
240
- return new aws.ecs.Service(`${this.name}-service`, Object.assign(Object.assign(Object.assign({ name: (_a = ecsServiceArgs.name) !== null && _a !== void 0 ? _a : this.name, cluster: pulumi.output(ecsServiceArgs.cluster).id, launchType: 'FARGATE', deploymentController: { type: ecsServiceArgs.deploymentController }, desiredCount: ecsServiceArgs.desiredCount, taskDefinition: this.taskDefinition.arn, enableExecuteCommand: true, networkConfiguration }, (ecsServiceArgs.loadBalancers && {
241
- loadBalancers: ecsServiceArgs.loadBalancers,
242
- })), (this.serviceDiscoveryService && {
243
- serviceRegistries: {
244
- registryArn: this.serviceDiscoveryService.arn,
245
- },
246
- })), { tags: Object.assign(Object.assign({}, common_tags_1.commonTags), ecsServiceArgs.tags) }), { parent: this });
267
+ return new aws.ecs.Service(`${this.name}-service`, {
268
+ name: ecsServiceArgs.name ?? this.name,
269
+ cluster: pulumi.output(ecsServiceArgs.cluster).id,
270
+ launchType: 'FARGATE',
271
+ deploymentController: { type: ecsServiceArgs.deploymentController },
272
+ desiredCount: ecsServiceArgs.desiredCount,
273
+ taskDefinition: this.taskDefinition.arn,
274
+ enableExecuteCommand: true,
275
+ networkConfiguration,
276
+ ...(ecsServiceArgs.loadBalancers && {
277
+ loadBalancers: ecsServiceArgs.loadBalancers,
278
+ }),
279
+ ...(this.serviceDiscoveryService && {
280
+ serviceRegistries: {
281
+ registryArn: this.serviceDiscoveryService.arn,
282
+ },
283
+ }),
284
+ tags: { ...common_tags_1.commonTags, ...ecsServiceArgs.tags },
285
+ }, { parent: this });
247
286
  }
248
287
  createServiceDiscovery() {
249
288
  const privateDnsNamespace = this.createPrivateDnsNameSpace();
@@ -316,7 +355,10 @@ class EcsService extends pulumi.ComponentResource {
316
355
  ],
317
356
  performanceMode: 'generalPurpose',
318
357
  throughputMode: 'bursting',
319
- tags: Object.assign(Object.assign({}, common_tags_1.commonTags), { Name: `${this.name}-data` }),
358
+ tags: {
359
+ ...common_tags_1.commonTags,
360
+ Name: `${this.name}-data`,
361
+ },
320
362
  }, { parent: this });
321
363
  const securityGroup = new aws.ec2.SecurityGroup(`${this.name}-persistent-storage-security-group`, {
322
364
  vpcId: vpc.vpcId,
@@ -22,14 +22,17 @@ function createStatPercentagePanel(title, position, dataSource, metric) {
22
22
  },
23
23
  ],
24
24
  fieldConfig: {
25
- defaults: Object.assign(Object.assign({}, percentageFieldConfig), (metric.thresholds
26
- ? {
27
- thresholds: {
28
- mode: 'absolute',
29
- steps: metric.thresholds,
30
- },
31
- }
32
- : {})),
25
+ defaults: {
26
+ ...percentageFieldConfig,
27
+ ...(metric.thresholds
28
+ ? {
29
+ thresholds: {
30
+ mode: 'absolute',
31
+ steps: metric.thresholds,
32
+ },
33
+ }
34
+ : {}),
35
+ },
33
36
  },
34
37
  };
35
38
  }
@@ -49,16 +52,19 @@ function createTimeSeriesPanel(title, position, dataSource, metric, unit, min, m
49
52
  },
50
53
  ],
51
54
  fieldConfig: {
52
- defaults: Object.assign({ unit,
55
+ defaults: {
56
+ unit,
53
57
  min,
54
- max }, (metric.thresholds
55
- ? {
56
- thresholds: {
57
- mode: 'absolute',
58
- steps: metric.thresholds,
59
- },
60
- }
61
- : {})),
58
+ max,
59
+ ...(metric.thresholds
60
+ ? {
61
+ thresholds: {
62
+ mode: 'absolute',
63
+ steps: metric.thresholds,
64
+ },
65
+ }
66
+ : {}),
67
+ },
62
68
  },
63
69
  };
64
70
  }
@@ -5,8 +5,11 @@ const grafana = require("@pulumiverse/grafana");
5
5
  const prometheus_1 = require("../../prometheus");
6
6
  const panels_1 = require("./panels");
7
7
  class WebServerSloDashboardBuilder {
8
+ name;
9
+ title;
10
+ panels = [];
11
+ tags;
8
12
  constructor(name, args) {
9
- this.panels = [];
10
13
  this.name = name;
11
14
  this.title = pulumi.output(args.title);
12
15
  }
@@ -6,8 +6,14 @@ const pulumi = require("@pulumi/pulumi");
6
6
  const random = require("@pulumi/random");
7
7
  const common_tags_1 = require("../../shared/common-tags");
8
8
  class Password extends pulumi.ComponentResource {
9
+ name;
10
+ value;
11
+ secret;
9
12
  constructor(name, args = {}, opts = {}) {
10
- super('studion:password:Password', name, {}, Object.assign(Object.assign({}, opts), { aliases: [...(opts.aliases || []), { type: 'studion:Password' }] }));
13
+ super('studion:password:Password', name, {}, {
14
+ ...opts,
15
+ aliases: [...(opts.aliases || []), { type: 'studion:Password' }],
16
+ });
11
17
  this.name = name;
12
18
  if (args.value) {
13
19
  this.value = pulumi.secret(args.value);
@@ -1,46 +1,37 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const node_test_1 = require("node:test");
13
4
  const assert = require("node:assert/strict");
14
5
  const queries_1 = require("./queries");
15
- (0, node_test_1.describe)('Prometheus Query Builders', () => __awaiter(void 0, void 0, void 0, function* () {
6
+ (0, node_test_1.describe)('Prometheus Query Builders', async () => {
16
7
  const namespace = 'app';
17
8
  const timeRange = '2m';
18
9
  const apiRouteFilter = 'http_route=~"/api/.*"';
19
- (0, node_test_1.describe)('getAvailabilityQuery', () => __awaiter(void 0, void 0, void 0, function* () {
10
+ (0, node_test_1.describe)('getAvailabilityQuery', async () => {
20
11
  (0, node_test_1.it)('should build correct query', () => {
21
12
  const result = (0, queries_1.getAvailabilityQuery)(namespace, timeRange);
22
13
  const expected = `(sum(rate(${namespace}_http_server_duration_milliseconds_count{http_status_code!~"5.."}[${timeRange}]))) / ` +
23
14
  `(sum(rate(${namespace}_http_server_duration_milliseconds_count[${timeRange}]))) * 100`;
24
15
  assert.equal(result, expected);
25
16
  });
26
- }));
27
- (0, node_test_1.describe)('getSuccessRateQuery', () => __awaiter(void 0, void 0, void 0, function* () {
17
+ });
18
+ (0, node_test_1.describe)('getSuccessRateQuery', async () => {
28
19
  (0, node_test_1.it)('should build correct query', () => {
29
20
  const result = (0, queries_1.getSuccessRateQuery)(namespace, timeRange, apiRouteFilter);
30
21
  const expected = `(sum(rate(${namespace}_http_server_duration_milliseconds_count{http_status_code=~"[2-4]..",${apiRouteFilter}}[2m]))) / ` +
31
22
  `(sum(rate(${namespace}_http_server_duration_milliseconds_count{${apiRouteFilter}}[2m]))) * 100`;
32
23
  assert.equal(result, expected);
33
24
  });
34
- }));
35
- (0, node_test_1.describe)('getPercentileLatencyQuery', () => __awaiter(void 0, void 0, void 0, function* () {
25
+ });
26
+ (0, node_test_1.describe)('getPercentileLatencyQuery', async () => {
36
27
  (0, node_test_1.it)('should build correct query', () => {
37
28
  const percentile = 0.95;
38
29
  const result = (0, queries_1.getPercentileLatencyQuery)(namespace, timeRange, percentile, apiRouteFilter);
39
30
  const expected = `histogram_quantile(${percentile}, sum by(le) (rate(${namespace}_http_server_duration_milliseconds_bucket{${apiRouteFilter}}[${timeRange}])))`;
40
31
  assert.equal(result, expected);
41
32
  });
42
- }));
43
- (0, node_test_1.describe)('getLatencyPercentageQuery', () => __awaiter(void 0, void 0, void 0, function* () {
33
+ });
34
+ (0, node_test_1.describe)('getLatencyPercentageQuery', async () => {
44
35
  (0, node_test_1.it)('should build correct query', () => {
45
36
  const threshold = 200;
46
37
  const result = (0, queries_1.getLatencyPercentageQuery)(namespace, timeRange, threshold, apiRouteFilter);
@@ -48,5 +39,5 @@ const queries_1 = require("./queries");
48
39
  `(sum(rate(${namespace}_http_server_duration_milliseconds_count{${apiRouteFilter}}[2m]))) * 100`;
49
40
  assert.equal(result, expected);
50
41
  });
51
- }));
52
- }));
42
+ });
43
+ });
@@ -11,6 +11,11 @@ const defaults = {
11
11
  parameterGroupName: 'default.redis7',
12
12
  };
13
13
  class ElastiCacheRedis extends pulumi.ComponentResource {
14
+ name;
15
+ vpc;
16
+ cluster;
17
+ securityGroup;
18
+ subnetGroup;
14
19
  constructor(name, args, opts = {}) {
15
20
  super('studion:redis:ElastiCacheRedis', name, {}, opts);
16
21
  const argsWithDefaults = (0, merge_with_defaults_1.mergeWithDefaults)(defaults, args);
@@ -31,7 +36,7 @@ class ElastiCacheRedis extends pulumi.ComponentResource {
31
36
  subnetGroupName: this.subnetGroup.name,
32
37
  parameterGroupName: parameterGroupName,
33
38
  port: 6379,
34
- tags: Object.assign(Object.assign({}, common_tags_1.commonTags), tags),
39
+ tags: { ...common_tags_1.commonTags, ...tags },
35
40
  }, { parent: this });
36
41
  }
37
42
  createSubnetGroup() {
@@ -10,10 +10,16 @@ const defaults = {
10
10
  primaryRegion: 'us-east-1',
11
11
  };
12
12
  class UpstashRedis extends pulumi.ComponentResource {
13
+ name;
14
+ instance;
15
+ password;
13
16
  constructor(name, args, opts = {}) {
14
- super('studion:redis:UpstashRedis', name, {}, Object.assign(Object.assign({}, opts), { aliases: [...(opts.aliases || []), { type: 'studion:Redis' }] }));
17
+ super('studion:redis:UpstashRedis', name, {}, {
18
+ ...opts,
19
+ aliases: [...(opts.aliases || []), { type: 'studion:Redis' }],
20
+ });
15
21
  const dbName = `${pulumi.getProject()}-${pulumi.getStack()}`;
16
- const argsWithDefaults = (0, merge_with_defaults_1.mergeWithDefaults)(Object.assign(Object.assign({}, defaults), { dbName }), args);
22
+ const argsWithDefaults = (0, merge_with_defaults_1.mergeWithDefaults)({ ...defaults, dbName }, args);
17
23
  this.name = name;
18
24
  this.instance = new upstash.RedisDatabase(`${this.name}-database`, {
19
25
  databaseName: argsWithDefaults.dbName,
@@ -6,8 +6,14 @@ const cache_rule_ttl_1 = require("./cache-rule-ttl");
6
6
  const s3_assets_1 = require("./s3-assets");
7
7
  const cloudfront_1 = require("../cloudfront");
8
8
  class StaticSite extends pulumi.ComponentResource {
9
+ name;
10
+ s3Assets;
11
+ cf;
9
12
  constructor(name, args, opts = {}) {
10
- super('studion:static-site:StaticSite', name, {}, Object.assign(Object.assign({}, opts), { aliases: [...(opts.aliases || []), { type: 'studion:StaticSite' }] }));
13
+ super('studion:static-site:StaticSite', name, {}, {
14
+ ...opts,
15
+ aliases: [...(opts.aliases || []), { type: 'studion:StaticSite' }],
16
+ });
11
17
  const { domain, hostedZoneId, certificate, bucketPrefix, indexDocument, errorDocument, cacheRules, tags, } = args;
12
18
  if (!domain && !certificate) {
13
19
  throw new Error('Provide either domain or certificate, or both');
@@ -5,6 +5,9 @@ const pulumi = require("@pulumi/pulumi");
5
5
  const aws = require("@pulumi/aws");
6
6
  const common_tags_1 = require("../../shared/common-tags");
7
7
  class S3Assets extends pulumi.ComponentResource {
8
+ name;
9
+ bucket;
10
+ websiteConfig;
8
11
  constructor(name, args, opts = {}) {
9
12
  super('studion:static-site:S3Assets', name, {}, opts);
10
13
  this.name = name;
@@ -30,7 +33,7 @@ class S3Assets extends pulumi.ComponentResource {
30
33
  createWebsiteBucket(bucketPrefix, indexDocument, errorDocument, tags) {
31
34
  const bucket = new aws.s3.Bucket(`${this.name}-bucket`, {
32
35
  bucketPrefix,
33
- tags: Object.assign(Object.assign({}, common_tags_1.commonTags), tags),
36
+ tags: { ...common_tags_1.commonTags, ...tags },
34
37
  }, { parent: this });
35
38
  const config = new aws.s3.BucketWebsiteConfiguration(`${this.name}-bucket-website-config`, {
36
39
  bucket: bucket.id,
@@ -10,6 +10,7 @@ exports.defaults = {
10
10
  numberOfAvailabilityZones: 2,
11
11
  };
12
12
  class Vpc extends pulumi.ComponentResource {
13
+ vpc;
13
14
  constructor(name, args, opts = {}) {
14
15
  super('studion:vpc:Vpc', name, {}, opts);
15
16
  const argsWithDefaults = (0, merge_with_defaults_1.mergeWithDefaults)(exports.defaults, args);
@@ -26,7 +27,7 @@ class Vpc extends pulumi.ComponentResource {
26
27
  { type: awsx.ec2.SubnetType.Public, cidrMask: 24 },
27
28
  { type: awsx.ec2.SubnetType.Isolated, cidrMask: 24 },
28
29
  ],
29
- tags: Object.assign(Object.assign({}, common_tags_1.commonTags), argsWithDefaults.tags),
30
+ tags: { ...common_tags_1.commonTags, ...argsWithDefaults.tags },
30
31
  }, { parent: this });
31
32
  this.registerOutputs();
32
33
  }
@@ -4,15 +4,28 @@ exports.WebServerBuilder = void 0;
4
4
  const pulumi = require("@pulumi/pulumi");
5
5
  const _1 = require(".");
6
6
  class WebServerBuilder {
7
+ _name;
8
+ _container;
9
+ _vpc;
10
+ _ecsConfig;
11
+ _domain;
12
+ _hostedZoneId;
13
+ _certificate;
14
+ _healthCheckPath;
15
+ _loadBalancingAlgorithmType;
16
+ _otelCollector;
17
+ _initContainers = [];
18
+ _sidecarContainers = [];
19
+ _volumes = [];
7
20
  constructor(name) {
8
- this._initContainers = [];
9
- this._sidecarContainers = [];
10
- this._volumes = [];
11
21
  this._name = name;
12
22
  }
13
23
  withContainer(image, port, config = {}) {
14
- this._container = Object.assign({ image,
15
- port }, config);
24
+ this._container = {
25
+ image,
26
+ port,
27
+ ...config,
28
+ };
16
29
  return this;
17
30
  }
18
31
  withEcsConfig(config) {
@@ -80,7 +93,20 @@ class WebServerBuilder {
80
93
  if (!this._vpc) {
81
94
  throw new Error('VPC not provided. Make sure to call WebServerBuilder.withVpc().');
82
95
  }
83
- return new _1.WebServer(this._name, Object.assign(Object.assign(Object.assign({}, this._ecsConfig), this._container), { vpc: this._vpc, volumes: this._volumes, domain: this._domain, hostedZoneId: this._hostedZoneId, certificate: this._certificate, healthCheckPath: this._healthCheckPath, loadBalancingAlgorithmType: this._loadBalancingAlgorithmType, otelCollector: this._otelCollector, initContainers: this._initContainers, sidecarContainers: this._sidecarContainers }), opts);
96
+ return new _1.WebServer(this._name, {
97
+ ...this._ecsConfig,
98
+ ...this._container,
99
+ vpc: this._vpc,
100
+ volumes: this._volumes,
101
+ domain: this._domain,
102
+ hostedZoneId: this._hostedZoneId,
103
+ certificate: this._certificate,
104
+ healthCheckPath: this._healthCheckPath,
105
+ loadBalancingAlgorithmType: this._loadBalancingAlgorithmType,
106
+ otelCollector: this._otelCollector,
107
+ initContainers: this._initContainers,
108
+ sidecarContainers: this._sidecarContainers,
109
+ }, opts);
84
110
  }
85
111
  }
86
112
  exports.WebServerBuilder = WebServerBuilder;
@@ -8,9 +8,22 @@ const acm_certificate_1 = require("../acm-certificate");
8
8
  const ecs_service_1 = require("../ecs-service");
9
9
  const load_balancer_1 = require("./load-balancer");
10
10
  class WebServer extends pulumi.ComponentResource {
11
+ name;
12
+ container;
13
+ ecsConfig;
14
+ service;
15
+ serviceSecurityGroup;
16
+ lb;
17
+ initContainers;
18
+ sidecarContainers;
19
+ volumes;
20
+ acmCertificate;
21
+ dnsRecords;
11
22
  constructor(name, args, opts = {}) {
12
- var _a;
13
- super('studion:web-server:WebServer', name, {}, Object.assign(Object.assign({}, opts), { aliases: [...(opts.aliases || []), { type: 'studion:WebServer' }] }));
23
+ super('studion:web-server:WebServer', name, {}, {
24
+ ...opts,
25
+ aliases: [...(opts.aliases || []), { type: 'studion:WebServer' }],
26
+ });
14
27
  const { vpc, domain, hostedZoneId, certificate } = args;
15
28
  const hasCustomDomain = !!domain || !!certificate;
16
29
  if (hasCustomDomain && !hostedZoneId) {
@@ -23,12 +36,15 @@ class WebServer extends pulumi.ComponentResource {
23
36
  this.lb = new load_balancer_1.WebServerLoadBalancer(`${this.name}-lb`, {
24
37
  vpc,
25
38
  port: args.port,
26
- certificate: certificate !== null && certificate !== void 0 ? certificate : (_a = this.acmCertificate) === null || _a === void 0 ? void 0 : _a.certificate,
39
+ certificate: certificate ?? this.acmCertificate?.certificate,
27
40
  healthCheckPath: args.healthCheckPath,
28
41
  loadBalancingAlgorithmType: args.loadBalancingAlgorithmType,
29
- }, Object.assign({ parent: this }, (this.acmCertificate
30
- ? { dependsOn: [this.acmCertificate.certificateValidation] }
31
- : undefined)));
42
+ }, {
43
+ parent: this,
44
+ ...(this.acmCertificate
45
+ ? { dependsOn: [this.acmCertificate.certificateValidation] }
46
+ : undefined),
47
+ });
32
48
  this.serviceSecurityGroup = this.createSecurityGroup(vpc);
33
49
  this.initContainers = this.getInitContainers(args);
34
50
  this.sidecarContainers = this.getSidecarContainers(args);
@@ -37,7 +53,7 @@ class WebServer extends pulumi.ComponentResource {
37
53
  this.volumes = this.getVolumes(args);
38
54
  this.service = this.createEcsService(this.container, this.lb, this.ecsConfig, this.volumes, this.initContainers, this.sidecarContainers);
39
55
  if (hasCustomDomain && hostedZoneId) {
40
- this.dnsRecords = this.createDnsRecords(certificate !== null && certificate !== void 0 ? certificate : this.acmCertificate.certificate, hostedZoneId, domain);
56
+ this.dnsRecords = this.createDnsRecords(certificate ?? this.acmCertificate.certificate, hostedZoneId, domain);
41
57
  }
42
58
  this.registerOutputs();
43
59
  }
@@ -62,7 +78,10 @@ class WebServer extends pulumi.ComponentResource {
62
78
  containers.push(...passedInits);
63
79
  if (otelCollector)
64
80
  containers.push(otelCollector.configContainer);
65
- return containers.map(container => (Object.assign(Object.assign({}, container), { essential: false })));
81
+ return containers.map(container => ({
82
+ ...container,
83
+ essential: false,
84
+ }));
66
85
  });
67
86
  }
68
87
  getSidecarContainers(args) {
@@ -74,7 +93,7 @@ class WebServer extends pulumi.ComponentResource {
74
93
  containers.push(...passedSidecars);
75
94
  if (otelCollector)
76
95
  containers.push(otelCollector.container);
77
- return containers.map(container => (Object.assign(Object.assign({}, container), { essential: true })));
96
+ return containers.map(container => ({ ...container, essential: true }));
78
97
  });
79
98
  }
80
99
  getTaskRoleInlinePolicies(args) {
@@ -154,19 +173,32 @@ class WebServer extends pulumi.ComponentResource {
154
173
  sidecarContainers || pulumi.output([]),
155
174
  ])
156
175
  .apply(([inits, sidecars]) => {
157
- return new ecs_service_1.EcsService(`${this.name}-ecs`, Object.assign(Object.assign({}, ecsConfig), { volumes, containers: [
158
- Object.assign(Object.assign({}, webServerContainer), { name: this.name, portMappings: [
176
+ return new ecs_service_1.EcsService(`${this.name}-ecs`, {
177
+ ...ecsConfig,
178
+ volumes,
179
+ containers: [
180
+ {
181
+ ...webServerContainer,
182
+ name: this.name,
183
+ portMappings: [
159
184
  ecs_service_1.EcsService.createTcpPortMapping(webServerContainer.port),
160
- ], essential: true }),
185
+ ],
186
+ essential: true,
187
+ },
161
188
  ...inits,
162
189
  ...sidecars,
163
- ], enableServiceAutoDiscovery: false, loadBalancers: [
190
+ ],
191
+ enableServiceAutoDiscovery: false,
192
+ loadBalancers: [
164
193
  {
165
194
  containerName: this.name,
166
195
  containerPort: webServerContainer.port,
167
196
  targetGroupArn: lb.targetGroup.arn,
168
197
  },
169
- ], assignPublicIp: true, securityGroup: this.serviceSecurityGroup }), {
198
+ ],
199
+ assignPublicIp: true,
200
+ securityGroup: this.serviceSecurityGroup,
201
+ }, {
170
202
  parent: this,
171
203
  dependsOn: [lb, lb.targetGroup],
172
204
  });
@@ -176,7 +208,7 @@ class WebServer extends pulumi.ComponentResource {
176
208
  const certOutput = pulumi.output(certificate);
177
209
  return pulumi
178
210
  .all([domain, certOutput.domainName, certOutput.subjectAlternativeNames])
179
- .apply(([domain, certDomain, certSans = []]) => (domain ? [domain] : [...new Set([certDomain, ...certSans])]).map((alias, index) => new aws.route53.Record(`${this.name}-route53-record${index === 0 ? '' : `-${index}`}`, {
211
+ .apply(([domain, certDomain, certSans = []]) => (domain ? [domain] : [...new Set([certDomain, ...certSans])]).map((alias, index) => new aws.route53.Record(`${this.name}-dns-a-record-${index}`, {
180
212
  type: 'A',
181
213
  name: alias,
182
214
  zoneId: hostedZoneId,
@@ -33,6 +33,12 @@ const defaults = {
33
33
  healthCheckPath: '/healthcheck',
34
34
  };
35
35
  class WebServerLoadBalancer extends pulumi.ComponentResource {
36
+ name;
37
+ lb;
38
+ targetGroup;
39
+ httpListener;
40
+ tlsListener;
41
+ securityGroup;
36
42
  constructor(name, args, opts = {}) {
37
43
  super('studion:web-server:WebServerLoadBalancer', name, {}, opts);
38
44
  this.name = name;
@@ -47,7 +53,7 @@ class WebServerLoadBalancer extends pulumi.ComponentResource {
47
53
  securityGroups: [this.securityGroup.id],
48
54
  internal: false,
49
55
  ipAddressType: 'ipv4',
50
- tags: Object.assign(Object.assign({}, common_tags_1.commonTags), { Name: name }),
56
+ tags: { ...common_tags_1.commonTags, Name: name },
51
57
  }, { parent: this });
52
58
  this.targetGroup = this.createLbTargetGroup(port, vpc.vpcId, healthCheckPath, loadBalancingAlgorithmType);
53
59
  this.httpListener = this.createLbHttpListener(this.lb, this.targetGroup, !!certificate);
@@ -109,11 +115,15 @@ class WebServerLoadBalancer extends pulumi.ComponentResource {
109
115
  timeout: 5,
110
116
  path: healthCheckPath,
111
117
  },
112
- tags: Object.assign(Object.assign({}, common_tags_1.commonTags), { Name: `${this.name}-target-group` }),
118
+ tags: { ...common_tags_1.commonTags, Name: `${this.name}-target-group` },
113
119
  }, { parent: this, dependsOn: [this.lb] });
114
120
  }
115
121
  createLbSecurityGroup(vpcId) {
116
- return new aws.ec2.SecurityGroup(`${this.name}-security-group`, Object.assign(Object.assign({}, webServerLoadBalancerNetworkConfig), { vpcId, tags: common_tags_1.commonTags }), { parent: this });
122
+ return new aws.ec2.SecurityGroup(`${this.name}-security-group`, {
123
+ ...webServerLoadBalancerNetworkConfig,
124
+ vpcId,
125
+ tags: common_tags_1.commonTags,
126
+ }, { parent: this });
117
127
  }
118
128
  }
119
129
  exports.WebServerLoadBalancer = WebServerLoadBalancer;
@@ -7,8 +7,11 @@ const memoryLimiterProcessor = require("./memory-limiter-processor");
7
7
  const _1 = require(".");
8
8
  const config_1 = require("./config");
9
9
  class OtelCollectorBuilder {
10
+ _serviceName;
11
+ _env;
12
+ _configBuilder;
13
+ _taskRoleInlinePolicies = [];
10
14
  constructor(serviceName, env) {
11
- this._taskRoleInlinePolicies = [];
12
15
  this._serviceName = pulumi.output(serviceName);
13
16
  this._env = pulumi.output(env);
14
17
  this._configBuilder = new config_1.OtelCollectorConfigBuilder();