@mavogel/cdk-vscode-server 0.0.55 → 0.0.57
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/.claude/hooks/file_checker.sh +0 -0
- package/.jsii +96 -24
- package/API.md +56 -0
- package/CLAUDE.md +84 -118
- package/README.md +48 -0
- package/assets/installer/installer.lambda/index.js +14 -2
- package/examples/custom-domain/main.ts +49 -0
- package/integ-tests/integ.al2023.ts.snapshot/IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645.assets.json +7 -6
- package/integ-tests/integ.al2023.ts.snapshot/IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645.template.json +6 -6
- package/integ-tests/integ.al2023.ts.snapshot/IntegTestStackAl2023.assets.json +20 -12
- package/integ-tests/integ.al2023.ts.snapshot/IntegTestStackAl2023.template.json +36 -152
- package/integ-tests/integ.al2023.ts.snapshot/{asset.23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce → asset.0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4}/index.js +988 -1165
- package/integ-tests/{integ.ubuntu.ts.snapshot/asset.a9865c9d36c7aa999e28cb7926e7a3a8e0b6d0854b25131a172024c5777442fa.lambda → integ.al2023.ts.snapshot/asset.33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.lambda}/index.js +14 -2
- package/integ-tests/{integ.ubuntu.ts.snapshot/asset.f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd.bundle → integ.al2023.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle}/index.js +296 -191
- package/integ-tests/{integ.ubuntu.ts.snapshot/asset.ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a → integ.al2023.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00}/index.js +1 -1
- package/integ-tests/integ.al2023.ts.snapshot/cdk.out +1 -1
- package/integ-tests/integ.al2023.ts.snapshot/integ.json +4 -3
- package/integ-tests/integ.al2023.ts.snapshot/manifest.json +956 -7
- package/integ-tests/integ.al2023.ts.snapshot/tree.json +1 -3228
- package/integ-tests/integ.custom-domain.ts +87 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.assets.json +33 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.template.json +333 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.assets.json +132 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.template.json +2862 -0
- package/integ-tests/{integ.ubuntu.ts.snapshot/asset.23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce → integ.custom-domain.ts.snapshot/asset.0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4}/index.js +988 -1165
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d/index.js +1 -0
- package/integ-tests/{integ.al2023.ts.snapshot/asset.a9865c9d36c7aa999e28cb7926e7a3a8e0b6d0854b25131a172024c5777442fa.lambda → integ.custom-domain.ts.snapshot/asset.33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.lambda}/index.js +14 -2
- package/integ-tests/{integ.al2023.ts.snapshot/asset.f692c9f68e4daba2abc99103efd3518bced1e9d7a2a89847b9b5d5473c64f1bd.bundle → integ.custom-domain.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle}/index.js +296 -191
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda/index.js +57 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/__entrypoint__.js +1 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/index.js +1 -0
- package/integ-tests/{integ.al2023.ts.snapshot/asset.ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a → integ.custom-domain.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00}/index.js +1 -1
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.b073cebcf4d61fb152a30f5a5e57a94df7f980a549fdf1a79a0b18c5750522d8/index.js +1 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/cfn-response.js +1 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/consts.js +1 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/framework.js +3 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/outbound.js +1 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/util.js +1 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/integ.json +23 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/manifest.json +1653 -0
- package/integ-tests/integ.custom-domain.ts.snapshot/tree.json +1 -0
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.assets.json +7 -6
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.template.json +6 -6
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.assets.json +20 -12
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.template.json +36 -72
- package/integ-tests/integ.ubuntu.ts.snapshot/asset.0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4/index.js +5992 -0
- package/integ-tests/integ.ubuntu.ts.snapshot/asset.33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f.lambda/index.js +143 -0
- package/integ-tests/integ.ubuntu.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle/index.js +30676 -0
- package/integ-tests/integ.ubuntu.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00/index.js +1 -0
- package/integ-tests/integ.ubuntu.ts.snapshot/cdk.out +1 -1
- package/integ-tests/integ.ubuntu.ts.snapshot/integ.json +3 -2
- package/integ-tests/integ.ubuntu.ts.snapshot/manifest.json +956 -7
- package/integ-tests/integ.ubuntu.ts.snapshot/tree.json +1 -3070
- package/lib/installer/installer.d.ts +7 -0
- package/lib/installer/installer.js +15 -7
- package/lib/installer/installer.lambda.js +20 -3
- package/lib/vscode-server.d.ts +33 -0
- package/lib/vscode-server.js +165 -5
- package/mavogelcdkvscodeserver/README.md +55 -0
- package/mavogelcdkvscodeserver/VSCodeServerProps.go +20 -0
- package/mavogelcdkvscodeserver/go.mod +1 -1
- package/mavogelcdkvscodeserver/jsii/jsii.go +2 -2
- package/mavogelcdkvscodeserver/version +1 -1
- 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
|
|
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
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
###
|
|
43
|
+
### Lambda Development
|
|
39
44
|
```bash
|
|
40
|
-
#
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
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
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
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
|

|
|
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
|
-
|
|
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": "
|
|
2
|
+
"version": "41.0.0",
|
|
3
3
|
"files": {
|
|
4
|
-
"
|
|
4
|
+
"530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42": {
|
|
5
5
|
"source": {
|
|
6
|
-
"path": "asset.
|
|
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": "
|
|
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
|
-
"
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
227
|
+
"value": "nodejs20.x"
|
|
228
228
|
},
|
|
229
229
|
"cn-northwest-1": {
|
|
230
|
-
"value": "
|
|
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": "
|
|
281
|
+
"value": "nodejs20.x"
|
|
282
282
|
},
|
|
283
283
|
"us-gov-west-1": {
|
|
284
|
-
"value": "
|
|
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": "
|
|
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
|
-
"
|
|
46
|
+
"9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00": {
|
|
47
|
+
"displayName": "AWS679f53fac002430cb0da5b7982bd2287/Code",
|
|
44
48
|
"source": {
|
|
45
|
-
"path": "asset.
|
|
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": "
|
|
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
|
-
"
|
|
60
|
+
"33da23274e25bd9f43638c5d83dad26e3931cbe78d462ffd9a9f565e948b4f5f": {
|
|
61
|
+
"displayName": "IntegVSCodeServer/InstallerOnEventHandler/Code",
|
|
57
62
|
"source": {
|
|
58
|
-
"path": "asset.
|
|
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": "
|
|
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
|
-
"
|
|
74
|
+
"0ad50fc42afd768c3d0bfdd4701e43284fb077a25f19eea1e8c51a5ca36ebfe4": {
|
|
75
|
+
"displayName": "login-handler/Code",
|
|
70
76
|
"source": {
|
|
71
|
-
"path": "asset.
|
|
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": "
|
|
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
|
-
"
|
|
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": "
|
|
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
|
}
|