@mavogel/cdk-vscode-server 0.0.63 β†’ 0.0.64

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 (54) hide show
  1. package/.jsii +18 -11
  2. package/API.md +9 -1
  3. package/CLAUDE.md +75 -2
  4. package/README.md +1 -1
  5. package/examples/auto-stop/main.ts +1 -1
  6. package/examples/custom/main.ts +1 -1
  7. package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.assets.json +2 -2
  8. package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.template.json +1 -1
  9. package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.assets.json +2 -2
  10. package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.template.json +3 -3
  11. package/integ-tests/integ.custom-domain.ts.snapshot/integ.json +1 -1
  12. package/integ-tests/integ.custom-domain.ts.snapshot/manifest.json +8 -5
  13. package/integ-tests/integ.custom-domain.ts.snapshot/tree.json +1 -1
  14. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegStopOnIdleFunctionalityDefaultTestDeployAssertEECF3FC0.assets.json +2 -2
  15. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegStopOnIdleFunctionalityDefaultTestDeployAssertEECF3FC0.template.json +4 -4
  16. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegTestStackStopOnIdle.assets.json +2 -2
  17. package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegTestStackStopOnIdle.template.json +3 -3
  18. package/integ-tests/integ.stop-on-idle.ts.snapshot/manifest.json +12 -6
  19. package/integ-tests/integ.stop-on-idle.ts.snapshot/tree.json +1 -1
  20. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.assets.json +2 -2
  21. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.template.json +1 -1
  22. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.assets.json +2 -2
  23. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.template.json +3 -3
  24. package/integ-tests/integ.ubuntu.ts.snapshot/integ.json +1 -1
  25. package/integ-tests/integ.ubuntu.ts.snapshot/manifest.json +8 -5
  26. package/integ-tests/integ.ubuntu.ts.snapshot/tree.json +1 -1
  27. package/integ-tests/integ.ubuntu25.ts +69 -0
  28. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegSetupVSCodeOnUbuntu25DefaultTestDeployAssert48DBCF35.assets.json +33 -0
  29. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegSetupVSCodeOnUbuntu25DefaultTestDeployAssert48DBCF35.template.json +337 -0
  30. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegTestStackUbuntu25.assets.json +118 -0
  31. package/integ-tests/integ.ubuntu25.ts.snapshot/IntegTestStackUbuntu25.template.json +2725 -0
  32. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d/index.js +1 -0
  33. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.2f99f38311da357eaaea1284d67c759759324dec4a1cd11621d9c59eea9e81df.lambda/index.js +180 -0
  34. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle/index.js +30676 -0
  35. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda/index.js +57 -0
  36. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/__entrypoint__.js +1 -0
  37. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/index.js +1 -0
  38. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00/index.js +1 -0
  39. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/cfn-response.js +1 -0
  40. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/consts.js +1 -0
  41. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/framework.js +3 -0
  42. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/outbound.js +1 -0
  43. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/util.js +1 -0
  44. package/integ-tests/integ.ubuntu25.ts.snapshot/asset.efac30c7091c58fed492058fa6403c14f7e58aab8cf4fd595d838b8d5eeec2b9/index.js +6017 -0
  45. package/integ-tests/integ.ubuntu25.ts.snapshot/integ.json +23 -0
  46. package/integ-tests/integ.ubuntu25.ts.snapshot/manifest.json +1473 -0
  47. package/integ-tests/integ.ubuntu25.ts.snapshot/tree.json +1 -0
  48. package/lib/idle-monitor/idle-monitor.js +1 -1
  49. package/lib/installer/installer.d.ts +5 -0
  50. package/lib/installer/installer.js +3 -2
  51. package/lib/mappings.js +11 -3
  52. package/lib/vscode-server.d.ts +5 -1
  53. package/lib/vscode-server.js +10 -3
  54. 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- [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_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## 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",
@@ -4309,7 +4309,7 @@
4309
4309
  "kind": "enum",
4310
4310
  "locationInModule": {
4311
4311
  "filename": "src/vscode-server.ts",
4312
- "line": 264
4312
+ "line": 269
4313
4313
  },
4314
4314
  "members": [
4315
4315
  {
@@ -4357,6 +4357,13 @@
4357
4357
  },
4358
4358
  "name": "UBUNTU_24"
4359
4359
  },
4360
+ {
4361
+ "docs": {
4362
+ "stability": "experimental",
4363
+ "summary": "Ubuntu 25."
4364
+ },
4365
+ "name": "UBUNTU_25"
4366
+ },
4360
4367
  {
4361
4368
  "docs": {
4362
4369
  "stability": "experimental",
@@ -4382,7 +4389,7 @@
4382
4389
  },
4383
4390
  "locationInModule": {
4384
4391
  "filename": "src/vscode-server.ts",
4385
- "line": 300
4392
+ "line": 305
4386
4393
  },
4387
4394
  "parameters": [
4388
4395
  {
@@ -4409,7 +4416,7 @@
4409
4416
  "kind": "class",
4410
4417
  "locationInModule": {
4411
4418
  "filename": "src/vscode-server.ts",
4412
- "line": 279
4419
+ "line": 284
4413
4420
  },
4414
4421
  "name": "VSCodeServer",
4415
4422
  "properties": [
@@ -4421,7 +4428,7 @@
4421
4428
  "immutable": true,
4422
4429
  "locationInModule": {
4423
4430
  "filename": "src/vscode-server.ts",
4424
- "line": 283
4431
+ "line": 288
4425
4432
  },
4426
4433
  "name": "domainName",
4427
4434
  "type": {
@@ -4436,7 +4443,7 @@
4436
4443
  "immutable": true,
4437
4444
  "locationInModule": {
4438
4445
  "filename": "src/vscode-server.ts",
4439
- "line": 293
4446
+ "line": 298
4440
4447
  },
4441
4448
  "name": "instance",
4442
4449
  "type": {
@@ -4451,7 +4458,7 @@
4451
4458
  "immutable": true,
4452
4459
  "locationInModule": {
4453
4460
  "filename": "src/vscode-server.ts",
4454
- "line": 288
4461
+ "line": 293
4455
4462
  },
4456
4463
  "name": "password",
4457
4464
  "type": {
@@ -4466,7 +4473,7 @@
4466
4473
  "immutable": true,
4467
4474
  "locationInModule": {
4468
4475
  "filename": "src/vscode-server.ts",
4469
- "line": 298
4476
+ "line": 303
4470
4477
  },
4471
4478
  "name": "idleMonitor",
4472
4479
  "optional": true,
@@ -4835,7 +4842,7 @@
4835
4842
  {
4836
4843
  "abstract": true,
4837
4844
  "docs": {
4838
- "default": "- Ubuntu-22",
4845
+ "default": "- Ubuntu-24",
4839
4846
  "stability": "experimental",
4840
4847
  "summary": "VSCode Server EC2 operating system."
4841
4848
  },
@@ -4965,6 +4972,6 @@
4965
4972
  "symbolId": "src/vscode-server:VSCodeServerProps"
4966
4973
  }
4967
4974
  },
4968
- "version": "0.0.63",
4969
- "fingerprint": "WvxdieugMWZqOIWa0lvMJ93ykF+/f8+uUocq/yMhBjA="
4975
+ "version": "0.0.64",
4976
+ "fingerprint": "3BRi+GN6i44q+cFPoBqPuFqBcUPFx0g3BHIvuo4ciaM="
4970
4977
  }
package/API.md CHANGED
@@ -716,7 +716,7 @@ public readonly instanceOperatingSystem: LinuxFlavorType;
716
716
  ```
717
717
 
718
718
  - *Type:* <a href="#@mavogel/cdk-vscode-server.LinuxFlavorType">LinuxFlavorType</a>
719
- - *Default:* Ubuntu-22
719
+ - *Default:* Ubuntu-24
720
720
 
721
721
  VSCode Server EC2 operating system.
722
722
 
@@ -854,6 +854,7 @@ The flavor of linux you want to run vscode server on.
854
854
  | --- | --- |
855
855
  | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_22">UBUNTU_22</a></code> | Ubuntu 22. |
856
856
  | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_24">UBUNTU_24</a></code> | Ubuntu 24. |
857
+ | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_25">UBUNTU_25</a></code> | Ubuntu 25. |
857
858
  | <code><a href="#@mavogel/cdk-vscode-server.LinuxFlavorType.AMAZON_LINUX_2023">AMAZON_LINUX_2023</a></code> | Amazon Linux 2023. |
858
859
 
859
860
  ---
@@ -872,6 +873,13 @@ Ubuntu 24.
872
873
  ---
873
874
 
874
875
 
876
+ ##### `UBUNTU_25` <a name="UBUNTU_25" id="@mavogel/cdk-vscode-server.LinuxFlavorType.UBUNTU_25"></a>
877
+
878
+ Ubuntu 25.
879
+
880
+ ---
881
+
882
+
875
883
  ##### `AMAZON_LINUX_2023` <a name="AMAZON_LINUX_2023" id="@mavogel/cdk-vscode-server.LinuxFlavorType.AMAZON_LINUX_2023"></a>
876
884
 
877
885
  Amazon Linux 2023.
package/CLAUDE.md CHANGED
@@ -88,9 +88,10 @@ Uses Lambda-backed custom resources via CDK Provider construct:
88
88
 
89
89
  1. **Installer** (`src/installer/`)
90
90
  - Runs SSM documents to install VS Code Server
91
- - OS-specific installation for Ubuntu 22/24 and Amazon Linux 2023
91
+ - OS-specific installation for Ubuntu 22/24/25 and Amazon Linux 2023
92
92
  - Returns SUCCESS when installation completes
93
93
  - Custom resource name: `SSMInstallerCustomResource`
94
+ - **Critical**: Must pass `linuxFlavorType` parameter to ensure correct OS-specific SSM document is used
94
95
 
95
96
  2. **SecretRetriever** (`src/secret-retriever/`)
96
97
  - Extracts generated password from Secrets Manager
@@ -130,11 +131,28 @@ enabler.node.addDependency(installerCustomResource);
130
131
  ### AMI Selection (`src/mappings.ts`)
131
132
 
132
133
  Contains SSM parameter paths for:
133
- - Ubuntu 22/24 (ARM + x86_64)
134
+ - Ubuntu 22/24/25 (ARM + x86_64)
134
135
  - Amazon Linux 2023 (ARM + x86_64)
135
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
+
136
142
  Function `getAmiSSMParameterForLinuxArchitectureAndFlavor()` returns region-specific SSM parameter for latest AMI.
137
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
+
138
156
  ### Key Props (`src/vscode-server.ts:27-200`)
139
157
 
140
158
  **Instance Configuration**:
@@ -183,6 +201,8 @@ Located in `integ-tests/`, using `@aws-cdk/integ-tests-alpha` framework.
183
201
 
184
202
  **Test Files**:
185
203
  - `integ.ubuntu.ts` - Basic Ubuntu 22 deployment + login test
204
+ - `integ.ubuntu24.ts` - Ubuntu 24 deployment + login test
205
+ - `integ.ubuntu25.ts` - Ubuntu 25 deployment + login test
186
206
  - `integ.al2023.ts` - Amazon Linux 2023 deployment
187
207
  - `integ.custom-domain.ts` - Custom domain + ACM certificate
188
208
  - `integ.stop-on-idle.ts` - **4-phase auto-stop workflow test**
@@ -231,6 +251,59 @@ Projen automatically discovers Lambda functions matching `src/**/*.lambda.ts` pa
231
251
  2. Build validation: `npx projen build` (includes awslint checks)
232
252
  3. Integration test: `npm run integ-test` (full deployment test)
233
253
 
254
+ ### Adding Support for a New Ubuntu Version
255
+
256
+ When Ubuntu releases a new version (e.g., Ubuntu 26):
257
+
258
+ 1. **Add AMI mappings** in `src/mappings.ts`:
259
+ ```typescript
260
+ [
261
+ 'arm-ubuntu26',
262
+ '/aws/service/canonical/ubuntu/server/CODENAME/stable/current/arm64/hvm/ebs-gp3/ami-id',
263
+ ],
264
+ [
265
+ 'amd64-ubuntu26',
266
+ '/aws/service/canonical/ubuntu/server/CODENAME/stable/current/amd64/hvm/ebs-gp3/ami-id',
267
+ ],
268
+ ```
269
+ Replace `CODENAME` with Ubuntu's codename (verify via AWS SSM Parameter Store)
270
+
271
+ 2. **Add enum value** in `src/vscode-server.ts`:
272
+ ```typescript
273
+ export enum LinuxFlavorType {
274
+ // ...
275
+ UBUNTU_26 = 'ubuntu26',
276
+ }
277
+ ```
278
+
279
+ 3. **Update Installer** in `src/installer/installer.ts`:
280
+ - Add `LinuxFlavorType.UBUNTU_26` to the Ubuntu switch case in `createSSMDocument()` (line ~657)
281
+ - Update installer calls in `src/vscode-server.ts` to include new case (line ~930)
282
+
283
+ 4. **Pass linuxFlavorType** in `src/vscode-server.ts`:
284
+ ```typescript
285
+ installer = Installer.ubuntu({
286
+ // ... other options
287
+ linuxFlavorType: instanceOperatingSystem, // Critical!
288
+ })._bind(this);
289
+ ```
290
+
291
+ 5. **Create integration test**: Copy `integ-tests/integ.ubuntu25.ts` to `integ.ubuntu26.ts` and update OS version
292
+
293
+ 6. **Update documentation**:
294
+ - Update README.md examples with inline comments showing all supported versions
295
+ - Examples in `examples/` directory (optional - can keep as Ubuntu 24)
296
+
297
+ 7. **Verify and build**:
298
+ ```bash
299
+ # Verify SSM parameters exist
300
+ aws ssm get-parameters-by-path --path "/aws/service/canonical/ubuntu/server/CODENAME/" --recursive --region us-east-1
301
+
302
+ # Build and test
303
+ npx projen build
304
+ npm run integ-test
305
+ ```
306
+
234
307
  ## Race Condition Prevention (Auto-Stop)
235
308
 
236
309
  **Issue**: IdleMonitor EventBridge rule triggers immediately on stack creation, potentially stopping instance during installation (observed: instance stopped 72 seconds after installer started).
package/README.md CHANGED
@@ -69,7 +69,7 @@ export class MyStack extends Stack {
69
69
  instanceVolumeSize: 8,
70
70
  instanceClass: ec2.InstanceClass.M7G,
71
71
  instanceSize: ec2.InstanceSize.LARGE,
72
- instanceOperatingSystem: LinuxFlavorType.UBUNTU_22,
72
+ instanceOperatingSystem: LinuxFlavorType.UBUNTU_24,
73
73
  instanceCpuArchitecture: LinuxArchitectureType.ARM,
74
74
 
75
75
  // πŸ‘‡πŸ½ or if you want to give the InstanceRole more permissions
@@ -37,7 +37,7 @@ export class AutoStopExampleStack extends Stack {
37
37
  instanceClass: ec2.InstanceClass.M7G,
38
38
  instanceSize: ec2.InstanceSize.XLARGE,
39
39
  instanceVolumeSize: 40,
40
- instanceOperatingSystem: LinuxFlavorType.UBUNTU_22,
40
+ instanceOperatingSystem: LinuxFlavorType.UBUNTU_24,
41
41
  instanceCpuArchitecture: LinuxArchitectureType.ARM,
42
42
 
43
43
  // πŸ”₯ Auto-Stop Configuration
@@ -17,7 +17,7 @@ export class MyStack extends Stack {
17
17
  instanceVolumeSize: 8,
18
18
  instanceClass: ec2.InstanceClass.M7G,
19
19
  instanceSize: ec2.InstanceSize.LARGE,
20
- instanceOperatingSystem: LinuxFlavorType.UBUNTU_22,
20
+ instanceOperatingSystem: LinuxFlavorType.UBUNTU_24,
21
21
  instanceCpuArchitecture: LinuxArchitectureType.ARM,
22
22
 
23
23
  // πŸ‘‡πŸ½ or if you want to give the InstanceRole more permissions
@@ -14,7 +14,7 @@
14
14
  }
15
15
  }
16
16
  },
17
- "c0c8c31a0be065be2df21bb20ec386bf72819c1e19f79e9fc09c29712e67a4a0": {
17
+ "4191278decec94a8cb032ef5af5b2424a3d6f3a20772116b870ecb754d98bb76": {
18
18
  "displayName": "IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514 Template",
19
19
  "source": {
20
20
  "path": "IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.template.json",
@@ -23,7 +23,7 @@
23
23
  "destinations": {
24
24
  "current_account-current_region": {
25
25
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
26
- "objectKey": "c0c8c31a0be065be2df21bb20ec386bf72819c1e19f79e9fc09c29712e67a4a0.json",
26
+ "objectKey": "4191278decec94a8cb032ef5af5b2424a3d6f3a20772116b870ecb754d98bb76.json",
27
27
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
28
28
  }
29
29
  }
@@ -41,7 +41,7 @@
41
41
  }
42
42
  },
43
43
  "flattenResponse": "false",
44
- "salt": "1762251890627"
44
+ "salt": "1762256639191"
45
45
  },
46
46
  "UpdateReplacePolicy": "Delete",
47
47
  "DeletionPolicy": "Delete"
@@ -113,7 +113,7 @@
113
113
  }
114
114
  }
115
115
  },
116
- "0d21ebe148c0168a894b38d8db4c34b6ac5b9a016612b7493c323c5d1dc23b7d": {
116
+ "7d89a55db29091c7bd6a0da54d0e29cfc725f77b6fcdde3eb3e136b774b01d04": {
117
117
  "displayName": "IntegTestStackCustomDomain Template",
118
118
  "source": {
119
119
  "path": "IntegTestStackCustomDomain.template.json",
@@ -122,7 +122,7 @@
122
122
  "destinations": {
123
123
  "current_account-current_region": {
124
124
  "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
125
- "objectKey": "0d21ebe148c0168a894b38d8db4c34b6ac5b9a016612b7493c323c5d1dc23b7d.json",
125
+ "objectKey": "7d89a55db29091c7bd6a0da54d0e29cfc725f77b6fcdde3eb3e136b774b01d04.json",
126
126
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
127
127
  }
128
128
  }
@@ -1418,7 +1418,7 @@
1418
1418
  "Ref": "IntegVSCodeServerserverinstanceInstanceProfile6130979E"
1419
1419
  },
1420
1420
  "ImageId": {
1421
- "Ref": "SsmParameterValueawsservicecanonicalubuntuserverjammystablecurrentarm64hvmebsgp2amiidC96584B6F00A464EAD1953AFF4B05118Parameter"
1421
+ "Ref": "SsmParameterValueawsservicecanonicalubuntuservernoblestablecurrentarm64hvmebsgp3amiidC96584B6F00A464EAD1953AFF4B05118Parameter"
1422
1422
  },
1423
1423
  "InstanceType": "m7g.xlarge",
1424
1424
  "LaunchTemplate": {
@@ -2998,9 +2998,9 @@
2998
2998
  }
2999
2999
  },
3000
3000
  "Parameters": {
3001
- "SsmParameterValueawsservicecanonicalubuntuserverjammystablecurrentarm64hvmebsgp2amiidC96584B6F00A464EAD1953AFF4B05118Parameter": {
3001
+ "SsmParameterValueawsservicecanonicalubuntuservernoblestablecurrentarm64hvmebsgp3amiidC96584B6F00A464EAD1953AFF4B05118Parameter": {
3002
3002
  "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
3003
- "Default": "/aws/service/canonical/ubuntu/server/jammy/stable/current/arm64/hvm/ebs-gp2/ami-id"
3003
+ "Default": "/aws/service/canonical/ubuntu/server/noble/stable/current/arm64/hvm/ebs-gp3/ami-id"
3004
3004
  },
3005
3005
  "BootstrapVersion": {
3006
3006
  "Type": "AWS::SSM::Parameter::Value<String>",
@@ -6,7 +6,7 @@
6
6
  "IntegTestStackCustomDomain"
7
7
  ],
8
8
  "regions": [
9
- "${Token[AWS.Region.8]}"
9
+ "${Token[AWS.Region.6]}"
10
10
  ],
11
11
  "cdkCommandOptions": {
12
12
  "destroy": {
@@ -18,7 +18,7 @@
18
18
  "validateOnSynth": false,
19
19
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
20
20
  "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
21
- "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/0d21ebe148c0168a894b38d8db4c34b6ac5b9a016612b7493c323c5d1dc23b7d.json",
21
+ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7d89a55db29091c7bd6a0da54d0e29cfc725f77b6fcdde3eb3e136b774b01d04.json",
22
22
  "requiresBootstrapStackVersion": 6,
23
23
  "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
24
24
  "additionalDependencies": [
@@ -902,7 +902,10 @@
902
902
  "/IntegTestStackCustomDomain/IntegVSCodeServer/server-instance/Resource": [
903
903
  {
904
904
  "type": "aws:cdk:logicalId",
905
- "data": "IntegVSCodeServerserverinstance0A3D62D7"
905
+ "data": "IntegVSCodeServerserverinstance0A3D62D7",
906
+ "trace": [
907
+ "!!DESTRUCTIVE_CHANGES: WILL_REPLACE"
908
+ ]
906
909
  }
907
910
  ],
908
911
  "/IntegTestStackCustomDomain/IntegVSCodeServer/server-instance/LaunchTemplate": [
@@ -1356,10 +1359,10 @@
1356
1359
  "data": "AWS679f53fac002430cb0da5b7982bd22872D164C4C"
1357
1360
  }
1358
1361
  ],
1359
- "/IntegTestStackCustomDomain/SsmParameterValue:--aws--service--canonical--ubuntu--server--jammy--stable--current--arm64--hvm--ebs-gp2--ami-id:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": [
1362
+ "/IntegTestStackCustomDomain/SsmParameterValue:--aws--service--canonical--ubuntu--server--noble--stable--current--arm64--hvm--ebs-gp3--ami-id:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": [
1360
1363
  {
1361
1364
  "type": "aws:cdk:logicalId",
1362
- "data": "SsmParameterValueawsservicecanonicalubuntuserverjammystablecurrentarm64hvmebsgp2amiidC96584B6F00A464EAD1953AFF4B05118Parameter"
1365
+ "data": "SsmParameterValueawsservicecanonicalubuntuservernoblestablecurrentarm64hvmebsgp3amiidC96584B6F00A464EAD1953AFF4B05118Parameter"
1363
1366
  }
1364
1367
  ],
1365
1368
  "/IntegTestStackCustomDomain/AWSCloudFrontPartitionHostedZoneIdMap": [
@@ -1576,7 +1579,7 @@
1576
1579
  "validateOnSynth": false,
1577
1580
  "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
1578
1581
  "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
1579
- "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c0c8c31a0be065be2df21bb20ec386bf72819c1e19f79e9fc09c29712e67a4a0.json",
1582
+ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4191278decec94a8cb032ef5af5b2424a3d6f3a20772116b870ecb754d98bb76.json",
1580
1583
  "requiresBootstrapStackVersion": 6,
1581
1584
  "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
1582
1585
  "additionalDependencies": [