Files
Notebook/content/documentation/devpod/_index.en.md
Damien 8e9caef392 Fix missing images on English pages
Hugo only auto-shares page-bundle resources across translations when
each language has its own content directory; with filename-based
translation (index.fr.md / index.en.md in the same folder) a resource
with no language code is assigned to the default language only. Add
.en.-suffixed copies of every image referenced from English pages and
point the English markdown at them.
2026-07-18 10:05:47 +02:00

318 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "DevPod on AWS"
date: 2025-02-11T20:00:00+02:00
weight: 1
cascade:
type: docs
---
## Sources
- [DevPod](https://devpod.sh/docs/what-is-devpod) ⚙️
- [DevContainer](https://containers.dev) 🐳
## Introduction 🚀
In this article, I want to introduce a fantastic tool that belongs to the same family as GitPod and Codespaces: **DevPod**! It lets you create development environments effortlessly — without getting locked in to a single provider. 🔒❌
DevPod is based on the **DevContainer** architecture and uses the specifications contained in a [devcontainer.json](https://containers.dev) file to launch your development environment. Personally, I use it to quickly deploy network mockups with ContainerLab. 💻🧰
## What is a DevContainer? 🤔
A development container (often called a "dev container") lets you use a container as a full-fledged development environment. (Check out the official [containers.dev](https://containers.dev) documentation for more details.)
Let's break it down:
Have you ever heard the phrase "It works on my machine"? If you're a developer, you've probably run into this problem when collaborating with others. But guess what? **DevContainers** solve the problem of environment drift by providing consistent, reproducible Docker environments. Say goodbye to installation headaches! 💆‍♀️
With DevContainers, all you need is:
1. A `.devcontainer` folder in your project.
2. A `devcontainer.json` file that tells VS Code how to configure the container.
3. Docker installed locally
The cornerstone of the DevContainer is the `devcontainer.json` file. For example:
```json
{
"name": "Python DevContainer",
"image": "mcr.microsoft.com/devcontainers/python:3.10",
"features": {
"docker-in-docker": "latest"
},
"extensions": [
"ms-python.python",
"ms-azuretools.vscode-docker"
]
}
```
**What's happening here?** 🕵️‍♀️
- **"image"** This uses a ready-to-use Python 3.10 environment.
- **"features"** This adds Docker support inside the container.
- **"extensions"** Installs useful extensions for Python and Docker in VS Code.
DevContainers are great for local development, but sometimes you need more power — maybe your workloads are huge, or you want to run specialized labs. That's where **DevPod** comes in. 💪
**So you can easily deploy labs to the Cloud**
## What is DevPod? 🤖
**DevPod** is an open-source tool that lets you launch development environments either on your local machine or in the cloud provider of your choice. Think of it as a self-hosted, highly customizable version of GitHub Codespaces. 🎉
In my day-to-day networking adventures, I deploy ContainerLab-based setups with DevContainers on AWS. Let's see how you can use DevPod to do exactly that (details on ContainerLab will follow in another article, I promise!). 😜
## AWS Provider 🌐
DevPod uses **Providers**, which are configuration modules that define where and how DevPod launches your environment. Here's the list of providers:
![Provider_list](provider.en.png#center)
We're going to focus on the **AWS Provider** — even though there are plenty of configuration options:
![Provider_list](aws_options.en.png#center)
Before you panic at all these settings, don't worry. If you're just doing a bit of experimenting, the default values will usually do the job. 🙌
> [!NOTE] **The perks of open source** 🎁
>
> The fact that DevPod is open-source means you can peek under the hood to see exactly how it works. Check out the AWS code [here](https://github.com/loft-sh/devpod-provider-aws/tree/main) if you're curious.
## How the AWS code works
Let's look at what DevPod does on AWS by examining the [aws.go code](https://github.com/loft-sh/devpod-provider-aws/blob/main/pkg/aws/aws.go). At a high level, it handles:
1. **Initialization**: Reading the configuration and setting up the AWS SDK clients (with custom credentials if needed).
2. **Networking**: Finding or creating the appropriate subnet, VPC, and security groups.
3. **AMI selection**: Choosing a suitable AMI (by default, a recent Ubuntu 22.04 image) and determining the root device.
4. **IAM setup**: Verifying that an appropriate instance role and instance profile exist, along with the associated policies.
5. **Instance lifecycle**: Creating, starting, stopping, checking the status of, and deleting instances.
6. **User data injection**: Generating a script (Base64-encoded) that configures the instance (adds users and SSH keys) on first boot.
7. **Optional DNS**: Managing Route 53 records for the instance if the configuration requires it.
From my perspective, two points stand out as potentially the most critical:
- **(#4) IAM setup**
- **(#6) User data injection**
### Why are points #4 and #6 "tricky"?
- **IAM setup** is mainly handled by the `CreateDevpodInstanceProfile` function. It creates a role named `devpod-ec2-role` that can perform the following operations:
- **EC2 operations**: For example, it can describe or stop instances — in particular, the instance associated with it.
- **SSM operations**: By attaching the AmazonSSMManagedInstanceCore policy, the instance can be managed by AWS Systems Manager.
- **KMS operations (optional)**: If configured, it can run `kms:Decrypt` on a specific KMS key, which is useful for managing session data or secrets.
- **User data injection** is essentially a startup script inserted into the instance as Base64. This script sets up a `devpod` user with sudo rights, creates the SSH folders, and inserts your public key into the appropriate file. In the code, [it looks like this](https://github.com/loft-sh/devpod-provider-aws/blob/9d2730c34ecee40cb42596c602381b92ad9c6682/pkg/aws/aws.go#L967-L980):
```bash
useradd devpod -d /home/devpod
mkdir -p /home/devpod
if grep -q sudo /etc/groups; then
usermod -aG sudo devpod
elif grep -q wheel /etc/groups; then
usermod -aG wheel devpod
fi
echo "devpod ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/91-devpod
mkdir -p /home/devpod/.ssh
echo " + string(publicKey) + " >> /home/devpod/.ssh/authorized_keys
chmod 0700 /home/devpod/.ssh
chmod 0600 /home/devpod/.ssh/authorized_keys
chown -R devpod:devpod /home/devpod
```
Since DevPod is open-source, you can easily check it out for yourself. It's a great learning tool if you want to understand all the inner workings! 🔩
## IAM roles and policies
You'll need to create an IAM user and attach an IAM policy to it that grants just enough permissions for DevPod. For example:
- **EC2 actions:**
- Description: `ec2:DescribeSubnets`, `ec2:DescribeVpcs`, `ec2:DescribeImages`, `ec2:DescribeInstances`, `ec2:DescribeSecurityGroups`
- Instance management: `ec2:RunInstances`, `ec2:StartInstances`, `ec2:StopInstances`, `ec2:TerminateInstances`, `ec2:CancelSpotInstanceRequests`
- Security groups & tags: `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTags`
- **IAM actions:**
- `iam:GetInstanceProfile`, `iam:CreateRole`, `iam:PutRolePolicy`, `iam:AttachRolePolicy`, `iam:CreateInstanceProfile`, `iam:AddRoleToInstanceProfile`
- **Route 53 (optional):**
- `route53:ListHostedZones`, `route53:GetHostedZone`, `route53:ChangeResourceRecordSets`
## AWS Configuration 🏗️
I usually use the AWS web console to set this up, but you can absolutely do it via the CLI too.
### Step 1: Log in to the AWS console
1. Go to the [AWS Management Console](https://aws.amazon.com/console/).
2. Use an account with the appropriate rights to create IAM resources.
### Step 2: Create a custom IAM policy
#### **A. Go to the IAM console**
- In the AWS menu, find **IAM**.
#### **B. Create a new policy**
1. Click **Policies** in the left-hand menu.
2. Click **Create policy**.
#### **C. Switch to the JSON tab**
- Paste something like this, adjusting as needed:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2Actions",
"Effect": "Allow",
"Action": [
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeSecurityGroups",
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:CancelSpotInstanceRequests",
"ec2:CreateSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
},
{
"Sid": "IAMActions",
"Effect": "Allow",
"Action": [
"iam:GetInstanceProfile",
"iam:CreateRole",
"iam:PutRolePolicy",
"iam:AttachRolePolicy",
"iam:CreateInstanceProfile",
"iam:AddRoleToInstanceProfile"
],
"Resource": "*"
},
{
"Sid": "Route53Actions",
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:GetHostedZone",
"route53:ChangeResourceRecordSets"
],
"Resource": "*"
}
]
}
```
- Click **Next** (tags are optional), then **Next: Review**.
#### **D. Review and create**
1. Name it `DevpodToolPolicy` (or whatever you prefer).
2. Add an optional description.
3. Click **Create policy**.
### Step 3: Create or update the IAM user
#### **A. Create a new user (if needed)**
1. Click **Users** in IAM.
2. Click **Add user**.
3. Give it a name (e.g., `devpod-tool-user`).
4. Choose **Programmatic access** if you want CLI access. 🤖
5. Click **Next**.
#### **B. Attach your new policy**
1. On the permissions page, choose **Attach policies directly**.
2. Check `DevpodToolPolicy`.
3. Click **Create**.
4. And there you go!
### Step 4: Verify and you're done
Go back to **Users** → **devpod-tool-user** → **Permissions** to confirm that `DevpodToolPolicy` is indeed attached. ✅
### Step 5: Use these credentials
- If you created a programmatic user, make sure to note down the **Access Key ID** and the **Secret Access Key**.
![devpod_user_sumup](devpod_user.en.png#center)
**Bonus**: Note your **VPC ID** (in the VPC section on AWS). You'll need it when configuring DevPod.
## Configuring DevPod 🛠️
### 1. Configure the AWS profile
```bash
aws configure --profile Devpod
```
When prompted for:
1. The Access Key ID
2. The Secret Access Key
3. The default region (e.g., `eu-west-1`)
4. The output format (I usually leave it blank)
### 2. Add the profile to DevPod
1. In DevPod, create a new provider and choose **AWS**.
2. Select the **AWS region** (e.g., `eu-west-1`).
3. Expand the AWS options.
4. **AWS disk size**: e.g., 40 GB to start.
5. **Instance type**: e.g., `t2.small`.
6. **AWS profile**: select `Devpod` (or whatever name you chose).
7. **AWS VPC ID**: add your VPC.
8. You can leave the rest as default.
Click **Add Provider**.
![added_new_provider](new_provider.en.png#center)
## Testing a deployment 🧪
### Deploy
Let's do a quick test using one of the pre-built Docker images:
1. Go to **Workspaces** in DevPod.
2. Click **Create Workspace**.
3. Choose your new **AWS** provider.
4. Choose your preferred IDE (VS Code, etc.).
5. On the right, select a quick-start example (e.g., Python). 🐍
6. Click **Create Workspace**.
![new_worspace](new_worskapce.en.png#center)
Wait a few moments, and your cloud-based environment will pop up in VS Code. 🎊
![vscode](vscode.en.png#center)
### Stop
When you're not using the environment, click **Stop** to shut down the EC2 instance. You'll only pay for storage — no compute time. Great for your wallet. 💰
![Stopped Instance](stopped_instance.en.png#center)
### Delete
Deleting the workspace removes all AWS resources associated with that environment, so you won't pay a dime. But you'll need to redeploy if you want to use it again. ♻️
![Delete Instance](delete_instance.en.png#center)
## Conclusion 💡
By combining **DevContainers** and **DevPod** on **AWS**, you can build flexible, self-managed development environments that scale with your needs — without being locked into vendor-specific platforms. Say goodbye to "It works on my machine!" issues and hello to frictionless coding. 🚀✨
Have fun! 🎉