@mavogel/cdk-vscode-server 0.0.54 → 0.0.56

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 (62) hide show
  1. package/.claude/hooks/file_checker.sh +0 -0
  2. package/.jsii +96 -24
  3. package/API.md +56 -0
  4. package/CLAUDE.md +84 -118
  5. package/README.md +48 -0
  6. package/assets/installer/installer.lambda/index.js +14 -2
  7. package/examples/custom-domain/main.ts +49 -0
  8. package/integ-tests/integ.al2023.ts.snapshot/IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645.assets.json +7 -6
  9. package/integ-tests/integ.al2023.ts.snapshot/IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645.template.json +6 -6
  10. package/integ-tests/integ.al2023.ts.snapshot/IntegTestStackAl2023.assets.json +20 -12
  11. package/integ-tests/integ.al2023.ts.snapshot/IntegTestStackAl2023.template.json +36 -152
  12. package/integ-tests/integ.al2023.ts.snapshot/{asset.23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce → asset.0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4}/index.js +988 -1165
  13. package/integ-tests/{integ.ubuntu.ts.snapshot/asset.a9865c9d36c7aa999e28cb7926e7a3a8e0b6d0854b25131a172024c5777442fa.lambda → integ.al2023.ts.snapshot/asset.33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.lambda}/index.js +14 -2
  14. package/integ-tests/{integ.ubuntu.ts.snapshot/asset.f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd.bundle → integ.al2023.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle}/index.js +296 -191
  15. package/integ-tests/{integ.ubuntu.ts.snapshot/asset.ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a → integ.al2023.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00}/index.js +1 -1
  16. package/integ-tests/integ.al2023.ts.snapshot/cdk.out +1 -1
  17. package/integ-tests/integ.al2023.ts.snapshot/integ.json +4 -3
  18. package/integ-tests/integ.al2023.ts.snapshot/manifest.json +956 -7
  19. package/integ-tests/integ.al2023.ts.snapshot/tree.json +1 -3228
  20. package/integ-tests/integ.custom-domain.ts +87 -0
  21. package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.assets.json +33 -0
  22. package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.template.json +333 -0
  23. package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.assets.json +132 -0
  24. package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.template.json +2862 -0
  25. package/integ-tests/{integ.ubuntu.ts.snapshot/asset.23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce → integ.custom-domain.ts.snapshot/asset.0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4}/index.js +988 -1165
  26. package/integ-tests/integ.custom-domain.ts.snapshot/asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d/index.js +1 -0
  27. package/integ-tests/{integ.al2023.ts.snapshot/asset.a9865c9d36c7aa999e28cb7926e7a3a8e0b6d0854b25131a172024c5777442fa.lambda → integ.custom-domain.ts.snapshot/asset.33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.lambda}/index.js +14 -2
  28. package/integ-tests/{integ.al2023.ts.snapshot/asset.f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd.bundle → integ.custom-domain.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle}/index.js +296 -191
  29. package/integ-tests/integ.custom-domain.ts.snapshot/asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda/index.js +57 -0
  30. package/integ-tests/integ.custom-domain.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/__entrypoint__.js +1 -0
  31. package/integ-tests/integ.custom-domain.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/index.js +1 -0
  32. package/integ-tests/{integ.al2023.ts.snapshot/asset.ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a → integ.custom-domain.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00}/index.js +1 -1
  33. package/integ-tests/integ.custom-domain.ts.snapshot/asset.b073cebcf4d61fb152a30f5a5e57a94df7f980a549fdf1a79a0b18c5750522d8/index.js +1 -0
  34. package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/cfn-response.js +1 -0
  35. package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/consts.js +1 -0
  36. package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/framework.js +3 -0
  37. package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/outbound.js +1 -0
  38. package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/util.js +1 -0
  39. package/integ-tests/integ.custom-domain.ts.snapshot/integ.json +23 -0
  40. package/integ-tests/integ.custom-domain.ts.snapshot/manifest.json +1653 -0
  41. package/integ-tests/integ.custom-domain.ts.snapshot/tree.json +1 -0
  42. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.assets.json +7 -6
  43. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.template.json +6 -6
  44. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.assets.json +20 -12
  45. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.template.json +36 -72
  46. package/integ-tests/integ.ubuntu.ts.snapshot/asset.0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4/index.js +5992 -0
  47. package/integ-tests/integ.ubuntu.ts.snapshot/asset.33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.lambda/index.js +143 -0
  48. package/integ-tests/integ.ubuntu.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle/index.js +30676 -0
  49. package/integ-tests/integ.ubuntu.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00/index.js +1 -0
  50. package/integ-tests/integ.ubuntu.ts.snapshot/cdk.out +1 -1
  51. package/integ-tests/integ.ubuntu.ts.snapshot/integ.json +3 -2
  52. package/integ-tests/integ.ubuntu.ts.snapshot/manifest.json +956 -7
  53. package/integ-tests/integ.ubuntu.ts.snapshot/tree.json +1 -3070
  54. package/lib/installer/installer.d.ts +7 -0
  55. package/lib/installer/installer.js +15 -7
  56. package/lib/installer/installer.lambda.js +20 -3
  57. package/lib/vscode-server.d.ts +33 -0
  58. package/lib/vscode-server.js +165 -5
  59. package/mavogelcdkvscodeserver/go.mod +1 -1
  60. package/mavogelcdkvscodeserver/jsii/jsii.go +2 -2
  61. package/mavogelcdkvscodeserver/version +1 -1
  62. package/package.json +4 -4
package/CLAUDE.md CHANGED
@@ -4,156 +4,122 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4
4
 
5
5
  ## Repository Overview
6
6
 
7
- This is a CDK construct library for deploying VS Code Server on AWS, designed for development and workshop purposes. The project creates a complete infrastructure setup that allows users to run a cloud-based VS Code instance accessible through CloudFront.
7
+ This is a JSII-enabled CDK construct library published to npm, PyPI, and Go that deploys VS Code Server on AWS. It's designed for workshop/development purposes and creates infrastructure for running a cloud-based VS Code instance accessible through CloudFront.
8
+
9
+ **Key Characteristics**:
10
+ - **Projen-managed**: All project configuration is in `.projenrc.ts` - run `npx projen` after modifying it
11
+ - **Multi-language**: TypeScript source published to Python and Go via JSII
12
+ - **Not production-ready**: Intentionally permissive for workshop scenarios
8
13
 
9
14
  ## Development Commands
10
15
 
11
16
  ### Build and Test
12
17
  ```bash
13
- # Build the project (TypeScript compilation, bundling, etc.)
18
+ # Build project (compiles TS, bundles Lambdas, generates API docs)
14
19
  npx projen build
15
20
 
16
- # Run tests
21
+ # Run unit tests
17
22
  npx projen test
18
23
 
24
+ # Run single test file
25
+ npx jest test/vscode-server.test.ts
26
+
19
27
  # Run tests in watch mode
20
28
  npx projen test:watch
21
29
 
22
- # Run a single test file
23
- npx jest test/vscode-server.test.ts
24
-
25
- # Run integration tests (deploys to AWS)
30
+ # Integration tests (deploys to eu-west-1, eu-west-2, eu-north-1)
26
31
  npm run integ-test
27
32
  ```
28
33
 
29
34
  ### Code Quality
30
35
  ```bash
31
- # Run ESLint
36
+ # ESLint
32
37
  npx projen eslint
33
38
 
34
- # AWS CDK linting
39
+ # AWS CDK-specific linting (awslint rules)
35
40
  npm run awslint
36
41
  ```
37
42
 
38
- ### Package Management
43
+ ### Lambda Development
39
44
  ```bash
40
- # Install dependencies and update projen
41
- npx projen
42
-
43
- # Build and package for all targets (JS, Python, Go)
44
- npx projen package-all
45
-
46
- # Package for specific target
47
- npx projen package:js
48
- npx projen package:python
49
- npx projen package:go
50
- ```
51
-
52
- ### Lambda Functions
53
- ```bash
54
- # Bundle installer Lambda
45
+ # Bundle specific Lambda
55
46
  npx projen bundle:installer/installer.lambda
56
-
57
- # Bundle secret retriever Lambda
58
47
  npx projen bundle:secret-retriever/secret-retriever.lambda
59
48
 
60
49
  # Watch mode for development
61
50
  npx projen bundle:installer/installer.lambda:watch
62
51
  ```
63
52
 
64
- ## Architecture Overview
65
-
66
- ### Core Components
67
-
68
- **Main Construct (`src/vscode-server.ts`)**:
69
- - `VSCodeServer` - Primary construct that orchestrates the entire solution
70
- - Creates VPC, EC2 instance, CloudFront distribution, security groups
71
- - Supports Ubuntu 22/24 and Amazon Linux 2023
72
- - Configurable instance types, storage, and additional permissions
73
-
74
- **Infrastructure Components**:
75
- - **VPC**: Single AZ public subnet configuration
76
- - **EC2 Instance**: Configurable instance with pre-installed development tools
77
- - **CloudFront**: Distribution for secure access with cache policies
78
- - **Security Groups**: Restricted to CloudFront prefix lists only
79
- - **IAM**: Comprehensive role for CDK operations and AWS service access
80
-
81
- **Lambda Functions** (`src/installer/`, `src/secret-retriever/`):
82
- - **Installer**: Custom resource for OS-specific VS Code server installation
83
- - **Secret Retriever**: Custom resource for extracting generated passwords
84
-
85
- **Utility Modules**:
86
- - `src/mappings.ts` - AMI mappings for different OS/architecture combinations
87
- - `src/prefixlist-retriever/` - AWS managed prefix list retrieval
88
- - `src/suppress-nags.ts` - CDK-nag suppression patterns
89
-
90
- ### Supported Configurations
91
-
92
- **Operating Systems**:
93
- - Ubuntu 22.04 LTS (`LinuxFlavorType.UBUNTU_22`)
94
- - Ubuntu 24.04 LTS (`LinuxFlavorType.UBUNTU_24`)
95
- - Amazon Linux 2023 (`LinuxFlavorType.AMAZON_LINUX_2023`)
96
-
97
- **Architectures**:
98
- - ARM64 (`LinuxArchitectureType.ARM`)
99
- - x86_64 (`LinuxArchitectureType.AMD64`)
100
-
101
- **Default Instance**: m7g.xlarge (ARM-based Graviton3)
102
-
103
- ## Project Structure
53
+ ### Publishing
54
+ ```bash
55
+ # Package for all targets (JS, Python, Go)
56
+ npx projen package-all
104
57
 
58
+ # Package specific target
59
+ npx projen package:js
60
+ npx projen package:python
61
+ npx projen package:go
105
62
  ```
106
- src/
107
- ├── index.ts # Main export
108
- ├── vscode-server.ts # Core VSCodeServer construct
109
- ├── mappings.ts # AMI mappings
110
- ├── installer/ # Installation Lambda functions
111
- ├── secret-retriever/ # Password generation utilities
112
- └── prefixlist-retriever/ # AWS prefix list utilities
113
-
114
- test/
115
- ├── vscode-server.test.ts # Unit tests
116
- └── installer/ # Lambda function tests
117
-
118
- integ-tests/
119
- ├── integ.ubuntu.ts # Ubuntu integration tests
120
- └── integ.al2023.ts # Amazon Linux integration tests
121
-
122
- examples/
123
- ├── simple/ # Basic usage example
124
- └── custom/ # Advanced configuration example
125
- ```
126
-
127
- ## Key Properties and Customization
128
63
 
129
- The `VSCodeServerProps` interface allows extensive customization:
130
-
131
- - **Instance Configuration**: `instanceClass`, `instanceSize`, `instanceVolumeSize`
132
- - **Operating System**: `instanceOperatingSystem`, `instanceCpuArchitecture`
133
- - **VS Code Settings**: `vscodeUser`, `vscodePassword`, `homeFolder`
134
- - **Development Server**: `devServerBasePath`, `devServerPort`
64
+ ## Architecture
65
+
66
+ ### Main Construct (`VSCodeServer`)
67
+ Located in `src/vscode-server.ts`, orchestrates:
68
+ - VPC with single public subnet
69
+ - EC2 instance (default: m7g.xlarge Graviton3 ARM)
70
+ - CloudFront distribution with custom cache policies for VS Code Server
71
+ - Security groups (CloudFront prefix list restriction only)
72
+ - IAM role with CDK permissions for workshop use
73
+ - Optional Route53 + ACM certificate integration via `domainName` prop
74
+
75
+ ### Custom Resources Pattern
76
+ Uses Lambda-backed custom resources via CDK Provider construct:
77
+ - **Installer** (`src/installer/`): OS-specific VS Code Server installation via SSM documents
78
+ - **SecretRetriever** (`src/secret-retriever/`): Extracts generated password from Secrets Manager
79
+ - **PrefixListRetriever** (`src/prefixlist-retriever/`): Fetches AWS-managed CloudFront prefix lists
80
+
81
+ ### AMI Selection
82
+ `src/mappings.ts` contains SSM parameter paths for:
83
+ - Ubuntu 22/24 (ARM + x86_64)
84
+ - Amazon Linux 2023 (ARM + x86_64)
85
+
86
+ Function `getAmiSSMParameterForLinuxArchitectureAndFlavor()` returns region-specific SSM parameter for latest AMI.
87
+
88
+ ### Key Props
89
+ `VSCodeServerProps` in `src/vscode-server.ts:27-155`:
90
+ - **Instance**: `instanceClass`, `instanceSize`, `instanceVolumeSize`
91
+ - **OS**: `instanceOperatingSystem` (LinuxFlavorType enum), `instanceCpuArchitecture` (LinuxArchitectureType enum)
92
+ - **VS Code**: `vscodeUser`, `vscodePassword`, `homeFolder`, `devServerPort`, `devServerBasePath`
93
+ - **Domain**: `domainName`, `hostedZoneId`, `certificateArn`, `autoCreateCertificate`
135
94
  - **Extensions**: `additionalInstanceRolePolicies`, `additionalTags`
136
95
 
137
- ## Important Development Notes
138
-
139
- - This is a **Projen-managed project** - all configuration changes should be made in `.projenrc.ts` (not found in current structure, likely generated)
140
- - The project uses **JSII** for multi-language support (TypeScript, Python, Go)
141
- - **CDK-nag** is integrated for security compliance checking
142
- - Integration tests deploy real AWS resources and require valid AWS credentials
143
- - Lambda functions are bundled using esbuild for optimal performance
144
- - CloudFront distribution includes custom cache policies for VS Code Server compatibility
145
-
146
- ## Security Considerations
147
-
148
- - Security groups restrict access to CloudFront IPs only
149
- - Instance role includes broad permissions for workshop scenarios (not production-ready)
150
- - Secrets Manager integration for password generation
151
- - EBS encryption enabled by default
152
- - IMDSv2 required on EC2 instances
153
-
154
- ## Testing Strategy
155
-
156
- - **Unit Tests**: Mock-based testing of construct logic
157
- - **Integration Tests**: Full deployment testing in multiple regions (eu-west-1, eu-west-2)
158
- - **Coverage Reports**: Generated in `coverage/` directory with multiple formats
159
- - **Jest Configuration**: Includes JUnit reporter for CI/CD integration
96
+ ## Important Patterns
97
+
98
+ ### Projen Workflow
99
+ 1. Edit `.projenrc.ts` for project changes (dependencies, build config, etc.)
100
+ 2. Run `npx projen` to regenerate managed files
101
+ 3. Never manually edit `package.json`, task definitions, or GitHub workflows
102
+
103
+ ### JSII Constraints
104
+ - All public APIs must be JSII-compatible (no TS-specific types)
105
+ - Bundled dependencies (like `node-html-parser`) in Lambda code must be listed in `.projenrc.ts` `bundledDeps`
106
+ - Lambda functions use esbuild bundling configured via Projen
107
+
108
+ ### CDK-nag Integration
109
+ - `src/suppress-nags.ts` contains suppression patterns
110
+ - Suppressions are applied via `NagSuppressions.addResourceSuppressions()` throughout construct code
111
+ - Necessary because workshop design intentionally violates production best practices (e.g., broad IAM permissions)
112
+
113
+ ### Integration Tests
114
+ - Located in `integ-tests/`
115
+ - Use `@aws-cdk/integ-tests-alpha` framework
116
+ - Deploy actual stacks to 3 regions in parallel
117
+ - Include assertion tests (e.g., login test via Lambda in `integ-tests/functions/`)
118
+ - Run with `npm run integ-test` (requires AWS credentials)
119
+
120
+ ## Domain/Certificate Feature (feat/route53-domain branch)
121
+ When `domainName` prop is provided:
122
+ - Creates Route53 A record pointing to CloudFront distribution
123
+ - Supports `autoCreateCertificate` flag to create ACM cert in us-east-1 with DNS validation
124
+ - Alternatively accepts existing `certificateArn`
125
+ - Auto-discovers hosted zone if `hostedZoneId` not provided
package/README.md CHANGED
@@ -20,6 +20,8 @@ we implement new features. Therefore make sure you use an exact version in your
20
20
 
21
21
  - [Features](#features)
22
22
  - [Usage](#usage)
23
+ - [Standard](#Standard)
24
+ - [Custom Domain Configuration](#custom-domain-configuration)
23
25
  - [Solution Design](#solution-design)
24
26
  - [Inspiration](#inspiration)
25
27
 
@@ -28,9 +30,13 @@ we implement new features. Therefore make sure you use an exact version in your
28
30
  - ⚡ **Quick Setup**: Spin up and configure your [vscode](https://code.visualstudio.com/) server in under 10 minutes in your AWS account
29
31
  - 📏 **Best Practice Setup**: Set up with [projen](https://projen.io/) and a [single configuration file](./.projenrc.ts) to keep your changes centralized.
30
32
  - 🤹‍♂️ **Pre-installed packages**: Besides the [vscode](https://code.visualstudio.com/) server, other tools and software packages such as `git`, `docker`, `awscli` `nodejs` and `python` are pre-installed on the EC2 instance.
33
+ - 🌐 **Custom Domain Support**: Use your own domain name with automatic ACM certificate creation and Route53 DNS configuration, or bring your existing certificate.
31
34
  - 🏗️ **Extensibility**: Pass in properties to the construct, which start with `additional*`. They allow you to extend the configuration to your needs. There are more to come...
32
35
 
33
36
  ## Usage
37
+ Actually we supported 2 modes:
38
+
39
+ ### Standard
34
40
  The following steps get you started:
35
41
 
36
42
  1. Create a new `awscdk-app` via
@@ -108,6 +114,48 @@ dev.vscodepassword64FBCA12 = foobarbaz
108
114
 
109
115
  See the [examples](./examples) folder for more inspiration.
110
116
 
117
+ ### Custom Domain Configuration
118
+
119
+ You can configure your VS Code Server with a custom domain name instead of using the default CloudFront domain. The construct supports three different configuration options:
120
+
121
+ #### Option 1: Auto-create Certificate with DNS Validation
122
+ ```ts
123
+ new VSCodeServer(this, 'vscode', {
124
+ domainName: 'vscode.example.com',
125
+ hostedZoneId: 'Z123EXAMPLE456', // optional - will auto-discover if not provided
126
+ autoCreateCertificate: true,
127
+ });
128
+ ```
129
+
130
+ This will:
131
+ - Create an ACM certificate in us-east-1 (required for CloudFront)
132
+ - Validate the certificate using DNS validation
133
+ - Create a Route53 A record pointing to the CloudFront distribution
134
+ - Configure the CloudFront distribution with the custom domain
135
+
136
+ #### Option 2: Use Existing Certificate
137
+ ```ts
138
+ new VSCodeServer(this, 'vscode', {
139
+ domainName: 'vscode.example.com',
140
+ hostedZoneId: 'Z123EXAMPLE456',
141
+ certificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012',
142
+ });
143
+ ```
144
+
145
+ **Requirements:**
146
+ - Certificate must be in us-east-1 region
147
+ - Certificate must be validated and ready to use
148
+ - Certificate must include the domain name
149
+
150
+ #### Option 3: Default (No Custom Domain)
151
+ ```ts
152
+ new VSCodeServer(this, 'vscode', {
153
+ // No domain configuration - uses CloudFront default domain
154
+ });
155
+ ```
156
+
157
+ For complete examples, see [examples/custom-domain/main.ts](./examples/custom-domain/main.ts).
158
+
111
159
  6. Then open the domain name in your favorite browser and you'd see the following login screen:
112
160
  ![vscode-server-ui-login](docs/img/vscode-server-ui-login-min.png)
113
161
 
@@ -120,8 +120,20 @@ var handler = async (event, context) => {
120
120
  }
121
121
  return { Data: responseData };
122
122
  } catch (error) {
123
- console.log(error);
124
- throw error;
123
+ console.log("Error occurred:", error);
124
+ const isUnauthorized = error.name === "UnauthorizedException" || error.name === "AccessDeniedException" || error.message && error.message.includes("not authorized");
125
+ const isThrottled = error.name === "ThrottlingException" || error.name === "TooManyRequestsException";
126
+ const isRetryable = isUnauthorized || isThrottled;
127
+ timeRemaining = context.getRemainingTimeInMillis();
128
+ if (isRetryable && timeRemaining > SLEEP_MS) {
129
+ console.log(
130
+ `Retryable error encountered (${error.name}). Attempt ${attemptNo}. Sleeping: ${SLEEP_MS / 1e3}s before retry`
131
+ );
132
+ await new Promise((resolve) => setTimeout(resolve, SLEEP_MS));
133
+ } else {
134
+ console.log("Non-retryable error or timeout. Failing...");
135
+ throw error;
136
+ }
125
137
  }
126
138
  }
127
139
  };
@@ -0,0 +1,49 @@
1
+ import { App, Stack, StackProps } from "aws-cdk-lib";
2
+ import { Construct } from "constructs";
3
+ import { VSCodeServer } from "../../src/index";
4
+
5
+ export class MyStack extends Stack {
6
+ constructor(scope: Construct, id: string, props: StackProps = {}) {
7
+ super(scope, id, props);
8
+
9
+ // Example 1: Custom domain with existing certificate
10
+ // Nginx will be configured with: server_name *.cloudfront.net vscode.example.com;
11
+ new VSCodeServer(this, "vscode-with-existing-cert", {
12
+ domainName: "vscode.example.com",
13
+ hostedZoneId: "Z123EXAMPLE456",
14
+ certificateArn:
15
+ "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
16
+ });
17
+
18
+ // Example 2: Custom domain with auto-created certificate
19
+ // Nginx will be configured with: server_name *.cloudfront.net vscode-auto.example.com;
20
+ new VSCodeServer(this, "vscode-with-auto-cert", {
21
+ domainName: "vscode-auto.example.com",
22
+ hostedZoneId: "Z123EXAMPLE456",
23
+ autoCreateCertificate: true,
24
+ });
25
+
26
+ // Example 3: Custom domain with hosted zone lookup (auto-discovery)
27
+ // Nginx will be configured with: server_name *.cloudfront.net vscode-lookup.example.com;
28
+ new VSCodeServer(this, "vscode-with-zone-lookup", {
29
+ domainName: "vscode-lookup.example.com",
30
+ autoCreateCertificate: true,
31
+ // hostedZoneId not provided - will be auto-discovered
32
+ });
33
+
34
+ // Example 4: Default behavior (no custom domain)
35
+ // Nginx will be configured with: server_name *.cloudfront.net;
36
+ new VSCodeServer(this, "vscode-default", {
37
+ // No domain configuration - uses CloudFront default domain only
38
+ });
39
+ }
40
+ }
41
+
42
+ const env = {
43
+ account: "123456789012",
44
+ region: "eu-central-1",
45
+ };
46
+
47
+ const app = new App();
48
+ new MyStack(app, "vscode-server-custom-domain", { env });
49
+ app.synth();
@@ -1,20 +1,21 @@
1
1
  {
2
- "version": "39.0.0",
2
+ "version": "41.0.0",
3
3
  "files": {
4
- "f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd": {
4
+ "530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42": {
5
5
  "source": {
6
- "path": "asset.f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd.bundle",
6
+ "path": "asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle",
7
7
  "packaging": "zip"
8
8
  },
9
9
  "destinations": {
10
10
  "current_account-current_region": {
11
11
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12
- "objectKey": "f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd.zip",
12
+ "objectKey": "530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.zip",
13
13
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14
14
  }
15
15
  }
16
16
  },
17
- "84ea43eb26709048c4d2d4a30e0c90d256e372f41390b121784fb6addfd40bb3": {
17
+ "e5a8816554ca9fe1e7bf41d7d9fcc2f77bb6af7b02cb83746f5f815104b12306": {
18
+ "displayName": "IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645 Template",
18
19
  "source": {
19
20
  "path": "IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645.template.json",
20
21
  "packaging": "file"
@@ -22,7 +23,7 @@
22
23
  "destinations": {
23
24
  "current_account-current_region": {
24
25
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
25
- "objectKey": "84ea43eb26709048c4d2d4a30e0c90d256e372f41390b121784fb6addfd40bb3.json",
26
+ "objectKey": "e5a8816554ca9fe1e7bf41d7d9fcc2f77bb6af7b02cb83746f5f815104b12306.json",
26
27
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
27
28
  }
28
29
  }
@@ -45,7 +45,7 @@
45
45
  }
46
46
  },
47
47
  "flattenResponse": "false",
48
- "salt": "1739276543111"
48
+ "salt": "1759320082329"
49
49
  },
50
50
  "UpdateReplacePolicy": "Delete",
51
51
  "DeletionPolicy": "Delete"
@@ -153,7 +153,7 @@
153
153
  "S3Bucket": {
154
154
  "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
155
155
  },
156
- "S3Key": "f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd.zip"
156
+ "S3Key": "530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.zip"
157
157
  },
158
158
  "Timeout": 120,
159
159
  "Handler": "index.handler",
@@ -224,10 +224,10 @@
224
224
  "value": "nodejs20.x"
225
225
  },
226
226
  "cn-north-1": {
227
- "value": "nodejs18.x"
227
+ "value": "nodejs20.x"
228
228
  },
229
229
  "cn-northwest-1": {
230
- "value": "nodejs18.x"
230
+ "value": "nodejs20.x"
231
231
  },
232
232
  "eu-central-1": {
233
233
  "value": "nodejs20.x"
@@ -278,10 +278,10 @@
278
278
  "value": "nodejs20.x"
279
279
  },
280
280
  "us-gov-east-1": {
281
- "value": "nodejs18.x"
281
+ "value": "nodejs20.x"
282
282
  },
283
283
  "us-gov-west-1": {
284
- "value": "nodejs18.x"
284
+ "value": "nodejs20.x"
285
285
  },
286
286
  "us-iso-east-1": {
287
287
  "value": "nodejs18.x"
@@ -1,7 +1,8 @@
1
1
  {
2
- "version": "39.0.0",
2
+ "version": "41.0.0",
3
3
  "files": {
4
4
  "781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b": {
5
+ "displayName": "IntegVSCodeServer/SecretRetrieverOnEventHandler/Code",
5
6
  "source": {
6
7
  "path": "asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda",
7
8
  "packaging": "zip"
@@ -15,6 +16,7 @@
15
16
  }
16
17
  },
17
18
  "bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca": {
19
+ "displayName": "IntegVSCodeServer/SecretRetrieveProvider/framework-onEvent/Code",
18
20
  "source": {
19
21
  "path": "asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca",
20
22
  "packaging": "zip"
@@ -28,6 +30,7 @@
28
30
  }
29
31
  },
30
32
  "7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200": {
33
+ "displayName": "IntegTestStackAl2023/Custom::VpcRestrictDefaultSGCustomResourceProvider Code",
31
34
  "source": {
32
35
  "path": "asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200",
33
36
  "packaging": "zip"
@@ -40,46 +43,50 @@
40
43
  }
41
44
  }
42
45
  },
43
- "ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a": {
46
+ "9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00": {
47
+ "displayName": "AWS679f53fac002430cb0da5b7982bd2287/Code",
44
48
  "source": {
45
- "path": "asset.ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a",
49
+ "path": "asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00",
46
50
  "packaging": "zip"
47
51
  },
48
52
  "destinations": {
49
53
  "current_account-current_region": {
50
54
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
51
- "objectKey": "ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a.zip",
55
+ "objectKey": "9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00.zip",
52
56
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
53
57
  }
54
58
  }
55
59
  },
56
- "a9865c9d36c7aa999e28cb7926e7a3a8e0b6d0854b25131a172024c5777442fa": {
60
+ "33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f": {
61
+ "displayName": "IntegVSCodeServer/InstallerOnEventHandler/Code",
57
62
  "source": {
58
- "path": "asset.a9865c9d36c7aa999e28cb7926e7a3a8e0b6d0854b25131a172024c5777442fa.lambda",
63
+ "path": "asset.33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.lambda",
59
64
  "packaging": "zip"
60
65
  },
61
66
  "destinations": {
62
67
  "current_account-current_region": {
63
68
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
64
- "objectKey": "a9865c9d36c7aa999e28cb7926e7a3a8e0b6d0854b25131a172024c5777442fa.zip",
69
+ "objectKey": "33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.zip",
65
70
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
66
71
  }
67
72
  }
68
73
  },
69
- "23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce": {
74
+ "0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4": {
75
+ "displayName": "login-handler/Code",
70
76
  "source": {
71
- "path": "asset.23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce",
77
+ "path": "asset.0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4",
72
78
  "packaging": "zip"
73
79
  },
74
80
  "destinations": {
75
81
  "current_account-current_region": {
76
82
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
77
- "objectKey": "23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce.zip",
83
+ "objectKey": "0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4.zip",
78
84
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
79
85
  }
80
86
  }
81
87
  },
82
88
  "2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d": {
89
+ "displayName": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code",
83
90
  "source": {
84
91
  "path": "asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d",
85
92
  "packaging": "zip"
@@ -92,7 +99,8 @@
92
99
  }
93
100
  }
94
101
  },
95
- "daccc551628f034bf6f7020e5a4aeea5d8c5af4bc18cebc60f9bb8c6e3f681d4": {
102
+ "78456291afad0703e73d0edcbe74101f565cb893d6c239a8a39dec908321d182": {
103
+ "displayName": "IntegTestStackAl2023 Template",
96
104
  "source": {
97
105
  "path": "IntegTestStackAl2023.template.json",
98
106
  "packaging": "file"
@@ -100,7 +108,7 @@
100
108
  "destinations": {
101
109
  "current_account-current_region": {
102
110
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
103
- "objectKey": "daccc551628f034bf6f7020e5a4aeea5d8c5af4bc18cebc60f9bb8c6e3f681d4.json",
111
+ "objectKey": "78456291afad0703e73d0edcbe74101f565cb893d6c239a8a39dec908321d182.json",
104
112
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
105
113
  }
106
114
  }