Code Anywhere: Configure Your Personal Web-Based Code Editor with AWS CLI or AWS CDK
Tags: aws, cli, cdk, lightsail
Published: 2023-10-31 18:38:01

In this article, we will explore how to configure our own web-based code editor on Amazon Lightsail using either AWS CLI or AWS CDK.

![web-based-code-editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ksxjsmc4iw1vgo0ohsew.png)

## Follow me for more
{% embed https://linktr.ee/fullstacksaiyan %}

## Why Choose a Web-Based Code Editor?
Web-based code editors have some cool advantages:
- **Easy Access**: You can reach web-based code editors from any device with an internet connection, which means you can code from virtually anywhere and any device.
- **Teamwork**: Many web-based editors support real-time collaboration, letting multiple developers work on the same code simultaneously, boosting productivity and teamwork.
- **No Installation Headache**: You won't need to set up complex development environments on your local machine because web-based editors eliminate that requirement. This makes life easier and keeps your development team on the same page.
- **Platform Compatibility**: Since web-based code editors run in web browsers, they work across different operating systems. Developers using various platforms can collaborate and work on the same codebase without a hitch.
- **Cloud Storage**: Web-based code editors store your code in the cloud, reducing the risk of data loss and ensuring easy access from anywhere with an internet connection.


## Installer VS Code for the Web
[Installer VS Code for the Web](https://github.com/rioastamal/installer-vscode-for-web) is a nifty open-source installer script. It turns your fresh cloud Virtual Machine (VM) into a fully functional VS Code for the web with HTTPS enabled. This means you can work from any device that supports a modern web browser. 

Here are some cool features of this installer:
- Works on several Linux distributions.
- Offers options to install ready-to-use development packages.
- Automatically maps your VM's public IP address to a domain name.

## Amazon Lightsail
Amazon Lightsail is like the friendly neighborhood cloud computing service provided by Amazon Web Services (AWS). It's designed to make deploying and managing cloud resources a breeze for developers, small businesses, and individuals. You won't have to deal with the complexity and learning curve associated with traditional AWS services.

We're going to transform our Amazon Lightsail instance into a fully functional web-based code editor with HTTPS capability. And we'll do it using either AWS CLI or AWS CDK.

## Prerequisites
- [Install AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
- [Configure AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)
- [Install AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install)

## Table of Contents
- [Lightsail Resource Parameters](#step1)
- [Configure Lightsail with AWS CLI](#step2)
- [Configure Lightsail with AWS CDK](#step3)
- [Conclusions](#step4)

## Lightsail Resource Parameters <a name="step1"/>
When creating Lightsail resources, there are some key parameters to keep in mind:
- **Availability Zone**: In Amazon Lightsail, an "availability zone" is essentially a physically separate data center within an AWS region. AWS regions are divided into multiple availability zones to provide redundancy and fault tolerance. For example, in the Singapore region, you'll find availability zones like `ap-southeast-1a`, `ap-southeast-1b`, and `ap-southeast-1c`.

- **Blueprint ID**: In Amazon Lightsail, a "blueprint" is a pre-made configuration template for different types of instances or applications. Blueprints make it super easy to set up instances with specific software stacks, like a LAMP (Linux, Apache, MySQL, PHP) stack or a WordPress content management system.

| Name                     | Blueprint ID      |
|-------------------------- |-------------------|
| Amazon Linux 2023        | amazon_linux_2023 |
| Amazon Linux 2           | amazon_linux_2    |
| Ubuntu                   | ubuntu_22_04      |
| Ubuntu                   | ubuntu_20_04      |
| Ubuntu                   | ubuntu_18_04      |
| Debian                   | debian_11         |
| Debian                   | debian_10         |
| FreeBSD                  | freebsd_12        |
| openSUSE Leap            | opensuse_15       |
| CentOS Stream 9          | centos_stream_9   |
| CentOS Linux             | centos_7_2009_01  |
| WordPress                | wordpress         |
| WordPress Multisite      | wordpress_multisite |
| LAMP (PHP 8)             | lamp_8_bitnami    |
| Node.js                  | nodejs            |
| Joomla                   | joomla            |
| Magento                  | magento           |
| MEAN                     | mean              |
| Drupal                   | drupal            |
| GitLab CE                | gitlab            |
| Redmine                  | redmine           |
| Nginx                    | nginx             |
| Ghost                    | ghost_bitnami     |
| Django                   | django_bitnami    |
| PrestaShop               | prestashop_bitnami |
| Plesk Hosting Stack on Ubuntu | plesk_ubuntu |
| cPanel & WHM for AlmaLinux | cpanel_whm_almalinux |


- **Bundle ID**: A "bundle" in Amazon Lightsail refers to a set of hardware resources such as CPU, RAM, and storage allocated to a Lightsail instance. Different bundles offer varying levels of performance and capacity.

| Name     | Instance Type | CPU Count | RAM Size (GB) | Disk Size (GB) | Price (Monthly) | Bundle ID    |
| -------- | ------------- | --------- | ------------- | --------------- | --------------- | -----------  |
| Nano     | nano          | 2         | 0.5           | 20              | $3.5            | nano_3_0    |
| Micro    | micro         | 2         | 1.0           | 40              | $5.0            | micro_3_0   |
| Small    | small         | 2         | 2.0           | 60              | $10.0           | small_3_0   |
| Medium   | medium        | 2         | 4.0           | 80              | $20.0           | medium_3_0  |
| Large    | large         | 2         | 8.0           | 160             | $40.0           | large_3_0   |
| Xlarge   | xlarge        | 4         | 16.0          | 320             | $80.0           | xlarge_3_0  |
| 2Xlarge  | 2xlarge       | 8         | 32.0          | 640             | $160.0          | 2xlarge_3_0 |


## Configure Lightsail with AWS CLI <a name="step2"/>
AWS CLI (Amazon Web Services Command Line Interface) is a command-line tool from Amazon Web Services that helps you manage and interact with AWS resources and services right from your local terminal or command prompt. It's built to simplify tasks for developers, administrators, and AWS users, making it easy to automate, script, and manage your AWS infrastructure without diving into the AWS Management Console (that web-based thing).

This is step by step on how to configure our web-based code editor with AWS CLI :
- Define our user data script into `user-data.sh` file. User data script, often referred to as a "user data" or "user script," is a script or set of commands that can be executed when launching a virtual machine (VM) or an instance in a cloud computing environment.
```sh
#!/bin/bash
export CODE_DOMAIN_NAME="\$(curl -s https://api.ipify.org).nip.io"
export CODE_PASSWORD="MyVeryLongPassword123"
curl -s -L https://raw.githubusercontent.com/rioastamal/installer-vscode-for-web/main/install.sh | bash -s -- --core
``` 
> You can define your own `CODE_PASSWORD` value above. It is the password that you are going to use to access your web-base code editor.

- Decide on the parameters that we will use to create our Lightsail instance, including `availability-zone`, `bundle-id`, and `blueprint-id`, using the information from the tables above.

|Parameters|Value|
|----------|-----|
|instance-names|code-server|
|availability-zone|ap-southeast-1a|
|bundle-id|small_3_0|
|blueprint-id|amazon_linux_2023|

- Run the following command with your chosen parameters and the `user-data.sh` file:
```sh
aws lightsail create-instances \
    --instance-names "code-server" \
    --availability-zone "ap-southeast-1a" \
    --blueprint-id "amazon_linux_2023" \
    --bundle-id "small_3_0" \
    --user-data file://user-data.sh
```
- To enable HTTPS for your web-based code editor, you need to open port 443 on your Lightsail instance using the following command:
```sh
aws lightsail open-instance-public-ports \
    --port-info fromPort=443,toPort=443,protocol=TCP \
    --instance-name "code-server"
```
- Retrieve your Lightsail `public IP` address using the following command and store it in a variable:
```sh
public_ip=$(aws lightsail get-instance --instance-name "code-server" --query 'instance.publicIpAddress' --output text)
```
- Display your web-based code editor URL with the `https://` prefix and `.nip.io` suffix:
```sh
echo "Here is your Code Server URL: https://$public_ip.nip.io"
```
- You will receive an output like this, which you can use to access your web-based code editor:
```sh
Here is your Code Server URL: https://13.212.142.172.nip.io
```
You can access your web-based code editor using the URL above (in several minutes) with `MyVeryLongPassword123` password (if you didn't define your own `CODE_PASSWORD` in the `user-data.sh` above) 

> To delete your Lightsail instance you can run following command.
```sh
aws lightsail delete-instance --instance-name "code-server"
```

## Configure Lightsail with AWS CDK <a name="step3"/>
AWS CDK (Cloud Development Kit) is a nifty open-source software development framework offered by Amazon Web Services (AWS). It simplifies the process of defining, deploying, and managing AWS infrastructure and resources using familiar programming languages like TypeScript, Python, Java, C#, and others. With AWS CDK, developers can define cloud resources and infrastructure as code in their chosen programming language. It then magically turns this code into AWS CloudFormation templates for deployment.

This is step by step on how to configure our web-based code editor with AWS CDK:
- Create your CDK project directory.
```sh
mkdir code-server && cd code-server
```
- Initialized CDK project.
```sh
cdk init app --language javascript
```
- CDK will start creating your project.
```sh
Applying project template app for javascript
# Welcome to your CDK JavaScript project

This is a blank project for CDK development with JavaScript.

The `cdk.json` file tells the CDK Toolkit how to execute your app. The build step is not required when using JavaScript.

## Useful commands

* `npm run test`         perform the jest unit tests
* `cdk deploy`           deploy this stack to your default AWS account/region
* `cdk diff`             compare deployed stack with current state
* `cdk synth`            emits the synthesized CloudFormation template

Initializing a new git repository...
warning: in the working copy of '.gitignore', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of '.npmignore', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'README.md', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'bin/code-server.js', LF will be replaced by CRLF the next time Git touches it
```
- After your project is ready, you can go to `lib/code-server-stack.js` and start creating your stack.
- Import `aws_lightsail` and `CfnOutput` module
```js
const { Stack, CfnOutput } = require("aws-cdk-lib");
const aws_lightsail = require("aws-cdk-lib/aws-lightsail");
```
- Define our `user-data` in a variable
```js
const userData = `
          #!/bin/bash
          export CODE_DOMAIN_NAME="\$(curl -s https://api.ipify.org).nip.io"
          export CODE_PASSWORD="MyVeryLongPassword123"
          curl -s -L https://raw.githubusercontent.com/rioastamal/installer-vscode-for-web/main/install.sh | bash -s -- --core`;
```
> You can define your own `CODE_PASSWORD` value above. It is the password that you are going to use to access your web-base code editor.

- Decide on the parameters that we will use to create our Lightsail instance, including `availability-zone`, `bundle-id`, and `blueprint-id`, using the information from the tables above.

|Parameters|Value|
|----------|-----|
|instanceName|code-server|
|availabilityZone|ap-southeast-1a|
|bundleId|small_3_0|
|blueprintId|amazon_linux_2023|
- Inside our `constructor` create Lightsail Instance using `CfnInstance` L1 construct.
```js
const code_server_instance = new aws_lightsail.CfnInstance(
      this,
      "CodeServerInstance",
      {
        instanceName: "code-server",
        blueprintId: "amazon_linux_2023",
        bundleId: "small_3_0",
        userData: userData,
        availabilityZone: "ap-southeast-1a",
        networking: {
          ports: [
            {
              protocol: "tcp",
              fromPort: 80,
              toPort: 80,
            },
            {
              protocol: "tcp",
              fromPort: 443,
              toPort: 443,
            },
          ],
        },
      }
    );
```
- Display your web-based code editor URL with the `https://` prefix and `.nip.io` suffix:
```js
 new CfnOutput(this, "CodeServerInstancePublicIp", {
      description: "Here is your Code Server URL:",
      value: `https://${code_server_instance.attrPublicIpAddress}.nip.io`,
    });
```
> The complete stack code will look like this
```js
const { Stack, CfnOutput } = require("aws-cdk-lib");
const aws_lightsail = require("aws-cdk-lib/aws-lightsail");

class CodeServerStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    const userData = `
          #!/bin/bash
          export CODE_DOMAIN_NAME="\$(curl -s https://api.ipify.org).nip.io"
          export CODE_PASSWORD="MyVeryLongPassword123"
          curl -s -L https://raw.githubusercontent.com/rioastamal/installer-vscode-for-web/main/install.sh | bash -s -- --core`;

    const code_server_instance = new aws_lightsail.CfnInstance(
      this,
      "CodeServerInstance",
      {
        instanceName: "code-server",
        blueprintId: "amazon_linux_2023",
        bundleId: "small_3_0",
        userData: userData,
        availabilityZone: "ap-southeast-1a",
        networking: {
          ports: [
            {
              protocol: "tcp",
              fromPort: 80,
              toPort: 80,
            },
            {
              protocol: "tcp",
              fromPort: 443,
              toPort: 443,
            },
          ],
        },
      }
    );

    new CfnOutput(this, "CodeServerInstancePublicIp", {
      description: "Here is your Code Server URL:",
      value: `https://${code_server_instance.attrPublicIpAddress}.nip.io`,
    });
  }
}

module.exports = { CodeServerStack };
```
- Deploy your CDK stack using this command in your terminal.
```sh
cdk deploy
```
- CDK will start `synth` and create `changeset`.
```sh
  Synthesis time: 0.51s

CodeServerStack:  start: Building 3d55542ca41bb6bafa251e4852dc0edd7b9609b642fc773fc3115d91600140f1:current_account-current_region
CodeServerStack:  success: Built 3d55542ca41bb6bafa251e4852dc0edd7b9609b642fc773fc3115d91600140f1:current_account-current_region
CodeServerStack:  start: Publishing 3d55542ca41bb6bafa251e4852dc0edd7b9609b642fc773fc3115d91600140f1:current_account-current_region
CodeServerStack:  success: Published 3d55542ca41bb6bafa251e4852dc0edd7b9609b642fc773fc3115d91600140f1:current_account-current_region
CodeServerStack: deploying... [1/1]
CodeServerStack: creating CloudFormation changeset...
CodeServerStack | 0/3 | 1:14:59 AM | REVIEW_IN_PROGRESS   | AWS::CloudFormation::Stack | CodeServerStack User Initiated
CodeServerStack | 0/3 | 1:15:05 AM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | CodeServerStack User Initiated
CodeServerStack | 0/3 | 1:15:08 AM | CREATE_IN_PROGRESS   | AWS::Lightsail::Instance | CodeServerInstance 
CodeServerStack | 0/3 | 1:15:08 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata       | CDKMetadata/Default (CDKMetadata) 
CodeServerStack | 0/3 | 1:15:09 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata       | CDKMetadata/Default (CDKMetadata) Resource creation Initiated
CodeServerStack | 1/3 | 1:15:09 AM | CREATE_COMPLETE      | AWS::CDK::Metadata       | CDKMetadata/Default (CDKMetadata) 
CodeServerStack | 1/3 | 1:15:12 AM | CREATE_IN_PROGRESS   | AWS::Lightsail::Instance | CodeServerInstance Resource creation Initiated
CodeServerStack | 2/3 | 1:15:29 AM | CREATE_COMPLETE      | AWS::Lightsail::Instance | CodeServerInstance
CodeServerStack | 3/3 | 1:15:31 AM | CREATE_COMPLETE      | AWS::CloudFormation::Stack | CodeServerStack

 ✅  CodeServerStack

✨  Deployment time: 37.54s
```
- You will receive an output like this, which you can use to access your web-based code editor:
```sh
Outputs:
CodeServerStack.CodeServerInstancePublicIp = https://13.229.52.187.nip.io
Stack ARN:
arn:aws:cloudformation:ap-southeast-1:319450934564:stack/CodeServerStack/122214b0-7687-11ee-94cb-0a2ad276ae8c

✨  Total time: 38.04s
```
You can access your web-based code editor using the URL above (in several minutes) with `MyVeryLongPassword123` password (if you didn't define your own `CODE_PASSWORD` in the `user-data.sh` above) 

> To delete your Lightsail instance you can run following command.
```sh
cdk destroy
```


## Conclusions <a name="step4"/>
In conclusion, we've explored just how straightforward it is to accomplish our goal of creating a web-based code editor on our Amazon Lightsail instance. Either with AWS CLI or AWS CDK. With the power of AWS dev tools at our fingertips, developers can streamline their workflows and boost productivity, all while enjoying the flexibility of choice in their development tools.

## Check out my previous post

{% embed https://dev.to/aws-builders/unlocking-the-power-of-nosql-building-a-todo-api-with-hapijs-and-dynamodb-1f7n %}