@codedazur/cdk-docker-cluster 0.4.0 → 0.5.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @codedazur/cdk-docker-cluster
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`d9e51b0`](https://github.com/codedazur/toolkit/commit/d9e51b0e2fb36d64c641ae341124b0fb2bd298df) Thanks [@thijsdaniels](https://github.com/thijsdaniels)! - An unused certificate resource was removed.
8
+
9
+ - Updated dependencies [[`d9e51b0`](https://github.com/codedazur/toolkit/commit/d9e51b0e2fb36d64c641ae341124b0fb2bd298df)]:
10
+ - @codedazur/cdk-site-distribution@0.1.2
11
+
12
+ ## 0.5.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [`d1f3d51`](https://github.com/codedazur/toolkit/commit/d1f3d512d31d659ffdc115147d9631057fe8d073) Thanks [@thijsdaniels](https://github.com/thijsdaniels)! - Support for a custom domain name was added.
17
+
18
+ ### Patch Changes
19
+
20
+ - [`17034ee`](https://github.com/codedazur/toolkit/commit/17034ee5fcbc026fc779a12130572d515d2b8298) Thanks [@thijsdaniels](https://github.com/thijsdaniels)! - Dependency versions were made explicit.
21
+
22
+ - [`737fe0d`](https://github.com/codedazur/toolkit/commit/737fe0ddd4d353db1e005d2dab886a4a60bc02d8) Thanks [@thijsdaniels](https://github.com/thijsdaniels)! - The build environment prop was renamed to arguments.
23
+
24
+ - Updated dependencies [[`17034ee`](https://github.com/codedazur/toolkit/commit/17034ee5fcbc026fc779a12130572d515d2b8298), [`d1f3d51`](https://github.com/codedazur/toolkit/commit/d1f3d512d31d659ffdc115147d9631057fe8d073)]:
25
+ - @codedazur/cdk-site-distribution@0.1.0
26
+
3
27
  ## 0.4.0
4
28
 
5
29
  ### Minor Changes
package/README.md CHANGED
@@ -2,16 +2,112 @@
2
2
 
3
3
  This construct creates a load balanced Fargate service, for which it builds a Docker image from a local directory. A CloudFront distribution is connected to the load balancer.
4
4
 
5
+ ## Examples
6
+
7
+ The minimum needed to get a DockerCluster up and running is a path to the source directory that contains a Dockerfile, relative to the CDK app, and the port on which your container needs to be accessible.
8
+
5
9
  ```ts
6
- new DockerCluster({
7
- path: "../../", // path to Docker build context
8
- file: "apps/myApp/DockerFile", // path to Dockerfile
10
+ new DockerCluster(this, "DockerCluster", {
11
+ source: "../path/to/source",
9
12
  port: 3000,
13
+ });
14
+ ```
15
+
16
+ ### With Monorepo Build
17
+
18
+ If your Dockerfile is not located directly in the build context directory, which is common for monorepositories, you can provide the path to the Dockerfile relative to the source directory.
19
+
20
+ ```ts
21
+ new DockerCluster({
22
+ source: {
23
+ directory: "../path/to/source",
24
+ file: "./apps/myApp/DockerFile",
25
+ },
26
+ // ...
27
+ });
28
+ ```
29
+
30
+ ### With Arguments and Secrets
31
+
32
+ Additionally, if your Dockerfile requires arguments and/or secrets, you can provide those as well.
33
+
34
+ ```ts
35
+ new DockerCluster({
36
+ source: {
37
+ // ...
38
+ arguments: {
39
+ MY_BUILD_ARGUMENT: "foo",
40
+ },
41
+ secrets: {
42
+ myBuildSecret: DockerBuildSecret.fromSrc("./foo"),
43
+ },
44
+ },
45
+ // ...
46
+ });
47
+ ```
48
+
49
+ ### With ContainerImage
50
+
51
+ Alternatively, you can provide your own `ContainerImage` instance. There are many ways to construct a `ContainerImage`. For example, you can create one from an asset and take full control over how CDK builds your Docker image.
52
+
53
+ ```ts
54
+ new DockerCluster({
55
+ source: ContainerImage.fromAsset("../path/to/source", {
56
+ // ...
57
+ }),
58
+ // ...
59
+ });
60
+ ```
61
+
62
+ Or, if you want to build your Docker image outside of CDK, you can create a `ContainerImage` from a path to your image's tarball.
63
+
64
+ ```ts
65
+ new DockerCluster({
66
+ source: ContainerImage.fromTarball("./path/to/image.tar"),
67
+ // ...
68
+ });
69
+ ```
70
+
71
+ Or if the image you need is published to a registry, you can create your
72
+ `ContainerImage` from a registry path. You can provide credentials in case the registry is private.
73
+
74
+ ```ts
75
+ new DockerCluster({
76
+ source: ContainerImage.fromRegistry("node:20"),
77
+ // ...
78
+ });
79
+ ```
80
+
81
+ Finally, you can create a `ContainerImage` from an image that you have published to an ECR repository.
82
+
83
+ ```ts
84
+ new DockerCluster({
85
+ source: ContainerImage.fromEcrRepository(myRespository, "my-tag"),
86
+ // ...
87
+ });
88
+ ```
89
+
90
+ ### With Scaling
91
+
92
+ The `DockerCluster` construct supports both vertical and horizontal scaling.
93
+
94
+ ```ts
95
+ new DockerCluster(this, "DockerCluster", {
96
+ // ...
10
97
  cpu: 1024, // 1vCPU
11
98
  memory: 4096, // 4GB
12
- tasks: { minimum: 1, maximum: 10 },
13
- secrets: {
14
- foo: DockerBuildSecret.fromSrc("./foo"),
99
+ tasks: 3,
100
+ });
101
+ ```
102
+
103
+ Horizontal auto-scaling is also supported.
104
+
105
+ ```ts
106
+ new DockerCluster(this, "DockerCluster", {
107
+ // ...
108
+ tasks: {
109
+ minimum: 1,
110
+ maximum: 5,
15
111
  },
16
112
  });
17
113
  ```
package/dist/index.d.mts CHANGED
@@ -1,10 +1,11 @@
1
- import { ApplicationLoadBalancedFargateServiceProps } from 'aws-cdk-lib/aws-ecs-patterns';
1
+ import * as aws_cdk_lib_aws_ecs from 'aws-cdk-lib/aws-ecs';
2
+ import { ContainerImage } from 'aws-cdk-lib/aws-ecs';
3
+ import { SiteDistributionProps, SiteDistribution } from '@codedazur/cdk-site-distribution';
4
+ import { ApplicationLoadBalancedFargateServiceProps, ApplicationLoadBalancedFargateService } from 'aws-cdk-lib/aws-ecs-patterns';
2
5
  import { Construct } from 'constructs';
3
6
 
4
7
  interface DockerClusterProps {
5
- path: string;
6
- file?: string;
7
- secrets?: Record<string, string>;
8
+ source: string | SourceProps | ContainerImage;
8
9
  port?: number;
9
10
  tasks?: number | {
10
11
  minimum: number;
@@ -12,17 +13,30 @@ interface DockerClusterProps {
12
13
  };
13
14
  cpu?: ApplicationLoadBalancedFargateServiceProps["cpu"];
14
15
  memory?: ApplicationLoadBalancedFargateServiceProps["memoryLimitMiB"];
15
- environment?: {
16
- buildtime?: Record<string, string>;
17
- runtime?: Record<string, string>;
18
- };
16
+ distribution?: Omit<SiteDistributionProps, "origin">;
17
+ }
18
+ interface SourceProps {
19
+ directory: string;
20
+ exclude?: string[];
21
+ file?: string;
22
+ arguments?: Record<string, string>;
23
+ secrets?: Record<string, string>;
19
24
  }
20
25
  /**
21
26
  * An Docker cluster on a load balanced Fargate service on EC2, using an image
22
27
  * built from a Dockerfile in a directory and pushed to ECR.
23
28
  */
24
29
  declare class DockerCluster extends Construct {
30
+ protected readonly props: DockerClusterProps;
31
+ readonly domain?: string;
32
+ readonly image: ContainerImage;
33
+ readonly service: ApplicationLoadBalancedFargateService;
34
+ readonly distribution: SiteDistribution;
25
35
  constructor(scope: Construct, id: string, props: DockerClusterProps);
36
+ protected createImage(source: string | SourceProps): aws_cdk_lib_aws_ecs.AssetImage;
37
+ protected createService(): ApplicationLoadBalancedFargateService;
38
+ protected createDistribution(): SiteDistribution;
39
+ protected getOutputDirectory(): string;
26
40
  }
27
41
 
28
- export { DockerCluster, DockerClusterProps };
42
+ export { DockerCluster, type DockerClusterProps };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { ApplicationLoadBalancedFargateServiceProps } from 'aws-cdk-lib/aws-ecs-patterns';
1
+ import * as aws_cdk_lib_aws_ecs from 'aws-cdk-lib/aws-ecs';
2
+ import { ContainerImage } from 'aws-cdk-lib/aws-ecs';
3
+ import { SiteDistributionProps, SiteDistribution } from '@codedazur/cdk-site-distribution';
4
+ import { ApplicationLoadBalancedFargateServiceProps, ApplicationLoadBalancedFargateService } from 'aws-cdk-lib/aws-ecs-patterns';
2
5
  import { Construct } from 'constructs';
3
6
 
4
7
  interface DockerClusterProps {
5
- path: string;
6
- file?: string;
7
- secrets?: Record<string, string>;
8
+ source: string | SourceProps | ContainerImage;
8
9
  port?: number;
9
10
  tasks?: number | {
10
11
  minimum: number;
@@ -12,17 +13,30 @@ interface DockerClusterProps {
12
13
  };
13
14
  cpu?: ApplicationLoadBalancedFargateServiceProps["cpu"];
14
15
  memory?: ApplicationLoadBalancedFargateServiceProps["memoryLimitMiB"];
15
- environment?: {
16
- buildtime?: Record<string, string>;
17
- runtime?: Record<string, string>;
18
- };
16
+ distribution?: Omit<SiteDistributionProps, "origin">;
17
+ }
18
+ interface SourceProps {
19
+ directory: string;
20
+ exclude?: string[];
21
+ file?: string;
22
+ arguments?: Record<string, string>;
23
+ secrets?: Record<string, string>;
19
24
  }
20
25
  /**
21
26
  * An Docker cluster on a load balanced Fargate service on EC2, using an image
22
27
  * built from a Dockerfile in a directory and pushed to ECR.
23
28
  */
24
29
  declare class DockerCluster extends Construct {
30
+ protected readonly props: DockerClusterProps;
31
+ readonly domain?: string;
32
+ readonly image: ContainerImage;
33
+ readonly service: ApplicationLoadBalancedFargateService;
34
+ readonly distribution: SiteDistribution;
25
35
  constructor(scope: Construct, id: string, props: DockerClusterProps);
36
+ protected createImage(source: string | SourceProps): aws_cdk_lib_aws_ecs.AssetImage;
37
+ protected createService(): ApplicationLoadBalancedFargateService;
38
+ protected createDistribution(): SiteDistribution;
39
+ protected getOutputDirectory(): string;
26
40
  }
27
41
 
28
- export { DockerCluster, DockerClusterProps };
42
+ export { DockerCluster, type DockerClusterProps };
package/dist/index.js CHANGED
@@ -25,7 +25,8 @@ __export(src_exports, {
25
25
  module.exports = __toCommonJS(src_exports);
26
26
 
27
27
  // src/constructs/DockerCluster.ts
28
- var import_cdk_cache_invalidator = require("@codedazur/cdk-cache-invalidator");
28
+ var import_cdk_site_distribution = require("@codedazur/cdk-site-distribution");
29
+ var import_aws_cdk_lib = require("aws-cdk-lib");
29
30
  var import_aws_cloudfront = require("aws-cdk-lib/aws-cloudfront");
30
31
  var import_aws_cloudfront_origins = require("aws-cdk-lib/aws-cloudfront-origins");
31
32
  var import_aws_ecr_assets = require("aws-cdk-lib/aws-ecr-assets");
@@ -34,53 +35,65 @@ var import_aws_ecs_patterns = require("aws-cdk-lib/aws-ecs-patterns");
34
35
  var import_constructs = require("constructs");
35
36
  var DockerCluster = class extends import_constructs.Construct {
36
37
  constructor(scope, id, props) {
37
- var _a, _b, _c;
38
38
  super(scope, id);
39
- const image = new import_aws_ecr_assets.DockerImageAsset(this, "Image", {
40
- directory: props.path,
41
- file: props.file,
42
- exclude: ["**/cdk.out"],
43
- buildSecrets: props.secrets,
44
- platform: import_aws_ecr_assets.Platform.LINUX_AMD64,
45
- buildArgs: (_a = props.environment) == null ? void 0 : _a.buildtime
39
+ this.props = props;
40
+ this.image = this.props.source instanceof import_aws_ecs.ContainerImage ? this.props.source : this.createImage(this.props.source);
41
+ this.service = this.createService();
42
+ this.distribution = this.createDistribution();
43
+ }
44
+ createImage(source) {
45
+ const props = {
46
+ exclude: [`**/${this.getOutputDirectory()}`],
47
+ platform: import_aws_ecr_assets.Platform.LINUX_AMD64
48
+ };
49
+ if (typeof source === "string") {
50
+ return import_aws_ecs.ContainerImage.fromAsset(source, props);
51
+ }
52
+ return import_aws_ecs.ContainerImage.fromAsset(source.directory, {
53
+ ...props,
54
+ file: source.file,
55
+ buildArgs: source.arguments,
56
+ buildSecrets: source.secrets
46
57
  });
47
- const desiredTasks = typeof props.tasks === "number" ? props.tasks : (_b = props.tasks) == null ? void 0 : _b.minimum;
48
- const fargate = new import_aws_ecs_patterns.ApplicationLoadBalancedFargateService(this, "Service", {
58
+ }
59
+ createService() {
60
+ var _a;
61
+ const desiredTasks = typeof this.props.tasks === "number" ? this.props.tasks : (_a = this.props.tasks) == null ? void 0 : _a.minimum;
62
+ const service = new import_aws_ecs_patterns.ApplicationLoadBalancedFargateService(this, "Service", {
49
63
  cluster: new import_aws_ecs.Cluster(this, "Cluster"),
50
- cpu: props.cpu,
51
- memoryLimitMiB: props.memory,
64
+ cpu: this.props.cpu,
65
+ memoryLimitMiB: this.props.memory,
52
66
  desiredCount: desiredTasks,
53
67
  taskImageOptions: {
54
- // image: ContainerImage.fromEcrRepository(image.repository, image.imageTag),
55
- image: import_aws_ecs.ContainerImage.fromDockerImageAsset(image),
56
- containerPort: props.port,
57
- environment: (_c = props.environment) == null ? void 0 : _c.runtime
68
+ image: this.image,
69
+ containerPort: this.props.port
58
70
  },
59
71
  circuitBreaker: {
60
72
  enable: true,
61
73
  rollback: true
62
- }
63
- // @todo certificate: ...
64
- // @todo publicLoadBalancer: false,
74
+ },
75
+ publicLoadBalancer: false
65
76
  });
66
- if (typeof props.tasks === "object") {
67
- fargate.service.autoScaleTaskCount({
68
- minCapacity: props.tasks.minimum,
69
- maxCapacity: props.tasks.maximum
77
+ if (typeof this.props.tasks === "object") {
78
+ this.service.service.autoScaleTaskCount({
79
+ minCapacity: this.props.tasks.minimum,
80
+ maxCapacity: this.props.tasks.maximum
70
81
  });
71
82
  }
72
- const distribution = new import_aws_cloudfront.Distribution(this, "Distribution", {
73
- defaultBehavior: {
74
- origin: new import_aws_cloudfront_origins.LoadBalancerV2Origin(fargate.loadBalancer, {
75
- protocolPolicy: import_aws_cloudfront.OriginProtocolPolicy.HTTP_ONLY
76
- // @todo OriginProtocolPolicy.HTTPS_ONLY
77
- })
78
- }
79
- });
80
- new import_cdk_cache_invalidator.CacheInvalidator(this, "CacheInvalidator", {
81
- distribution
83
+ return service;
84
+ }
85
+ createDistribution() {
86
+ return new import_cdk_site_distribution.SiteDistribution(this, "Distribution", {
87
+ ...this.props.distribution,
88
+ origin: new import_aws_cloudfront_origins.LoadBalancerV2Origin(this.service.loadBalancer, {
89
+ protocolPolicy: import_aws_cloudfront.OriginProtocolPolicy.HTTP_ONLY
90
+ })
82
91
  });
83
92
  }
93
+ getOutputDirectory() {
94
+ var _a, _b;
95
+ return (_b = (_a = import_aws_cdk_lib.App.of(this)) == null ? void 0 : _a.outdir) != null ? _b : "cdk.out";
96
+ }
84
97
  };
85
98
  // Annotate the CommonJS export names for ESM import in node:
86
99
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1,8 +1,11 @@
1
1
  // src/constructs/DockerCluster.ts
2
- import { CacheInvalidator } from "@codedazur/cdk-cache-invalidator";
3
- import { Distribution, OriginProtocolPolicy } from "aws-cdk-lib/aws-cloudfront";
2
+ import {
3
+ SiteDistribution
4
+ } from "@codedazur/cdk-site-distribution";
5
+ import { App } from "aws-cdk-lib";
6
+ import { OriginProtocolPolicy } from "aws-cdk-lib/aws-cloudfront";
4
7
  import { LoadBalancerV2Origin } from "aws-cdk-lib/aws-cloudfront-origins";
5
- import { DockerImageAsset, Platform } from "aws-cdk-lib/aws-ecr-assets";
8
+ import { Platform } from "aws-cdk-lib/aws-ecr-assets";
6
9
  import { Cluster, ContainerImage } from "aws-cdk-lib/aws-ecs";
7
10
  import {
8
11
  ApplicationLoadBalancedFargateService
@@ -10,53 +13,65 @@ import {
10
13
  import { Construct } from "constructs";
11
14
  var DockerCluster = class extends Construct {
12
15
  constructor(scope, id, props) {
13
- var _a, _b, _c;
14
16
  super(scope, id);
15
- const image = new DockerImageAsset(this, "Image", {
16
- directory: props.path,
17
- file: props.file,
18
- exclude: ["**/cdk.out"],
19
- buildSecrets: props.secrets,
20
- platform: Platform.LINUX_AMD64,
21
- buildArgs: (_a = props.environment) == null ? void 0 : _a.buildtime
17
+ this.props = props;
18
+ this.image = this.props.source instanceof ContainerImage ? this.props.source : this.createImage(this.props.source);
19
+ this.service = this.createService();
20
+ this.distribution = this.createDistribution();
21
+ }
22
+ createImage(source) {
23
+ const props = {
24
+ exclude: [`**/${this.getOutputDirectory()}`],
25
+ platform: Platform.LINUX_AMD64
26
+ };
27
+ if (typeof source === "string") {
28
+ return ContainerImage.fromAsset(source, props);
29
+ }
30
+ return ContainerImage.fromAsset(source.directory, {
31
+ ...props,
32
+ file: source.file,
33
+ buildArgs: source.arguments,
34
+ buildSecrets: source.secrets
22
35
  });
23
- const desiredTasks = typeof props.tasks === "number" ? props.tasks : (_b = props.tasks) == null ? void 0 : _b.minimum;
24
- const fargate = new ApplicationLoadBalancedFargateService(this, "Service", {
36
+ }
37
+ createService() {
38
+ var _a;
39
+ const desiredTasks = typeof this.props.tasks === "number" ? this.props.tasks : (_a = this.props.tasks) == null ? void 0 : _a.minimum;
40
+ const service = new ApplicationLoadBalancedFargateService(this, "Service", {
25
41
  cluster: new Cluster(this, "Cluster"),
26
- cpu: props.cpu,
27
- memoryLimitMiB: props.memory,
42
+ cpu: this.props.cpu,
43
+ memoryLimitMiB: this.props.memory,
28
44
  desiredCount: desiredTasks,
29
45
  taskImageOptions: {
30
- // image: ContainerImage.fromEcrRepository(image.repository, image.imageTag),
31
- image: ContainerImage.fromDockerImageAsset(image),
32
- containerPort: props.port,
33
- environment: (_c = props.environment) == null ? void 0 : _c.runtime
46
+ image: this.image,
47
+ containerPort: this.props.port
34
48
  },
35
49
  circuitBreaker: {
36
50
  enable: true,
37
51
  rollback: true
38
- }
39
- // @todo certificate: ...
40
- // @todo publicLoadBalancer: false,
52
+ },
53
+ publicLoadBalancer: false
41
54
  });
42
- if (typeof props.tasks === "object") {
43
- fargate.service.autoScaleTaskCount({
44
- minCapacity: props.tasks.minimum,
45
- maxCapacity: props.tasks.maximum
55
+ if (typeof this.props.tasks === "object") {
56
+ this.service.service.autoScaleTaskCount({
57
+ minCapacity: this.props.tasks.minimum,
58
+ maxCapacity: this.props.tasks.maximum
46
59
  });
47
60
  }
48
- const distribution = new Distribution(this, "Distribution", {
49
- defaultBehavior: {
50
- origin: new LoadBalancerV2Origin(fargate.loadBalancer, {
51
- protocolPolicy: OriginProtocolPolicy.HTTP_ONLY
52
- // @todo OriginProtocolPolicy.HTTPS_ONLY
53
- })
54
- }
55
- });
56
- new CacheInvalidator(this, "CacheInvalidator", {
57
- distribution
61
+ return service;
62
+ }
63
+ createDistribution() {
64
+ return new SiteDistribution(this, "Distribution", {
65
+ ...this.props.distribution,
66
+ origin: new LoadBalancerV2Origin(this.service.loadBalancer, {
67
+ protocolPolicy: OriginProtocolPolicy.HTTP_ONLY
68
+ })
58
69
  });
59
70
  }
71
+ getOutputDirectory() {
72
+ var _a, _b;
73
+ return (_b = (_a = App.of(this)) == null ? void 0 : _a.outdir) != null ? _b : "cdk.out";
74
+ }
60
75
  };
61
76
  export {
62
77
  DockerCluster
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codedazur/cdk-docker-cluster",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "main": ".dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -22,22 +22,17 @@
22
22
  "types": "tsc --noEmit",
23
23
  "test": "vitest run --passWithNoTests"
24
24
  },
25
- "dependencies": {
26
- "@codedazur/cdk-cache-invalidator": "*"
27
- },
28
25
  "peerDependencies": {
29
26
  "aws-cdk-lib": ">=2",
30
27
  "constructs": ">=10"
31
28
  },
29
+ "dependencies": {
30
+ "@codedazur/cdk-site-distribution": "^0.1.2"
31
+ },
32
32
  "devDependencies": {
33
- "@codedazur/eslint-config": "*",
34
- "@codedazur/tsconfig": "*",
35
- "@types/node": "^20.14.2",
36
- "aws-cdk-lib": "^2.145.0",
33
+ "@types/node": "^20.14.9",
34
+ "aws-cdk-lib": "^2.147.2",
37
35
  "constructs": "^10.3.0",
38
- "esbuild": "^0.20.2",
39
- "eslint": "^8.30.0",
40
- "tsconfig": "*",
41
- "typescript": "^5.4.5"
36
+ "esbuild": "^0.21.5"
42
37
  }
43
38
  }
package/tsconfig.json CHANGED
@@ -1,5 +1,3 @@
1
1
  {
2
- "extends": "@codedazur/tsconfig/cdk.json",
3
- "include": ["."],
4
- "exclude": ["dist", "build", "node_modules"]
2
+ "extends": "@codedazur/tsconfig/cdk.json"
5
3
  }