@mavogel/cdk-vscode-server 0.0.63 โ†’ 0.0.65

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 (55) hide show
  1. package/.jsii +127 -38
  2. package/API.md +112 -1
  3. package/CLAUDE.md +121 -4
  4. package/README.md +64 -1
  5. package/examples/auto-stop/main.ts +1 -1
  6. package/examples/custom/main.ts +24 -2
  7. package/examples/custom-install-steps/main.ts +201 -0
  8. package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.assets.json +2 -2
  9. package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.template.json +1 -1
  10. package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.assets.json +2 -2
  11. package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.template.json +3 -3
  12. package/integ-tests/integ.custom-domain.ts.snapshot/integ.json +1 -1
  13. package/integ-tests/integ.custom-domain.ts.snapshot/manifest.json +8 -5
  14. package/integ-tests/integ.custom-domain.ts.snapshot/tree.json +1 -1
  15. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegStopOnIdleFunctionalityDefaultTestDeployAssertEECF3FC0.assets.json +2 -2
  16. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegStopOnIdleFunctionalityDefaultTestDeployAssertEECF3FC0.template.json +4 -4
  17. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegTestStackStopOnIdle.assets.json +2 -2
  18. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegTestStackStopOnIdle.template.json +3 -3
  19. package/integ-tests/integ.stop-on-idle.ts.snapshot/manifest.json +12 -6
  20. package/integ-tests/integ.stop-on-idle.ts.snapshot/tree.json +1 -1
  21. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.assets.json +2 -2
  22. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.template.json +1 -1
  23. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.assets.json +2 -2
  24. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.template.json +3 -3
  25. package/integ-tests/integ.ubuntu.ts.snapshot/integ.json +1 -1
  26. package/integ-tests/integ.ubuntu.ts.snapshot/manifest.json +8 -5
  27. package/integ-tests/integ.ubuntu.ts.snapshot/tree.json +1 -1
  28. package/integ-tests/integ.ubuntu25.ts +69 -0
  29. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegSetupVSCodeOnUbuntu25DefaultTestDeployAssert48DBCF35.assets.json +33 -0
  30. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegSetupVSCodeOnUbuntu25DefaultTestDeployAssert48DBCF35.template.json +337 -0
  31. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegTestStackUbuntu25.assets.json +118 -0
  32. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegTestStackUbuntu25.template.json +2725 -0
  33. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d/index.js +1 -0
  34. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.2f99f38311da357eaaea1284d67c759759324dec4a1cd11621d9c59eea9e81df.lambda/index.js +180 -0
  35. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle/index.js +30676 -0
  36. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda/index.js +57 -0
  37. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/__entrypoint__.js +1 -0
  38. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/index.js +1 -0
  39. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00/index.js +1 -0
  40. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/cfn-response.js +1 -0
  41. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/consts.js +1 -0
  42. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/framework.js +3 -0
  43. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/outbound.js +1 -0
  44. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/util.js +1 -0
  45. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.efac30c7091c58fed492058fa6403c14f7e58aab8cf4fd595d838b8d5eeec2b9/index.js +6017 -0
  46. package/integ-tests/integ.ubuntu25.ts.snapshot/integ.json +23 -0
  47. package/integ-tests/integ.ubuntu25.ts.snapshot/manifest.json +1473 -0
  48. package/integ-tests/integ.ubuntu25.ts.snapshot/tree.json +1 -0
  49. package/lib/idle-monitor/idle-monitor.js +1 -1
  50. package/lib/installer/installer.d.ts +11 -0
  51. package/lib/installer/installer.js +21 -4
  52. package/lib/mappings.js +11 -3
  53. package/lib/vscode-server.d.ts +57 -1
  54. package/lib/vscode-server.js +12 -3
  55. package/package.json +1 -1
package/.jsii CHANGED
@@ -4102,7 +4102,7 @@
4102
4102
  },
4103
4103
  "name": "@mavogel/cdk-vscode-server",
4104
4104
  "readme": {
4105
- "markdown": "![Source](https://img.shields.io/github/stars/MV-Consulting/cdk-vscode-server?logo=github&label=GitHub%20Stars)\n[![Build Status](https://github.com/MV-Consulting/cdk-vscode-server/actions/workflows/build.yml/badge.svg)](https://github.com/MV-Consulting/cdk-vscode-server/actions/workflows/build.yml)\n[![ESLint Code Formatting](https://img.shields.io/badge/code_style-eslint-brightgreen.svg)](https://eslint.org)\n[![Latest release](https://img.shields.io/github/release/MV-Consulting/cdk-vscode-server.svg)](https://github.com/MV-Consulting/cdk-vscode-server/releases)\n![GitHub](https://img.shields.io/github/license/MV-Consulting/cdk-vscode-server)\n[![npm](https://img.shields.io/npm/dt/@mavogel/cdk-vscode-server?label=npm&color=orange)](https://www.npmjs.com/package/@mavogel/cdk-vscode-server)\n[![typescript](https://img.shields.io/badge/jsii-typescript-blueviolet.svg)](https://www.npmjs.com/package/@mavogel/cdk-vscode-server)\n\n# cdk-vscode-server\n\nRunning your dev IDE vscode on AWS for development and workshop purposes.\n\n> [!Note]\n> This construct is designed for workshop purposes and does not fulfill all security and authentication best practices.\n\n![EXPERIMENTAL](https://img.shields.io/badge/stability-experimantal-orange?style=for-the-badge)**<br>This is an early version of the package. The API will change while I\nwe implement new features. Therefore make sure you use an exact version in your `package.json` before it reaches 1.0.0.**\n\n## Table of Contents\n\n- [Features](#features)\n- [Usage](#usage)\n - [Standard](#Standard)\n - [Pre-populate with Git Repository](#pre-populate-with-git-repository)\n - [Custom Domain Configuration](#custom-domain-configuration)\n - [Auto-Stop Configuration](#auto-stop-configuration)\n- [Solution Design](#solution-design)\n- [Inspiration](#inspiration)\n\n## Features\n\n- โšก **Quick Setup**: Spin up and configure your [vscode](https://code.visualstudio.com/) server in under 10 minutes in your AWS account\n- ๐Ÿ“ **Best Practice Setup**: Set up with [projen](https://projen.io/) and a [single configuration file](./.projenrc.ts) to keep your changes centralized.\n- ๐Ÿคนโ€โ™‚๏ธ **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.\n- ๐ŸŒ **Custom Domain Support**: Use your own domain name with automatic ACM certificate creation and Route53 DNS configuration, or bring your existing certificate.\n- ๐Ÿ’ฐ **Auto-Stop**: Automatically stop EC2 instances after inactivity with Elastic IP retention - save up to 75% on costs for development environments.\n- ๐Ÿ—๏ธ **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...\n\n## Usage\nActually we supported 2 modes:\n\n### Standard\nThe following steps get you started:\n\n1. Create a new `awscdk-app` via\n```bash\nnpx projen new awscdk-app-ts --package-manager=npm\n```\n3. Add `@mavogel/cdk-vscode-server` as a dependency to your project in the `.projenrc.ts` file\n4. Run `npx projen` to install it\n5. Add the following to the `src/main.ts` file:\n```ts\nimport { App, Stack, StackProps } from 'aws-cdk-lib';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport * as iam from 'aws-cdk-lib/aws-iam';\nimport { Construct } from 'constructs';\nimport {\n LinuxArchitectureType,\n LinuxFlavorType,\n VSCodeServer\n} from '@mavogel/cdk-vscode-server';\n\nexport class MyStack extends Stack {\n constructor(scope: Construct, id: string, props: StackProps = {}) {\n super(scope, id, props);\n\n new VSCodeServer(this, 'vscode', {\n // for example (or simply use the defaults by not setting the properties)\n instanceVolumeSize: 8,\n instanceClass: ec2.InstanceClass.M7G,\n instanceSize: ec2.InstanceSize.LARGE,\n instanceOperatingSystem: LinuxFlavorType.UBUNTU_22,\n instanceCpuArchitecture: LinuxArchitectureType.ARM,\n\n // ๐Ÿ‘‡๐Ÿฝ or if you want to give the InstanceRole more permissions\n additionalInstanceRolePolicies: [\n new iam.PolicyStatement({\n effect: iam.Effect.ALLOW,\n actions: [\n 'codebuild:*',\n ],\n resources: [\n `arn:aws:codebuild:*:${Stack.of(this).account}:*/*`,\n ],\n }),\n ]\n\n // and more... ๐Ÿ’ก\n });\n }\n}\n\nconst env = {\n account: '123456789912',\n region: 'eu-central-1',\n};\n\nconst app = new App();\nnew MyStack(app, 'vscode-server', { env });\napp.synth();\n```\n\nand deploy it\n```bash\nnpx projen build\nnpx projen deploy\n```\n\nwith the output\n```console\nโœจ Deployment time: 509.87s\n\nOutputs:\ndev.vscodedomainName6729AA39 = https://d1foo65bar4baz.cloudfront.net/?folder=/Workshop\ndev.vscodepassword64FBCA12 = foobarbaz\n```\n\nSee the [examples](./examples) folder for more inspiration.\n\n### Pre-populate with Git Repository\n\nClone a git repository into the VS Code Server's home folder during instance setup - perfect for workshops or development environments with starter code:\n\n```ts\nnew VSCodeServer(this, 'vscode', {\n // Clone a git repository into the home folder\n repoUrl: 'https://github.com/aws-samples/my-workshop-repo.git',\n\n // Optional: customize the home folder path (default: /Workshop)\n homeFolder: '/MyWorkshop',\n\n // Optional: specify VS Code user (default: vscode-user)\n vscodeUser: 'workshop-user',\n});\n```\n\n**What happens:**\n1. During instance setup, the specified git repository is cloned into the user's home folder\n2. VS Code Server opens with the repository already loaded and ready to use\n3. Participants can start coding immediately without manual git clone steps\n\n**Use cases:**\n- Workshop environments with pre-configured starter code\n- Development environments with boilerplate projects\n- Training sessions with example applications\n- Code review sessions with pre-loaded repositories\n\n**Repository requirements:**\n- Must be publicly accessible (no authentication required)\n- HTTPS URLs only (SSH git URLs are not supported)\n- Repository will be cloned using `git clone` during instance initialization\n\nFor complete examples, see [examples/](./examples).\n\n### Custom Domain Configuration\n\nYou 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:\n\n#### Option 1: Auto-create Certificate with DNS Validation\n```ts\nnew VSCodeServer(this, 'vscode', {\n domainName: 'vscode.example.com',\n hostedZoneId: 'Z123EXAMPLE456', // optional - will auto-discover if not provided\n autoCreateCertificate: true,\n});\n```\n\nThis will:\n- Create an ACM certificate in us-east-1 (required for CloudFront)\n- Validate the certificate using DNS validation\n- Create a Route53 A record pointing to the CloudFront distribution\n- Configure the CloudFront distribution with the custom domain\n\n#### Option 2: Use Existing Certificate\n```ts\nnew VSCodeServer(this, 'vscode', {\n domainName: 'vscode.example.com',\n hostedZoneId: 'Z123EXAMPLE456',\n certificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012',\n});\n```\n\n**Requirements:**\n- Certificate must be in us-east-1 region\n- Certificate must be validated and ready to use\n- Certificate must include the domain name\n\n#### Option 3: Default (No Custom Domain)\n```ts\nnew VSCodeServer(this, 'vscode', {\n // No domain configuration - uses CloudFront default domain\n});\n```\n\nFor complete examples, see [examples/custom-domain/main.ts](./examples/custom-domain/main.ts).\n\n6. Then open the domain name in your favorite browser and you'd see the following login screen:\n![vscode-server-ui-login](docs/img/vscode-server-ui-login-min.png)\n\n7. After entering the password, you are logged into VSCode and can start coding :tada:\n\n![vscode-server-ui](docs/img/vscode-server-ui-min.png)\n\n> [!Important]\n> There are issues with copy pasting into the VSCode terminal within the Firefox browser (2025-01-12)\n\n### Auto-Stop Configuration\n\nSave up to 75% on costs by automatically stopping EC2 instances when idle:\n\n```ts\nnew VSCodeServer(this, 'vscode', {\n enableAutoStop: true, // Enable auto-stop feature\n idleTimeoutMinutes: 30, // Stop after 30 minutes of no activity (default)\n idleCheckIntervalMinutes: 5, // Check for idle activity every 5 minutes (default)\n});\n```\n\n**How it works:**\n1. **Idle Detection**: Monitors CloudFront request metrics at configured intervals (default: every 5 minutes)\n2. **Auto-Stop**: Stops the EC2 instance after the configured idle timeout when no requests are detected\n3. **Static IP**: Allocates an Elastic IP to maintain a consistent public IP address across stop/start cycles\n4. **Manual Resume**: Users can manually start the instance via AWS Console or CLI when needed\n\n**Cost Savings Example:**\n- **Without auto-stop**: m7g.xlarge running 24/7 = ~$120/month\n- **With auto-stop** (8 hours/day, 5 days/week): ~$30/month\n- **Savings**: ~$90/month (75% reduction)\n\n**Additional costs:**\n- Elastic IP (allocated): ~$3.65/month\n- Lambda function (IdleMonitor): ~$0.10/month\n- EventBridge rule: Negligible\n- **Net savings**: ~$86/month per instance\n\n**Architecture Components:**\n- Elastic IP for consistent public addressing\n- EventBridge rule triggering idle monitoring at configured intervals\n- IdleMonitor Lambda function checking CloudWatch metrics for request activity\n- IdleMonitorEnabler custom resource ensuring monitoring only starts after installation completes\n- CloudWatch metrics from CloudFront distribution\n\n**Integration Testing:**\n\nThe stop-on-idle functionality includes comprehensive integration tests (`integ-tests/integ.stop-on-idle.ts`) that verify the complete workflow:\n\n1. **Phase 1 - Verify Auto-Stop**: Waits for the instance to automatically stop after the configured idle timeout\n2. **Phase 2 - Disable IdleMonitor**: Disables the EventBridge rule to prevent the instance from being stopped again during testing\n3. **Phase 3 - Start Instance**: Starts the stopped instance and waits for it to reach the running state\n4. **Phase 4 - Verify Login**: Confirms that VS Code Server is accessible through CloudFront after the instance has been restarted\n\nThis 4-phase test ensures that:\n- Idle detection works correctly based on CloudWatch metrics\n- Instance stops automatically when no activity is detected\n- Instance can be successfully restarted after being stopped\n- VS Code Server remains accessible after stop/start cycles\n- Elastic IP maintains connectivity across state changes\n\nRun integration tests with:\n```bash\nnpm run integ-test\n```\n\n## Solution Design\n\n<details>\n <summary>... if you're curious about click here for the details</summary>\n\n![vscode-server-solution-design](docs/img/vscode-server.drawio-min.png)\n\n</details>\n\n## Inspiration\nThis project was created based on the following inspiration\n\n- [vscode-on-ec2-for-prototyping](https://github.com/aws-samples/vscode-on-ec2-for-prototyping): as baseline, which unfortunately was outdated\n- [aws-terraform-dev-container](https://github.com/awslabs/aws-terraform-dev-container): as baseline for terraform, but unfortunately also outdated\n- [java-on-aws-workshop-ide-only.yaml](https://github.com/aws-samples/java-on-aws/blob/main/labs/unicorn-store/infrastructure/cfn/java-on-aws-workshop-ide-only.yaml): an already synthesized cloudformation stack, which used mostly python as the custom resources\n- [fleet-workshop-team-stack-self.json](https://static.us-east-1.prod.workshops.aws/public/cc4aa67e-5b7a-4df1-abf7-c42502899a25/assets/fleet-workshop-team-stack-self.json): also an already synthesized cloudformation stack, which did much more as I currently implemented here.\n- [eks-workshop-vscode-cfn.yaml](https://github.com/aws-samples/eks-workshop-v2/blob/main/lab/cfn/eks-workshop-vscode-cfn.yaml): another great baseline\n\n\n## ๐Ÿš€ Unlock the Full Potential of Your AWS Cloud Infrastructure\n\nHi, Iโ€™m Manuel, an AWS expert passionate about empowering businesses with **scalable, resilient, and cost-optimized cloud solutions**. With **MV Consulting**, I specialize in crafting **tailored AWS architectures** and **DevOps-driven workflows** that not only meet your current needs but grow with you.\n\n---\n\n### ๐ŸŒŸ Why Work With Me?\n\nโœ”๏ธ **Tailored AWS Solutions:** Every business is unique, so I design custom solutions that fit your goals and challenges.\nโœ”๏ธ **Well-Architected Designs:** From scalability to security, my solutions align with AWS Well-Architected Framework.\nโœ”๏ธ **Cloud-Native Focus:** I specialize in modern, cloud-native systems that embrace the full potential of AWS.\nโœ”๏ธ **Business-Driven Tech:** Technology should serve your business, not the other way around.\n\n---\n\n### ๐Ÿ›  What I Bring to the Table\n\n๐Ÿ”‘ **12x AWS Certifications**\nIโ€™m **AWS Certified Solutions Architect and DevOps โ€“ Professional** and hold numerous additional certifications, so you can trust Iโ€™ll bring industry best practices to your projects. Feel free to explose by [badges](https://www.credly.com/users/manuel-vogel)\n\nโš™๏ธ **Infrastructure as Code (IaC)**\nWith deep expertise in **AWS CDK** and **Terraform**, I ensure your infrastructure is automated, maintainable, and scalable.\n\n๐Ÿ“ฆ **DevOps Expertise**\nFrom CI/CD pipelines with **GitHub Actions** and **GitLab CI** to container orchestration **Kubernetes** and others, I deliver workflows that are smooth and efficient.\n\n๐ŸŒ **Hands-On Experience**\nWith over **7 years of AWS experience** and a decade in the tech world, Iโ€™ve delivered solutions for companies large and small. My open-source contributions showcase my commitment to transparency and innovation. Feel free to explore my [GitHub profile](https://github.com/mavogel)\n\n---\n\n### ๐Ÿ’ผ Letโ€™s Build Something Great Together\n\nI know that choosing the right partner is critical to your success. When you work with me, youโ€™re not just contracting an engineer โ€“ youโ€™re gaining a trusted advisor and hands-on expert who cares about your business as much as you do.\n\nโœ”๏ธ **Direct Collaboration**: No middlemen or red tape โ€“ you work with me directly.\nโœ”๏ธ **Transparent Process**: Expect open communication, clear timelines, and visible results.\nโœ”๏ธ **Real Value**: My solutions focus on delivering measurable impact for your business.\n\n\n<a href=\"https://tinyurl.com/mvc-15min\"><img alt=\"Schedule your call\" src=\"https://img.shields.io/badge/schedule%20your%20call-success.svg?style=for-the-badge\"/></a>\n\n---\n\n## ๐Ÿ™Œ Acknowledgements\n\nBig shoutout to the amazing team behind [Projen](https://github.com/projen/projen)!\nTheir groundbreaking work simplifies cloud infrastructure projects and inspires us every day. ๐Ÿ’ก\n\n## Author\n\n[Manuel Vogel](https://manuel-vogel.de/about/)\n\n[![](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/manuel-vogel)\n[![](https://img.shields.io/badge/GitHub-2b3137?style=for-the-badge&logo=github&logoColor=white)](https://github.com/mavogel)"
4105
+ "markdown": "![Source](https://img.shields.io/github/stars/MV-Consulting/cdk-vscode-server?logo=github&label=GitHub%20Stars)\n[![Build Status](https://github.com/MV-Consulting/cdk-vscode-server/actions/workflows/build.yml/badge.svg)](https://github.com/MV-Consulting/cdk-vscode-server/actions/workflows/build.yml)\n[![ESLint Code Formatting](https://img.shields.io/badge/code_style-eslint-brightgreen.svg)](https://eslint.org)\n[![Latest release](https://img.shields.io/github/release/MV-Consulting/cdk-vscode-server.svg)](https://github.com/MV-Consulting/cdk-vscode-server/releases)\n![GitHub](https://img.shields.io/github/license/MV-Consulting/cdk-vscode-server)\n[![npm](https://img.shields.io/npm/dt/@mavogel/cdk-vscode-server?label=npm&color=orange)](https://www.npmjs.com/package/@mavogel/cdk-vscode-server)\n[![typescript](https://img.shields.io/badge/jsii-typescript-blueviolet.svg)](https://www.npmjs.com/package/@mavogel/cdk-vscode-server)\n\n# cdk-vscode-server\n\nRunning your dev IDE vscode on AWS for development and workshop purposes.\n\n> [!Note]\n> This construct is designed for workshop purposes and does not fulfill all security and authentication best practices.\n\n![EXPERIMENTAL](https://img.shields.io/badge/stability-experimantal-orange?style=for-the-badge)**<br>This is an early version of the package. The API will change while I\nwe implement new features. Therefore make sure you use an exact version in your `package.json` before it reaches 1.0.0.**\n\n## Table of Contents\n\n- [Features](#features)\n- [Usage](#usage)\n - [Standard](#Standard)\n - [Pre-populate with Git Repository](#pre-populate-with-git-repository)\n - [Custom Domain Configuration](#custom-domain-configuration)\n - [Auto-Stop Configuration](#auto-stop-configuration)\n - [Custom Installation Steps](#custom-installation-steps)\n- [Solution Design](#solution-design)\n- [Inspiration](#inspiration)\n\n## Features\n\n- โšก **Quick Setup**: Spin up and configure your [vscode](https://code.visualstudio.com/) server in under 10 minutes in your AWS account\n- ๐Ÿ“ **Best Practice Setup**: Set up with [projen](https://projen.io/) and a [single configuration file](./.projenrc.ts) to keep your changes centralized.\n- ๐Ÿคนโ€โ™‚๏ธ **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.\n- ๐ŸŒ **Custom Domain Support**: Use your own domain name with automatic ACM certificate creation and Route53 DNS configuration, or bring your existing certificate.\n- ๐Ÿ’ฐ **Auto-Stop**: Automatically stop EC2 instances after inactivity with Elastic IP retention - save up to 75% on costs for development environments.\n- ๐Ÿ”ง **Custom Install Steps**: Extend the standard installation with your own shell commands to install workshop-specific tools, configure environments, or run setup scripts.\n- ๐Ÿ—๏ธ **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...\n\n## Usage\nActually we supported 2 modes:\n\n### Standard\nThe following steps get you started:\n\n1. Create a new `awscdk-app` via\n```bash\nnpx projen new awscdk-app-ts --package-manager=npm\n```\n3. Add `@mavogel/cdk-vscode-server` as a dependency to your project in the `.projenrc.ts` file\n4. Run `npx projen` to install it\n5. Add the following to the `src/main.ts` file:\n```ts\nimport { App, Stack, StackProps } from 'aws-cdk-lib';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport * as iam from 'aws-cdk-lib/aws-iam';\nimport { Construct } from 'constructs';\nimport {\n LinuxArchitectureType,\n LinuxFlavorType,\n VSCodeServer\n} from '@mavogel/cdk-vscode-server';\n\nexport class MyStack extends Stack {\n constructor(scope: Construct, id: string, props: StackProps = {}) {\n super(scope, id, props);\n\n new VSCodeServer(this, 'vscode', {\n // for example (or simply use the defaults by not setting the properties)\n instanceVolumeSize: 8,\n instanceClass: ec2.InstanceClass.M7G,\n instanceSize: ec2.InstanceSize.LARGE,\n instanceOperatingSystem: LinuxFlavorType.UBUNTU_24,\n instanceCpuArchitecture: LinuxArchitectureType.ARM,\n\n // ๐Ÿ‘‡๐Ÿฝ or if you want to give the InstanceRole more permissions\n additionalInstanceRolePolicies: [\n new iam.PolicyStatement({\n effect: iam.Effect.ALLOW,\n actions: [\n 'codebuild:*',\n ],\n resources: [\n `arn:aws:codebuild:*:${Stack.of(this).account}:*/*`,\n ],\n }),\n ]\n\n // and more... ๐Ÿ’ก\n });\n }\n}\n\nconst env = {\n account: '123456789912',\n region: 'eu-central-1',\n};\n\nconst app = new App();\nnew MyStack(app, 'vscode-server', { env });\napp.synth();\n```\n\nand deploy it\n```bash\nnpx projen build\nnpx projen deploy\n```\n\nwith the output\n```console\nโœจ Deployment time: 509.87s\n\nOutputs:\ndev.vscodedomainName6729AA39 = https://d1foo65bar4baz.cloudfront.net/?folder=/Workshop\ndev.vscodepassword64FBCA12 = foobarbaz\n```\n\nSee the [examples](./examples) folder for more inspiration.\n\n### Pre-populate with Git Repository\n\nClone a git repository into the VS Code Server's home folder during instance setup - perfect for workshops or development environments with starter code:\n\n```ts\nnew VSCodeServer(this, 'vscode', {\n // Clone a git repository into the home folder\n repoUrl: 'https://github.com/aws-samples/my-workshop-repo.git',\n\n // Optional: customize the home folder path (default: /Workshop)\n homeFolder: '/MyWorkshop',\n\n // Optional: specify VS Code user (default: vscode-user)\n vscodeUser: 'workshop-user',\n});\n```\n\n**What happens:**\n1. During instance setup, the specified git repository is cloned into the user's home folder\n2. VS Code Server opens with the repository already loaded and ready to use\n3. Participants can start coding immediately without manual git clone steps\n\n**Use cases:**\n- Workshop environments with pre-configured starter code\n- Development environments with boilerplate projects\n- Training sessions with example applications\n- Code review sessions with pre-loaded repositories\n\n**Repository requirements:**\n- Must be publicly accessible (no authentication required)\n- HTTPS URLs only (SSH git URLs are not supported)\n- Repository will be cloned using `git clone` during instance initialization\n\nFor complete examples, see [examples/](./examples).\n\n### Custom Domain Configuration\n\nYou 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:\n\n#### Option 1: Auto-create Certificate with DNS Validation\n```ts\nnew VSCodeServer(this, 'vscode', {\n domainName: 'vscode.example.com',\n hostedZoneId: 'Z123EXAMPLE456', // optional - will auto-discover if not provided\n autoCreateCertificate: true,\n});\n```\n\nThis will:\n- Create an ACM certificate in us-east-1 (required for CloudFront)\n- Validate the certificate using DNS validation\n- Create a Route53 A record pointing to the CloudFront distribution\n- Configure the CloudFront distribution with the custom domain\n\n#### Option 2: Use Existing Certificate\n```ts\nnew VSCodeServer(this, 'vscode', {\n domainName: 'vscode.example.com',\n hostedZoneId: 'Z123EXAMPLE456',\n certificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012',\n});\n```\n\n**Requirements:**\n- Certificate must be in us-east-1 region\n- Certificate must be validated and ready to use\n- Certificate must include the domain name\n\n#### Option 3: Default (No Custom Domain)\n```ts\nnew VSCodeServer(this, 'vscode', {\n // No domain configuration - uses CloudFront default domain\n});\n```\n\nFor complete examples, see [examples/custom-domain/main.ts](./examples/custom-domain/main.ts).\n\n6. Then open the domain name in your favorite browser and you'd see the following login screen:\n![vscode-server-ui-login](docs/img/vscode-server-ui-login-min.png)\n\n7. After entering the password, you are logged into VSCode and can start coding :tada:\n\n![vscode-server-ui](docs/img/vscode-server-ui-min.png)\n\n> [!Important]\n> There are issues with copy pasting into the VSCode terminal within the Firefox browser (2025-01-12)\n\n### Auto-Stop Configuration\n\nSave up to 75% on costs by automatically stopping EC2 instances when idle:\n\n```ts\nnew VSCodeServer(this, 'vscode', {\n enableAutoStop: true, // Enable auto-stop feature\n idleTimeoutMinutes: 30, // Stop after 30 minutes of no activity (default)\n idleCheckIntervalMinutes: 5, // Check for idle activity every 5 minutes (default)\n});\n```\n\n**How it works:**\n1. **Idle Detection**: Monitors CloudFront request metrics at configured intervals (default: every 5 minutes)\n2. **Auto-Stop**: Stops the EC2 instance after the configured idle timeout when no requests are detected\n3. **Static IP**: Allocates an Elastic IP to maintain a consistent public IP address across stop/start cycles\n4. **Manual Resume**: Users can manually start the instance via AWS Console or CLI when needed\n\n**Cost Savings Example:**\n- **Without auto-stop**: m7g.xlarge running 24/7 = ~$120/month\n- **With auto-stop** (8 hours/day, 5 days/week): ~$30/month\n- **Savings**: ~$90/month (75% reduction)\n\n**Additional costs:**\n- Elastic IP (allocated): ~$3.65/month\n- Lambda function (IdleMonitor): ~$0.10/month\n- EventBridge rule: Negligible\n- **Net savings**: ~$86/month per instance\n\n**Architecture Components:**\n- Elastic IP for consistent public addressing\n- EventBridge rule triggering idle monitoring at configured intervals\n- IdleMonitor Lambda function checking CloudWatch metrics for request activity\n- IdleMonitorEnabler custom resource ensuring monitoring only starts after installation completes\n- CloudWatch metrics from CloudFront distribution\n\n**Integration Testing:**\n\nThe stop-on-idle functionality includes comprehensive integration tests (`integ-tests/integ.stop-on-idle.ts`) that verify the complete workflow:\n\n1. **Phase 1 - Verify Auto-Stop**: Waits for the instance to automatically stop after the configured idle timeout\n2. **Phase 2 - Disable IdleMonitor**: Disables the EventBridge rule to prevent the instance from being stopped again during testing\n3. **Phase 3 - Start Instance**: Starts the stopped instance and waits for it to reach the running state\n4. **Phase 4 - Verify Login**: Confirms that VS Code Server is accessible through CloudFront after the instance has been restarted\n\nThis 4-phase test ensures that:\n- Idle detection works correctly based on CloudWatch metrics\n- Instance stops automatically when no activity is detected\n- Instance can be successfully restarted after being stopped\n- VS Code Server remains accessible after stop/start cycles\n- Elastic IP maintains connectivity across state changes\n\nRun integration tests with:\n```bash\nnpm run integ-test\n```\n\n### Custom Installation Steps\n\nExtend the standard VS Code Server installation with your own custom shell commands - perfect for installing workshop-specific tools, configuring development environments, or running setup scripts:\n\n```ts\nnew VSCodeServer(this, 'vscode', {\n // Add custom installation steps that run after standard setup\n customInstallSteps: [\n {\n name: 'InstallWorkshopTools',\n commands: [\n '#!/bin/bash',\n 'echo \"Installing workshop-specific tools\"',\n\n // Install additional software\n 'curl -fsSL https://get.docker.com | sh',\n 'usermod -aG docker ubuntu',\n\n // Configure environment\n 'echo \"export WORKSHOP_ENV=production\" >> /home/ubuntu/.bashrc',\n ],\n },\n {\n name: 'CloneStarterCode',\n commands: [\n '#!/bin/bash',\n 'cd /home/ubuntu',\n 'git clone https://github.com/my-org/workshop-starter.git',\n 'chown -R ubuntu:ubuntu workshop-starter',\n ],\n },\n ],\n});\n```\n\n**Key Features:**\n- **Execute After Standard Setup**: Custom steps run after VS Code Server installation completes\n- **Multiple Steps**: Add as many installation steps as needed, executed in order\n- **Full Shell Access**: Run any shell commands with root privileges\n- **Workshop-Friendly**: Pre-install tools, configure environments, or download starter code\n\n**Common Use Cases:**\n- Install additional development tools (Docker, kubectl, terraform)\n- Configure workshop-specific environments and credentials\n- Clone starter code repositories with specific permissions\n- Set up databases or services required for training\n- Download and prepare datasets or assets\n- Configure IDE extensions or settings\n\n**Supported Operating Systems:**\n- Ubuntu 22/24/25\n- Amazon Linux 2023\n\n**Requirements:**\n- Commands execute with root privileges during instance initialization\n- Use absolute paths or ensure proper working directory context\n- Consider idempotency if instance might be restarted\n- Commands run synchronously in the order specified\n\nFor complete examples, see [examples/custom-install-steps/main.ts](./examples/custom-install-steps/main.ts).\n\n## Solution Design\n\n<details>\n <summary>... if you're curious about click here for the details</summary>\n\n![vscode-server-solution-design](docs/img/vscode-server.drawio-min.png)\n\n</details>\n\n## Inspiration\nThis project was created based on the following inspiration\n\n- [vscode-on-ec2-for-prototyping](https://github.com/aws-samples/vscode-on-ec2-for-prototyping): as baseline, which unfortunately was outdated\n- [aws-terraform-dev-container](https://github.com/awslabs/aws-terraform-dev-container): as baseline for terraform, but unfortunately also outdated\n- [java-on-aws-workshop-ide-only.yaml](https://github.com/aws-samples/java-on-aws/blob/main/labs/unicorn-store/infrastructure/cfn/java-on-aws-workshop-ide-only.yaml): an already synthesized cloudformation stack, which used mostly python as the custom resources\n- [fleet-workshop-team-stack-self.json](https://static.us-east-1.prod.workshops.aws/public/cc4aa67e-5b7a-4df1-abf7-c42502899a25/assets/fleet-workshop-team-stack-self.json): also an already synthesized cloudformation stack, which did much more as I currently implemented here.\n- [eks-workshop-vscode-cfn.yaml](https://github.com/aws-samples/eks-workshop-v2/blob/main/lab/cfn/eks-workshop-vscode-cfn.yaml): another great baseline\n\n\n## ๐Ÿš€ Unlock the Full Potential of Your AWS Cloud Infrastructure\n\nHi, Iโ€™m Manuel, an AWS expert passionate about empowering businesses with **scalable, resilient, and cost-optimized cloud solutions**. With **MV Consulting**, I specialize in crafting **tailored AWS architectures** and **DevOps-driven workflows** that not only meet your current needs but grow with you.\n\n---\n\n### ๐ŸŒŸ Why Work With Me?\n\nโœ”๏ธ **Tailored AWS Solutions:** Every business is unique, so I design custom solutions that fit your goals and challenges.\nโœ”๏ธ **Well-Architected Designs:** From scalability to security, my solutions align with AWS Well-Architected Framework.\nโœ”๏ธ **Cloud-Native Focus:** I specialize in modern, cloud-native systems that embrace the full potential of AWS.\nโœ”๏ธ **Business-Driven Tech:** Technology should serve your business, not the other way around.\n\n---\n\n### ๐Ÿ›  What I Bring to the Table\n\n๐Ÿ”‘ **12x AWS Certifications**\nIโ€™m **AWS Certified Solutions Architect and DevOps โ€“ Professional** and hold numerous additional certifications, so you can trust Iโ€™ll bring industry best practices to your projects. Feel free to explose by [badges](https://www.credly.com/users/manuel-vogel)\n\nโš™๏ธ **Infrastructure as Code (IaC)**\nWith deep expertise in **AWS CDK** and **Terraform**, I ensure your infrastructure is automated, maintainable, and scalable.\n\n๐Ÿ“ฆ **DevOps Expertise**\nFrom CI/CD pipelines with **GitHub Actions** and **GitLab CI** to container orchestration **Kubernetes** and others, I deliver workflows that are smooth and efficient.\n\n๐ŸŒ **Hands-On Experience**\nWith over **7 years of AWS experience** and a decade in the tech world, Iโ€™ve delivered solutions for companies large and small. My open-source contributions showcase my commitment to transparency and innovation. Feel free to explore my [GitHub profile](https://github.com/mavogel)\n\n---\n\n### ๐Ÿ’ผ Letโ€™s Build Something Great Together\n\nI know that choosing the right partner is critical to your success. When you work with me, youโ€™re not just contracting an engineer โ€“ youโ€™re gaining a trusted advisor and hands-on expert who cares about your business as much as you do.\n\nโœ”๏ธ **Direct Collaboration**: No middlemen or red tape โ€“ you work with me directly.\nโœ”๏ธ **Transparent Process**: Expect open communication, clear timelines, and visible results.\nโœ”๏ธ **Real Value**: My solutions focus on delivering measurable impact for your business.\n\n\n<a href=\"https://tinyurl.com/mvc-15min\"><img alt=\"Schedule your call\" src=\"https://img.shields.io/badge/schedule%20your%20call-success.svg?style=for-the-badge\"/></a>\n\n---\n\n## ๐Ÿ™Œ Acknowledgements\n\nBig shoutout to the amazing team behind [Projen](https://github.com/projen/projen)!\nTheir groundbreaking work simplifies cloud infrastructure projects and inspires us every day. ๐Ÿ’ก\n\n## Author\n\n[Manuel Vogel](https://manuel-vogel.de/about/)\n\n[![](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/manuel-vogel)\n[![](https://img.shields.io/badge/GitHub-2b3137?style=for-the-badge&logo=github&logoColor=white)](https://github.com/mavogel)"
4106
4106
  },
4107
4107
  "repository": {
4108
4108
  "type": "git",
@@ -4119,6 +4119,63 @@
4119
4119
  }
4120
4120
  },
4121
4121
  "types": {
4122
+ "@mavogel/cdk-vscode-server.CustomInstallStep": {
4123
+ "assembly": "@mavogel/cdk-vscode-server",
4124
+ "datatype": true,
4125
+ "docs": {
4126
+ "stability": "experimental",
4127
+ "summary": "Custom installation step for SSM document Allows users to extend the installer with additional shell commands."
4128
+ },
4129
+ "fqn": "@mavogel/cdk-vscode-server.CustomInstallStep",
4130
+ "kind": "interface",
4131
+ "locationInModule": {
4132
+ "filename": "src/vscode-server.ts",
4133
+ "line": 31
4134
+ },
4135
+ "name": "CustomInstallStep",
4136
+ "properties": [
4137
+ {
4138
+ "abstract": true,
4139
+ "docs": {
4140
+ "example": "['#!/bin/bash', 'echo \"Installing custom tool\"', 'apt-get install -y my-tool']",
4141
+ "stability": "experimental",
4142
+ "summary": "Shell commands to run for this step Each command will be executed in sequence."
4143
+ },
4144
+ "immutable": true,
4145
+ "locationInModule": {
4146
+ "filename": "src/vscode-server.ts",
4147
+ "line": 46
4148
+ },
4149
+ "name": "commands",
4150
+ "type": {
4151
+ "collection": {
4152
+ "elementtype": {
4153
+ "primitive": "string"
4154
+ },
4155
+ "kind": "array"
4156
+ }
4157
+ }
4158
+ },
4159
+ {
4160
+ "abstract": true,
4161
+ "docs": {
4162
+ "example": "'InstallCustomTool'",
4163
+ "stability": "experimental",
4164
+ "summary": "Name of the installation step Must be unique within the SSM document."
4165
+ },
4166
+ "immutable": true,
4167
+ "locationInModule": {
4168
+ "filename": "src/vscode-server.ts",
4169
+ "line": 38
4170
+ },
4171
+ "name": "name",
4172
+ "type": {
4173
+ "primitive": "string"
4174
+ }
4175
+ }
4176
+ ],
4177
+ "symbolId": "src/vscode-server:CustomInstallStep"
4178
+ },
4122
4179
  "@mavogel/cdk-vscode-server.IdleMonitor": {
4123
4180
  "assembly": "@mavogel/cdk-vscode-server",
4124
4181
  "base": "constructs.Construct",
@@ -4309,7 +4366,7 @@
4309
4366
  "kind": "enum",
4310
4367
  "locationInModule": {
4311
4368
  "filename": "src/vscode-server.ts",
4312
- "line": 264
4369
+ "line": 324
4313
4370
  },
4314
4371
  "members": [
4315
4372
  {
@@ -4340,7 +4397,7 @@
4340
4397
  "kind": "enum",
4341
4398
  "locationInModule": {
4342
4399
  "filename": "src/vscode-server.ts",
4343
- "line": 244
4400
+ "line": 299
4344
4401
  },
4345
4402
  "members": [
4346
4403
  {
@@ -4357,6 +4414,13 @@
4357
4414
  },
4358
4415
  "name": "UBUNTU_24"
4359
4416
  },
4417
+ {
4418
+ "docs": {
4419
+ "stability": "experimental",
4420
+ "summary": "Ubuntu 25."
4421
+ },
4422
+ "name": "UBUNTU_25"
4423
+ },
4360
4424
  {
4361
4425
  "docs": {
4362
4426
  "stability": "experimental",
@@ -4382,7 +4446,7 @@
4382
4446
  },
4383
4447
  "locationInModule": {
4384
4448
  "filename": "src/vscode-server.ts",
4385
- "line": 300
4449
+ "line": 360
4386
4450
  },
4387
4451
  "parameters": [
4388
4452
  {
@@ -4409,7 +4473,7 @@
4409
4473
  "kind": "class",
4410
4474
  "locationInModule": {
4411
4475
  "filename": "src/vscode-server.ts",
4412
- "line": 279
4476
+ "line": 339
4413
4477
  },
4414
4478
  "name": "VSCodeServer",
4415
4479
  "properties": [
@@ -4421,7 +4485,7 @@
4421
4485
  "immutable": true,
4422
4486
  "locationInModule": {
4423
4487
  "filename": "src/vscode-server.ts",
4424
- "line": 283
4488
+ "line": 343
4425
4489
  },
4426
4490
  "name": "domainName",
4427
4491
  "type": {
@@ -4436,7 +4500,7 @@
4436
4500
  "immutable": true,
4437
4501
  "locationInModule": {
4438
4502
  "filename": "src/vscode-server.ts",
4439
- "line": 293
4503
+ "line": 353
4440
4504
  },
4441
4505
  "name": "instance",
4442
4506
  "type": {
@@ -4451,7 +4515,7 @@
4451
4515
  "immutable": true,
4452
4516
  "locationInModule": {
4453
4517
  "filename": "src/vscode-server.ts",
4454
- "line": 288
4518
+ "line": 348
4455
4519
  },
4456
4520
  "name": "password",
4457
4521
  "type": {
@@ -4466,7 +4530,7 @@
4466
4530
  "immutable": true,
4467
4531
  "locationInModule": {
4468
4532
  "filename": "src/vscode-server.ts",
4469
- "line": 298
4533
+ "line": 358
4470
4534
  },
4471
4535
  "name": "idleMonitor",
4472
4536
  "optional": true,
@@ -4488,7 +4552,7 @@
4488
4552
  "kind": "interface",
4489
4553
  "locationInModule": {
4490
4554
  "filename": "src/vscode-server.ts",
4491
- "line": 30
4555
+ "line": 52
4492
4556
  },
4493
4557
  "name": "VSCodeServerProps",
4494
4558
  "properties": [
@@ -4502,7 +4566,7 @@
4502
4566
  "immutable": true,
4503
4567
  "locationInModule": {
4504
4568
  "filename": "src/vscode-server.ts",
4505
- "line": 113
4569
+ "line": 135
4506
4570
  },
4507
4571
  "name": "additionalInstanceRolePolicies",
4508
4572
  "optional": true,
@@ -4525,7 +4589,7 @@
4525
4589
  "immutable": true,
4526
4590
  "locationInModule": {
4527
4591
  "filename": "src/vscode-server.ts",
4528
- "line": 120
4592
+ "line": 142
4529
4593
  },
4530
4594
  "name": "additionalTags",
4531
4595
  "optional": true,
@@ -4550,7 +4614,7 @@
4550
4614
  "immutable": true,
4551
4615
  "locationInModule": {
4552
4616
  "filename": "src/vscode-server.ts",
4553
- "line": 216
4617
+ "line": 238
4554
4618
  },
4555
4619
  "name": "assetZipS3Path",
4556
4620
  "optional": true,
@@ -4568,7 +4632,7 @@
4568
4632
  "immutable": true,
4569
4633
  "locationInModule": {
4570
4634
  "filename": "src/vscode-server.ts",
4571
- "line": 157
4635
+ "line": 179
4572
4636
  },
4573
4637
  "name": "autoCreateCertificate",
4574
4638
  "optional": true,
@@ -4588,7 +4652,7 @@
4588
4652
  "immutable": true,
4589
4653
  "locationInModule": {
4590
4654
  "filename": "src/vscode-server.ts",
4591
- "line": 227
4655
+ "line": 249
4592
4656
  },
4593
4657
  "name": "branchZipS3Path",
4594
4658
  "optional": true,
@@ -4606,7 +4670,7 @@
4606
4670
  "immutable": true,
4607
4671
  "locationInModule": {
4608
4672
  "filename": "src/vscode-server.ts",
4609
- "line": 147
4673
+ "line": 169
4610
4674
  },
4611
4675
  "name": "certificateArn",
4612
4676
  "optional": true,
@@ -4614,6 +4678,31 @@
4614
4678
  "primitive": "string"
4615
4679
  }
4616
4680
  },
4681
+ {
4682
+ "abstract": true,
4683
+ "docs": {
4684
+ "default": "- no custom installation steps",
4685
+ "example": "customInstallSteps: [\n {\n name: 'InstallCustomTool',\n commands: [\n '#!/bin/bash',\n 'echo \"Installing my custom tool\"',\n 'curl -O https://example.com/tool.sh',\n 'bash tool.sh',\n ],\n },\n {\n name: 'ConfigureWorkshopEnv',\n commands: [\n '#!/bin/bash',\n 'echo \"export MY_VAR=value\" >> /home/participant/.bashrc',\n ],\n },\n]",
4686
+ "remarks": "Allows you to add additional shell commands that run after the standard installation steps.\nUseful for installing workshop-specific tools, configuring custom environments, or running\nsetup scripts.\n\nEach step will be executed in the order provided, after all standard installation steps complete.",
4687
+ "stability": "experimental",
4688
+ "summary": "Custom installation steps to extend the SSM document."
4689
+ },
4690
+ "immutable": true,
4691
+ "locationInModule": {
4692
+ "filename": "src/vscode-server.ts",
4693
+ "line": 293
4694
+ },
4695
+ "name": "customInstallSteps",
4696
+ "optional": true,
4697
+ "type": {
4698
+ "collection": {
4699
+ "elementtype": {
4700
+ "fqn": "@mavogel/cdk-vscode-server.CustomInstallStep"
4701
+ },
4702
+ "kind": "array"
4703
+ }
4704
+ }
4705
+ },
4617
4706
  {
4618
4707
  "abstract": true,
4619
4708
  "docs": {
@@ -4624,7 +4713,7 @@
4624
4713
  "immutable": true,
4625
4714
  "locationInModule": {
4626
4715
  "filename": "src/vscode-server.ts",
4627
- "line": 99
4716
+ "line": 121
4628
4717
  },
4629
4718
  "name": "devServerBasePath",
4630
4719
  "optional": true,
@@ -4642,7 +4731,7 @@
4642
4731
  "immutable": true,
4643
4732
  "locationInModule": {
4644
4733
  "filename": "src/vscode-server.ts",
4645
- "line": 106
4734
+ "line": 128
4646
4735
  },
4647
4736
  "name": "devServerPort",
4648
4737
  "optional": true,
@@ -4660,7 +4749,7 @@
4660
4749
  "immutable": true,
4661
4750
  "locationInModule": {
4662
4751
  "filename": "src/vscode-server.ts",
4663
- "line": 129
4752
+ "line": 151
4664
4753
  },
4665
4754
  "name": "domainName",
4666
4755
  "optional": true,
@@ -4678,7 +4767,7 @@
4678
4767
  "immutable": true,
4679
4768
  "locationInModule": {
4680
4769
  "filename": "src/vscode-server.ts",
4681
- "line": 165
4770
+ "line": 187
4682
4771
  },
4683
4772
  "name": "enableAutoStop",
4684
4773
  "optional": true,
@@ -4698,7 +4787,7 @@
4698
4787
  "immutable": true,
4699
4788
  "locationInModule": {
4700
4789
  "filename": "src/vscode-server.ts",
4701
- "line": 238
4790
+ "line": 260
4702
4791
  },
4703
4792
  "name": "folderZipS3Path",
4704
4793
  "optional": true,
@@ -4716,7 +4805,7 @@
4716
4805
  "immutable": true,
4717
4806
  "locationInModule": {
4718
4807
  "filename": "src/vscode-server.ts",
4719
- "line": 92
4808
+ "line": 114
4720
4809
  },
4721
4810
  "name": "homeFolder",
4722
4811
  "optional": true,
@@ -4734,7 +4823,7 @@
4734
4823
  "immutable": true,
4735
4824
  "locationInModule": {
4736
4825
  "filename": "src/vscode-server.ts",
4737
- "line": 138
4826
+ "line": 160
4738
4827
  },
4739
4828
  "name": "hostedZoneId",
4740
4829
  "optional": true,
@@ -4752,7 +4841,7 @@
4752
4841
  "immutable": true,
4753
4842
  "locationInModule": {
4754
4843
  "filename": "src/vscode-server.ts",
4755
- "line": 181
4844
+ "line": 203
4756
4845
  },
4757
4846
  "name": "idleCheckIntervalMinutes",
4758
4847
  "optional": true,
@@ -4770,7 +4859,7 @@
4770
4859
  "immutable": true,
4771
4860
  "locationInModule": {
4772
4861
  "filename": "src/vscode-server.ts",
4773
- "line": 173
4862
+ "line": 195
4774
4863
  },
4775
4864
  "name": "idleTimeoutMinutes",
4776
4865
  "optional": true,
@@ -4788,7 +4877,7 @@
4788
4877
  "immutable": true,
4789
4878
  "locationInModule": {
4790
4879
  "filename": "src/vscode-server.ts",
4791
- "line": 64
4880
+ "line": 86
4792
4881
  },
4793
4882
  "name": "instanceClass",
4794
4883
  "optional": true,
@@ -4806,7 +4895,7 @@
4806
4895
  "immutable": true,
4807
4896
  "locationInModule": {
4808
4897
  "filename": "src/vscode-server.ts",
4809
- "line": 85
4898
+ "line": 107
4810
4899
  },
4811
4900
  "name": "instanceCpuArchitecture",
4812
4901
  "optional": true,
@@ -4824,7 +4913,7 @@
4824
4913
  "immutable": true,
4825
4914
  "locationInModule": {
4826
4915
  "filename": "src/vscode-server.ts",
4827
- "line": 50
4916
+ "line": 72
4828
4917
  },
4829
4918
  "name": "instanceName",
4830
4919
  "optional": true,
@@ -4835,14 +4924,14 @@
4835
4924
  {
4836
4925
  "abstract": true,
4837
4926
  "docs": {
4838
- "default": "- Ubuntu-22",
4927
+ "default": "- Ubuntu-24",
4839
4928
  "stability": "experimental",
4840
4929
  "summary": "VSCode Server EC2 operating system."
4841
4930
  },
4842
4931
  "immutable": true,
4843
4932
  "locationInModule": {
4844
4933
  "filename": "src/vscode-server.ts",
4845
- "line": 78
4934
+ "line": 100
4846
4935
  },
4847
4936
  "name": "instanceOperatingSystem",
4848
4937
  "optional": true,
@@ -4860,7 +4949,7 @@
4860
4949
  "immutable": true,
4861
4950
  "locationInModule": {
4862
4951
  "filename": "src/vscode-server.ts",
4863
- "line": 71
4952
+ "line": 93
4864
4953
  },
4865
4954
  "name": "instanceSize",
4866
4955
  "optional": true,
@@ -4878,7 +4967,7 @@
4878
4967
  "immutable": true,
4879
4968
  "locationInModule": {
4880
4969
  "filename": "src/vscode-server.ts",
4881
- "line": 57
4970
+ "line": 79
4882
4971
  },
4883
4972
  "name": "instanceVolumeSize",
4884
4973
  "optional": true,
@@ -4898,7 +4987,7 @@
4898
4987
  "immutable": true,
4899
4988
  "locationInModule": {
4900
4989
  "filename": "src/vscode-server.ts",
4901
- "line": 205
4990
+ "line": 227
4902
4991
  },
4903
4992
  "name": "repoUrl",
4904
4993
  "optional": true,
@@ -4917,7 +5006,7 @@
4917
5006
  "immutable": true,
4918
5007
  "locationInModule": {
4919
5008
  "filename": "src/vscode-server.ts",
4920
- "line": 194
5009
+ "line": 216
4921
5010
  },
4922
5011
  "name": "skipStatusChecks",
4923
5012
  "optional": true,
@@ -4935,7 +5024,7 @@
4935
5024
  "immutable": true,
4936
5025
  "locationInModule": {
4937
5026
  "filename": "src/vscode-server.ts",
4938
- "line": 43
5027
+ "line": 65
4939
5028
  },
4940
5029
  "name": "vscodePassword",
4941
5030
  "optional": true,
@@ -4953,7 +5042,7 @@
4953
5042
  "immutable": true,
4954
5043
  "locationInModule": {
4955
5044
  "filename": "src/vscode-server.ts",
4956
- "line": 36
5045
+ "line": 58
4957
5046
  },
4958
5047
  "name": "vscodeUser",
4959
5048
  "optional": true,
@@ -4965,6 +5054,6 @@
4965
5054
  "symbolId": "src/vscode-server:VSCodeServerProps"
4966
5055
  }
4967
5056
  },
4968
- "version": "0.0.63",
4969
- "fingerprint": "WvxdieugMWZqOIWa0lvMJ93ykF+/f8+uUocq/yMhBjA="
5057
+ "version": "0.0.65",
5058
+ "fingerprint": "7vbIqLB8Ot4WaR5BJMRcdxC62yqLMBmLo5+GQVZqV0I="
4970
5059
  }
package/API.md CHANGED
@@ -312,6 +312,65 @@ The IdleMonitor construct (only present if enableAutoStop is true).
312
312
 
313
313
  ## Structs <a name="Structs" id="Structs"></a>
314
314
 
315
+ ### CustomInstallStep <a name="CustomInstallStep" id="@mavogel/cdk-vscode-server.CustomInstallStep"></a>
316
+
317
+ Custom installation step for SSM document Allows users to extend the installer with additional shell commands.
318
+
319
+ #### Initializer <a name="Initializer" id="@mavogel/cdk-vscode-server.CustomInstallStep.Initializer"></a>
320
+
321
+ ```typescript
322
+ import { CustomInstallStep } from '@mavogel/cdk-vscode-server'
323
+
324
+ const customInstallStep: CustomInstallStep = { ... }
325
+ ```
326
+
327
+ #### Properties <a name="Properties" id="Properties"></a>
328
+
329
+ | **Name** | **Type** | **Description** |
330
+ | --- | --- | --- |
331
+ | <code><a href="#@mavogel/cdk-vscode-server.CustomInstallStep.property.commands">commands</a></code> | <code>string[]</code> | Shell commands to run for this step Each command will be executed in sequence. |
332
+ | <code><a href="#@mavogel/cdk-vscode-server.CustomInstallStep.property.name">name</a></code> | <code>string</code> | Name of the installation step Must be unique within the SSM document. |
333
+
334
+ ---
335
+
336
+ ##### `commands`<sup>Required</sup> <a name="commands" id="@mavogel/cdk-vscode-server.CustomInstallStep.property.commands"></a>
337
+
338
+ ```typescript
339
+ public readonly commands: string[];
340
+ ```
341
+
342
+ - *Type:* string[]
343
+
344
+ Shell commands to run for this step Each command will be executed in sequence.
345
+
346
+ ---
347
+
348
+ *Example*
349
+
350
+ ```typescript
351
+ ['#!/bin/bash', 'echo "Installing custom tool"', 'apt-get install -y my-tool']
352
+ ```
353
+
354
+
355
+ ##### `name`<sup>Required</sup> <a name="name" id="@mavogel/cdk-vscode-server.CustomInstallStep.property.name"></a>
356
+
357
+ ```typescript
358
+ public readonly name: string;
359
+ ```
360
+
361
+ - *Type:* string
362
+
363
+ Name of the installation step Must be unique within the SSM document.
364
+
365
+ ---
366
+
367
+ *Example*
368
+
369
+ ```typescript
370
+ 'InstallCustomTool'
371
+ ```
372
+
373
+
315
374
  ### IdleMonitorProps <a name="IdleMonitorProps" id="@mavogel/cdk-vscode-server.IdleMonitorProps"></a>
316
375
 
317
376
  Props for IdleMonitor construct.
@@ -423,6 +482,7 @@ const vSCodeServerProps: VSCodeServerProps = { ... }
423
482
  | <code><a href="#@mavogel/cdk-vscode-server.VSCodeServerProps.property.autoCreateCertificate">autoCreateCertificate</a></code> | <code>boolean</code> | Auto-create ACM certificate with DNS validation in us-east-1 region Requires hostedZoneId to be provided for DNS validation Cannot be used together with certificateArn Certificate will automatically be created in us-east-1 as required by CloudFront. |
424
483
  | <code><a href="#@mavogel/cdk-vscode-server.VSCodeServerProps.property.branchZipS3Path">branchZipS3Path</a></code> | <code>string</code> | S3 path to a zip file containing git branches to create in the home folder repository. |
425
484
  | <code><a href="#@mavogel/cdk-vscode-server.VSCodeServerProps.property.certificateArn">certificateArn</a></code> | <code>string</code> | ARN of existing ACM certificate for the domain Certificate must be in us-east-1 region for CloudFront Cannot be used together with autoCreateCertificate. |
485
+ | <code><a href="#@mavogel/cdk-vscode-server.VSCodeServerProps.property.customInstallSteps">customInstallSteps</a></code> | <code><a href="#@mavogel/cdk-vscode-server.CustomInstallStep">CustomInstallStep</a>[]</code> | Custom installation steps to extend the SSM document. |
426
486
  | <code><a href="#@mavogel/cdk-vscode-server.VSCodeServerProps.property.devServerBasePath">devServerBasePath</a></code> | <code>string</code> | Base path for the application to be added to Nginx sites-available list. |
427
487
  | <code><a href="#@mavogel/cdk-vscode-server.VSCodeServerProps.property.devServerPort">devServerPort</a></code> | <code>number</code> | Port for the DevServer. |
428
488
  | <code><a href="#@mavogel/cdk-vscode-server.VSCodeServerProps.property.domainName">domainName</a></code> | <code>string</code> | Custom domain name for the VS Code server When provided, creates a CloudFront distribution with this domain name and sets up Route53 A record pointing to the distribution. |
@@ -543,6 +603,49 @@ ARN of existing ACM certificate for the domain Certificate must be in us-east-1
543
603
 
544
604
  ---
545
605
 
606
+ ##### `customInstallSteps`<sup>Optional</sup> <a name="customInstallSteps" id="@mavogel/cdk-vscode-server.VSCodeServerProps.property.customInstallSteps"></a>
607
+
608
+ ```typescript
609
+ public readonly customInstallSteps: CustomInstallStep[];
610
+ ```
611
+
612
+ - *Type:* <a href="#@mavogel/cdk-vscode-server.CustomInstallStep">CustomInstallStep</a>[]
613
+ - *Default:* no custom installation steps
614
+
615
+ Custom installation steps to extend the SSM document.
616
+
617
+ Allows you to add additional shell commands that run after the standard installation steps.
618
+ Useful for installing workshop-specific tools, configuring custom environments, or running
619
+ setup scripts.
620
+
621
+ Each step will be executed in the order provided, after all standard installation steps complete.
622
+
623
+ ---
624
+
625
+ *Example*
626
+
627
+ ```typescript
628
+ customInstallSteps: [
629
+ {
630
+ name: 'InstallCustomTool',
631
+ commands: [
632
+ '#!/bin/bash',
633
+ 'echo "Installing my custom tool"',
634
+ 'curl -O https://example.com/tool.sh',
635
+ 'bash tool.sh',
636
+ ],
637
+ },
638
+ {
639
+ name: 'ConfigureWorkshopEnv',
640
+ commands: [
641
+ '#!/bin/bash',
642
+ 'echo "export MY_VAR=value" >> /home/participant/.bashrc',
643
+ ],
644
+ },
645
+ ]
646
+ ```
647
+
648
+
546
649
  ##### `devServerBasePath`<sup>Optional</sup> <a name="devServerBasePath" id="@mavogel/cdk-vscode-server.VSCodeServerProps.property.devServerBasePath"></a>
547
650
 
548
651
  ```typescript
@@ -716,7 +819,7 @@ public readonly instanceOperatingSystem: LinuxFlavorType;
716
819
  ```
717
820
 
718
821
  - *Type:* <a href="#@mavogel/cdk-vscode-server.LinuxFlavorType">LinuxFlavorType</a>
719
- - *Default:* Ubuntu-22
822
+ - *Default:* Ubuntu-24
720
823
 
721
824
  VSCode Server EC2 operating system.
722
825
 
@@ -854,6 +957,7 @@ The flavor of linux you want to run vscode server on.
854
957
  | --- | --- |
855
958
  | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_22">UBUNTU_22</a></code> | Ubuntu 22. |
856
959
  | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_24">UBUNTU_24</a></code> | Ubuntu 24. |
960
+ | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_25">UBUNTU_25</a></code> | Ubuntu 25. |
857
961
  | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.AMAZON_LINUX_2023">AMAZON_LINUX_2023</a></code> | Amazon Linux 2023. |
858
962
 
859
963
  ---
@@ -872,6 +976,13 @@ Ubuntu 24.
872
976
  ---
873
977
 
874
978
 
979
+ ##### `UBUNTU_25` <a name="UBUNTU_25" id="@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_25"></a>
980
+
981
+ Ubuntu 25.
982
+
983
+ ---
984
+
985
+
875
986
  ##### `AMAZON_LINUX_2023` <a name="AMAZON_LINUX_2023" id="@mavogel/cdk-vscode-server.LinuxFlavorType.AMAZON_LINUX_2023"></a>
876
987
 
877
988
  Amazon Linux 2023.