@mavogel/cdk-vscode-server 0.0.99 → 0.0.101

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.md CHANGED
@@ -1,399 +1 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Repository Overview
6
-
7
- A JSII-enabled CDK construct library that deploys VS Code Server on AWS. Published to npm and PyPI. Designed for workshop/development environments with intentionally permissive security for ease of use.
8
-
9
- **Key Characteristic**: This is **NOT production-ready** by design - it's optimized for quick workshop setup and learning environments.
10
-
11
- ## Projen-Managed Project
12
-
13
- **Critical**: ALL project configuration is in `.projenrc.ts`. After modifying it, run `npx projen` to regenerate managed files.
14
-
15
- **Never manually edit**:
16
- - `package.json`
17
- - Task definitions
18
- - GitHub workflows
19
- - Any file with "~~ Generated by projen" header
20
-
21
- ## Development Commands
22
-
23
- ### Build and Test
24
- ```bash
25
- # Full build (compiles TS, bundles Lambdas, generates API docs)
26
- npx projen build
27
-
28
- # Run unit tests
29
- npx projen test
30
-
31
- # Run single test file
32
- npx jest test/vscode-server.test.ts
33
-
34
- # Watch mode for tests
35
- npx projen test:watch
36
-
37
- # Integration tests (deploys to eu-west-1, eu-west-2, eu-north-1, eu-west-3)
38
- npm run integ-test
39
- ```
40
-
41
- ### Code Quality
42
- ```bash
43
- # ESLint
44
- npx projen eslint
45
-
46
- # AWS CDK-specific linting (awslint rules)
47
- npm run awslint
48
- ```
49
-
50
- ### Lambda Development
51
- ```bash
52
- # Bundle specific Lambda
53
- npx projen bundle:installer/installer.lambda
54
- npx projen bundle:idle-monitor/idle-monitor.lambda
55
- npx projen bundle:idle-monitor-enabler/idle-monitor-enabler.lambda
56
- npx projen bundle:secret-retriever/secret-retriever.lambda
57
-
58
- # Watch mode for Lambda development
59
- npx projen bundle:installer/installer.lambda:watch
60
- ```
61
-
62
- ### Publishing
63
- ```bash
64
- # Package for all targets (npm, Python)
65
- npx projen package-all
66
-
67
- # Package specific target
68
- npx projen package:js
69
- npx projen package:python
70
- ```
71
-
72
- ## Architecture Overview
73
-
74
- ### Main Construct: `VSCodeServer` (src/vscode-server.ts)
75
-
76
- Orchestrates the entire infrastructure:
77
- - VPC with single public subnet
78
- - EC2 instance (default: m7g.xlarge Graviton3 ARM)
79
- - CloudFront distribution with custom cache policies
80
- - Security groups (CloudFront prefix list restriction only)
81
- - IAM role with broad CDK permissions (workshop-friendly)
82
- - Optional: Route53 + ACM certificate integration
83
- - Optional: Auto-stop feature with idle monitoring
84
-
85
- ### Custom Resource Pattern
86
-
87
- Uses Lambda-backed custom resources via CDK Provider construct:
88
-
89
- 1. **Installer** (`src/installer/`)
90
- - Runs SSM documents to install VS Code Server
91
- - OS-specific installation for Ubuntu 22/24/25 and Amazon Linux 2023
92
- - Returns SUCCESS when installation completes
93
- - Custom resource name: `SSMInstallerCustomResource`
94
- - **Critical**: Must pass `linuxFlavorType` parameter to ensure correct OS-specific SSM document is used
95
-
96
- 2. **SecretRetriever** (`src/secret-retriever/`)
97
- - Extracts generated password from Secrets Manager
98
- - Returns password as CloudFormation output
99
-
100
- 3. **PrefixListRetriever** (`src/prefixlist-retriever/`)
101
- - Fetches AWS-managed CloudFront prefix lists
102
- - Used to restrict security group ingress
103
-
104
- 4. **IdleMonitorEnabler** (`src/idle-monitor-enabler/`)
105
- - Enables EventBridge rule ONLY after installation completes
106
- - Prevents race condition where IdleMonitor stops instance mid-installation
107
- - Critical dependency chain: `Installer → IdleMonitorEnabler → IdleMonitor active`
108
-
109
- ### Auto-Stop Feature Architecture
110
-
111
- **Problem Solved**: Race condition where IdleMonitor could stop instance during installation.
112
-
113
- **Solution Flow**:
114
- 1. EventBridge rule created in **DISABLED** state (`src/idle-monitor/idle-monitor.ts:118`)
115
- 2. Installer runs and completes VS Code Server setup
116
- 3. IdleMonitorEnabler custom resource **enables** the rule after installation succeeds
117
- 4. IdleMonitor now safely monitors CloudFront metrics for idle detection
118
-
119
- **Key Files**:
120
- - `src/idle-monitor/idle-monitor.ts` - EventBridge rule + Lambda for monitoring
121
- - `src/idle-monitor/idle-monitor.lambda.ts` - Checks CloudWatch metrics, stops instance if idle
122
- - `src/idle-monitor-enabler/idle-monitor-enabler.ts` - Custom resource construct
123
- - `src/idle-monitor-enabler/idle-monitor-enabler.lambda.ts` - Enables EventBridge rule via AWS SDK
124
-
125
- **Dependency Wiring** (`src/vscode-server.ts:984`):
126
- ```typescript
127
- const installerCustomResource = this.node.findChild('SSMInstallerCustomResource');
128
- enabler.node.addDependency(installerCustomResource);
129
- ```
130
-
131
- ### AMI Selection (`src/mappings.ts`)
132
-
133
- Contains SSM parameter paths for:
134
- - Ubuntu 22/24/25 (ARM + x86_64)
135
- - Amazon Linux 2023 (ARM + x86_64)
136
-
137
- **Ubuntu Codenames**:
138
- - Ubuntu 22 = "jammy" (uses ebs-gp2)
139
- - Ubuntu 24 = "noble" (uses ebs-gp3)
140
- - Ubuntu 25 = "plucky" (uses ebs-gp3)
141
-
142
- Function `getAmiSSMParameterForLinuxArchitectureAndFlavor()` returns region-specific SSM parameter for latest AMI.
143
-
144
- **Verify SSM Parameters** (when adding new OS versions):
145
- ```bash
146
- # List available Ubuntu versions
147
- aws ssm get-parameters-by-path --path "/aws/service/canonical/ubuntu/server/" --recursive --query "Parameters[*].Name" --region us-east-1
148
-
149
- # Verify specific AMI paths exist
150
- aws ssm get-parameters --names \
151
- "/aws/service/canonical/ubuntu/server/plucky/stable/current/amd64/hvm/ebs-gp3/ami-id" \
152
- "/aws/service/canonical/ubuntu/server/plucky/stable/current/arm64/hvm/ebs-gp3/ami-id" \
153
- --region us-east-1
154
- ```
155
-
156
- ### Key Props (`src/vscode-server.ts:27-200`)
157
-
158
- **Instance Configuration**:
159
- - `instanceClass`, `instanceSize`, `instanceVolumeSize`
160
- - `instanceOperatingSystem` (LinuxFlavorType enum)
161
- - `instanceCpuArchitecture` (LinuxArchitectureType enum)
162
-
163
- **VS Code Configuration**:
164
- - `vscodeUser`, `vscodePassword`, `homeFolder`
165
- - `devServerPort`, `devServerBasePath`
166
-
167
- **Domain/Certificate**:
168
- - `domainName`, `hostedZoneId`, `certificateArn`, `autoCreateCertificate`
169
-
170
- **Auto-Stop**:
171
- - `enableAutoStop` - Enable automatic instance stop when idle
172
- - `idleTimeoutMinutes` - Minutes of inactivity before stopping (default: 30)
173
- - `idleCheckIntervalMinutes` - How often to check (default: 5)
174
- - `skipStatusChecks` - Skip EC2 status checks before stopping (for testing only)
175
-
176
- **Custom Installation**:
177
- - `customInstallSteps` - Array of custom shell commands that run after standard installation
178
- - `repoUrl` - Git repository to clone into home folder during setup
179
-
180
- **Extensions**:
181
- - `additionalInstanceRolePolicies`, `additionalTags`
182
-
183
- ## JSII Constraints
184
-
185
- **Critical for JSII compatibility**:
186
- - All public APIs must be JSII-compatible (no TS-specific types)
187
- - Bundled dependencies (like `node-html-parser`) must be in `.projenrc.ts` `bundledDeps`
188
- - Lambda functions use esbuild bundling configured via Projen (auto-discovered in `src/**/*.lambda.ts`)
189
- - **@example JSDoc blocks must NOT use code fences** (```) - JSII will fail with "must be code only, no code block fences allowed"
190
-
191
- ## CDK-nag Integration
192
-
193
- Suppressions defined in `src/suppress-nags.ts` and applied throughout construct code.
194
-
195
- **Why suppressions are needed**: Workshop design intentionally violates production best practices:
196
- - Broad IAM permissions for ease of use
197
- - Permissive security groups
198
- - Public subnet deployment
199
- - No VPC endpoints
200
-
201
- Apply suppressions via `Validations.of(construct).acknowledge({ id, reason })` (cdk-nag v3's `Validations`/`IPolicyValidationPlugin` API replaced v2's `NagSuppressions`). Granular ARN-embedded findings (e.g. `AwsSolutions-IAM4`/`AwsSolutions-IAM5` for managed policies or wildcard resources) can't go through `acknowledge()` directly — it rejects any id with more than one `::` delimiter — so use the `acknowledgeGranularFinding()` bypass helper in `src/suppress-nags.ts` instead.
202
-
203
- ## Integration Tests
204
-
205
- Located in `integ-tests/`, using `@aws-cdk/integ-tests-alpha` framework.
206
-
207
- **Test Files**:
208
- - `integ.ubuntu.ts` - Basic Ubuntu 22 deployment + login test
209
- - `integ.ubuntu24.ts` - Ubuntu 24 deployment + login test
210
- - `integ.ubuntu25.ts` - Ubuntu 25 deployment + login test
211
- - `integ.al2023.ts` - Amazon Linux 2023 deployment
212
- - `integ.custom-domain.ts` - Custom domain + ACM certificate
213
- - `integ.stop-on-idle.ts` - **4-phase auto-stop workflow test**
214
-
215
- **Stop-on-Idle Test Phases** (`integ-tests/integ.stop-on-idle.ts`):
216
- 1. `verify-auto-stop` - Wait for instance to stop after idle timeout
217
- 2. `disable-idle-monitor` - Disable EventBridge rule to prevent re-stopping
218
- 3. `start-instance` - Start instance and wait for running state
219
- 4. `verify-login` - Check VS Code Server accessibility via CloudFront
220
-
221
- **Run Integration Tests**:
222
- ```bash
223
- npm run integ-test # Deploys to 4 regions in parallel
224
- ```
225
-
226
- **Important**: Integration tests deploy actual stacks and incur AWS costs.
227
-
228
- ## Lambda Bundling
229
-
230
- Projen automatically discovers Lambda functions matching `src/**/*.lambda.ts` pattern.
231
-
232
- **Auto-generated tasks** for each Lambda:
233
- - `bundle:<path>/name.lambda` - Bundle Lambda code
234
- - `bundle:<path>/name.lambda:watch` - Watch mode for development
235
-
236
- **Bundled output**: `assets/<path>/name.lambda/index.js`
237
-
238
- ## Common Workflows
239
-
240
- ### Adding a New Lambda Function
241
-
242
- 1. Create `src/my-feature/my-feature.lambda.ts`
243
- 2. Create `src/my-feature/my-feature-function.ts` (CDK construct wrapper)
244
- 3. Run `npx projen` - auto-discovers and creates bundle task
245
- 4. Import in construct: `import { MyFeatureFunction } from './my-feature/my-feature-function'`
246
-
247
- ### Adding Custom Installation Steps
248
-
249
- Custom steps are appended to SSM document `mainSteps` array in `createSSMDocument()`:
250
-
251
- 1. **Define interface** (if needed) in `src/vscode-server.ts`:
252
- ```typescript
253
- export interface CustomInstallStep {
254
- readonly name: string;
255
- readonly commands: string[];
256
- }
257
- ```
258
-
259
- 2. **Add prop** to `VSCodeServerProps` with JSDoc documentation (no code fences!)
260
-
261
- 3. **Pass to Installer** in both Ubuntu and Amazon Linux paths:
262
- ```typescript
263
- installer = Installer.ubuntu({
264
- // ... other options
265
- customInstallSteps: customInstallSteps,
266
- })._bind(this);
267
- ```
268
-
269
- 4. **Update `createSSMDocument()`** in `src/installer/installer.ts` to accept and use custom steps:
270
- ```typescript
271
- ...(customInstallSteps?.map((step) => ({
272
- action: 'aws:runShellScript' as const,
273
- name: step.name,
274
- inputs: {
275
- runCommand: step.commands,
276
- },
277
- })) ?? []),
278
- ```
279
-
280
- 5. **Write unit tests** in `test/vscode-server.test.ts` covering normal usage, without steps, and empty array
281
-
282
- 6. **Update documentation** in README.md with practical examples and add to `examples/` directory
283
-
284
- ### Modifying VSCodeServer Props
285
-
286
- 1. Edit `src/vscode-server.ts` - update `VSCodeServerProps` interface
287
- 2. If adding new types/interfaces, export them from `src/vscode-server.ts`
288
- 3. Run `npx projen build` - regenerates JSII artifacts + API docs
289
- 4. Update README.md with usage examples and feature section
290
- 5. Add example usage in `examples/` directory
291
-
292
- ### Testing Changes
293
-
294
- 1. Unit tests: `npx jest test/vscode-server.test.ts`
295
- 2. Build validation: `npx projen build` (includes awslint checks)
296
- 3. Integration test: `npm run integ-test` (full deployment test)
297
-
298
- ### Adding Support for a New Ubuntu Version
299
-
300
- When Ubuntu releases a new version (e.g., Ubuntu 26):
301
-
302
- 1. **Add AMI mappings** in `src/mappings.ts`:
303
- ```typescript
304
- [
305
- 'arm-ubuntu26',
306
- '/aws/service/canonical/ubuntu/server/CODENAME/stable/current/arm64/hvm/ebs-gp3/ami-id',
307
- ],
308
- [
309
- 'amd64-ubuntu26',
310
- '/aws/service/canonical/ubuntu/server/CODENAME/stable/current/amd64/hvm/ebs-gp3/ami-id',
311
- ],
312
- ```
313
- Replace `CODENAME` with Ubuntu's codename (verify via AWS SSM Parameter Store)
314
-
315
- 2. **Add enum value** in `src/vscode-server.ts`:
316
- ```typescript
317
- export enum LinuxFlavorType {
318
- // ...
319
- UBUNTU_26 = 'ubuntu26',
320
- }
321
- ```
322
-
323
- 3. **Update Installer** in `src/installer/installer.ts`:
324
- - Add `LinuxFlavorType.UBUNTU_26` to the Ubuntu switch case in `createSSMDocument()` (line ~657)
325
- - Update installer calls in `src/vscode-server.ts` to include new case (line ~930)
326
-
327
- 4. **Pass linuxFlavorType** in `src/vscode-server.ts`:
328
- ```typescript
329
- installer = Installer.ubuntu({
330
- // ... other options
331
- linuxFlavorType: instanceOperatingSystem, // Critical!
332
- })._bind(this);
333
- ```
334
-
335
- 5. **Create integration test**: Copy `integ-tests/integ.ubuntu25.ts` to `integ.ubuntu26.ts` and update OS version
336
-
337
- 6. **Update documentation**:
338
- - Update README.md examples with inline comments showing all supported versions
339
- - Examples in `examples/` directory (optional - can keep as Ubuntu 24)
340
-
341
- 7. **Verify and build**:
342
- ```bash
343
- # Verify SSM parameters exist
344
- aws ssm get-parameters-by-path --path "/aws/service/canonical/ubuntu/server/CODENAME/" --recursive --region us-east-1
345
-
346
- # Build and test
347
- npx projen build
348
- npm run integ-test
349
- ```
350
-
351
- ## Race Condition Prevention (Auto-Stop)
352
-
353
- **Issue**: IdleMonitor EventBridge rule triggers immediately on stack creation, potentially stopping instance during installation (observed: instance stopped 72 seconds after installer started).
354
-
355
- **Fix**: Three-stage dependency chain ensures safe operation:
356
-
357
- ```
358
- EC2 Instance
359
- ↓
360
- Installer Custom Resource (waits for VS Code Server installation)
361
- ↓
362
- IdleMonitorEnabler Custom Resource (enables EventBridge rule)
363
- ↓
364
- IdleMonitor Active (now safe to monitor)
365
- ```
366
-
367
- **Implementation Details**:
368
- - EventBridge rule created with `enabled: false` (`src/idle-monitor/idle-monitor.ts:118`)
369
- - IdleMonitorEnabler depends on `SSMInstallerCustomResource` via `node.addDependency()`
370
- - CloudFormation enforces ordering automatically
371
-
372
- This pattern can be applied to any future features requiring post-installation activation.
373
-
374
- ## Multi-Language Publishing
375
-
376
- Project publishes to:
377
- - **npm**: `@mavogel/cdk-vscode-server`
378
- - **PyPI**: `cdk-vscode-server`
379
-
380
- JSII compiles TypeScript to:
381
- - JavaScript (npm)
382
- - Python (PyPI)
383
-
384
- **Publishing** (requires credentials):
385
- ```bash
386
- npx projen release
387
- ```
388
-
389
- ## Workshop-Specific Considerations
390
-
391
- **Remember**: This construct is intentionally designed for workshops, NOT production:
392
-
393
- - IAM roles have broad permissions (all CDK operations)
394
- - Security groups allow CloudFront only (but permissive within that constraint)
395
- - No private subnets or VPC endpoints (cost optimization for workshops)
396
- - Single public subnet (simplicity over high availability)
397
- - Password-based authentication (ease of use over MFA/SSO)
398
-
399
- When reviewing changes, prioritize **ease of use** and **quick setup** over security hardening.
1
+ @AGENTS.md
@@ -46,7 +46,7 @@ const constructs_1 = require("constructs");
46
46
  * Construct that monitors CloudFront request metrics and stops the EC2 instance when idle
47
47
  */
48
48
  class IdleMonitor extends constructs_1.Construct {
49
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@mavogel/cdk-vscode-server.IdleMonitor", version: "0.0.99" };
49
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@mavogel/cdk-vscode-server.IdleMonitor", version: "0.0.101" };
50
50
  /**
51
51
  * The Lambda function that performs idle monitoring
52
52
  */
@@ -158,10 +158,10 @@ export declare abstract class Installer {
158
158
  */
159
159
  private createInstallCDKStep;
160
160
  /**
161
- * Creates the InstallQCLI step for SSM document
161
+ * Creates the InstallKiroCLI step for SSM document
162
162
  * This step is identical for both Ubuntu and Amazon Linux
163
163
  */
164
- private createInstallQCLIStep;
164
+ private createInstallKiroCLIStep;
165
165
  /**
166
166
  * Creates the Installuv step for SSM document
167
167
  * This step is identical for both Ubuntu and Amazon Linux