Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 0 additions & 29 deletions examples/devcontainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,6 @@ devcontainers:
forwardPorts: [9000, 9001]
```

## Supported Fields

- ✅ `name` - Container display name
- ✅ `image` - Pre-built container image
- ✅ `build` - Build configuration (dockerfile, context, args)
- ✅ `workspaceFolder` - Working directory inside container
- ✅ `workspaceMount` - Primary workspace volume mount
- ✅ `mounts` - Additional volume mounts
- ✅ **`forwardPorts`** - Port forwarding (critical for dev workflows)
- ✅ **`portsAttributes`** - Port metadata (labels, protocols)
- ✅ `containerEnv` - Environment variables
- ✅ `runArgs` - Additional docker/podman arguments
- ✅ `remoteUser` - User to run as

## Unsupported Fields (Ignored)

- ❌ `features` - Use Dockerfile instead
- ❌ `customizations` - Use VS Code extension instead
- ❌ `postCreateCommand` / lifecycle scripts - Use Dockerfile ENTRYPOINT/CMD

## Port Forwarding Examples

### Simple Port Mapping
Expand Down Expand Up @@ -150,12 +130,3 @@ atmos devcontainer remove <name>
# Show configuration
atmos devcontainer config <name>
```

## Container Naming

Containers are named: `atmos-devcontainer-{name}-{instance}`

Examples:
- `atmos-devcontainer-default-default`
- `atmos-devcontainer-terraform-alice`
- `atmos-devcontainer-python-bob`
2 changes: 2 additions & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ exclude = [
"example\\.com",
"cpco\\.io",
"cloudposse\\.com.*utm_",
# Private GitHub org (not accessible to CI)
"github\\.com/cloudposse-corp",
"slack\\.cloudposse\\.com",
"wttr\\.in",
# GNU.org (rate limits and connection resets)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,8 @@ Make it even easier with shell aliases in your `atmos.yaml`:

```yaml
# atmos.yaml
cli:
aliases:
shell: "devcontainer shell geodesic"
aliases:
shell: "devcontainer shell geodesic"
```

Now you can just type:
Expand Down Expand Up @@ -221,42 +220,6 @@ devcontainer:

Each project gets the right tool versions automatically.

## Real-World Workflows

### Onboarding a New Team Member

**Old way:**
1. Install Homebrew
2. Install Docker
3. Install Terraform (with tfenv or version manager)
4. Install kubectl
5. Install AWS CLI
6. Configure AWS credentials
7. Install Helm
8. Install Helmfile
9. Install jq, yq, and other tools
10. Debug version conflicts
11. Maybe productive by end of day?

**New way with Geodesic:**
```bash
brew install atmos
cd team-infrastructure
atmos devcontainer shell geodesic
# Productive in 2 minutes
```

### Working on Multiple Projects

**Old way:**
- Project A uses one set of tool versions
- Project B uses different tool versions
- Use version managers (tfenv, etc.) to switch constantly
- Hope you remember to switch before running commands

**New way with Geodesic:**
Each project defines its Geodesic version in `atmos.yaml`, and you automatically get the right tools when you launch the devcontainer for that project.

## Integration with Atmos Auth

Geodesic works seamlessly with Atmos's identity injection feature:
Expand Down
203 changes: 62 additions & 141 deletions website/blog/2025-12-05-native-devcontainer-support.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ tags: [feature]
date: 2025-12-05
release: v1.201.0
---
import EmbedExample from '@site/src/components/EmbedExample'
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

Running Atmos and managing cloud infrastructure inevitably means depending on dozens of tools—Terraform, kubectl, Helmfile, AWS CLI, and many more. But here's the problem every platform team faces: **"It works on my machine."**

Expand Down Expand Up @@ -106,33 +109,32 @@ Each instance is an independent container with its own state, perfect for runnin

## Configuration in atmos.yaml

Define devcontainers alongside your stack and component configuration:
Devcontainers are configured under the top-level `devcontainer` key in `atmos.yaml`. You can define them inline or import existing `devcontainer.json` files — both approaches are fully supported.

```yaml
# atmos.yaml
components:
devcontainer:
geodesic:
spec:
name: "Geodesic DevOps Toolbox"
image: "cloudposse/geodesic:latest"
workspaceFolder: "/workspace"
workspaceMount: "type=bind,source=${PWD},target=/workspace"
forwardPorts:
- 8080
containerEnv:
ATMOS_BASE_PATH: "/workspace"
remoteUser: "root"

terraform:
spec:
name: "Terraform Development"
image: "hashicorp/terraform:1.10"
workspaceFolder: "/workspace"
forwardPorts:
- 3000
mounts:
- "type=bind,source=${HOME}/.aws,target=/root/.aws,readonly"
devcontainer:
geodesic:
spec:
name: "Geodesic DevOps Toolbox"
image: "cloudposse/geodesic:latest"
workspaceFolder: "/workspace"
workspaceMount: "type=bind,source=${PWD},target=/workspace"
forwardPorts:
- 8080
containerEnv:
ATMOS_BASE_PATH: "/workspace"
remoteUser: "root"

terraform:
spec:
name: "Terraform Development"
image: "hashicorp/terraform:1.10"
workspaceFolder: "/workspace"
forwardPorts:
- 3000
mounts:
- "type=bind,source=${HOME}/.aws,target=/root/.aws,readonly"
```

### Use Existing devcontainer.json Files
Expand All @@ -141,24 +143,22 @@ Already have `.devcontainer/devcontainer.json` files? Atmos can use them directl

```yaml
# atmos.yaml
components:
devcontainer:
geodesic:
spec: !include .devcontainer/devcontainer.json
devcontainer:
geodesic:
spec: !include .devcontainer/devcontainer.json
```

Or include and override specific fields:

```yaml
# atmos.yaml
components:
devcontainer:
geodesic:
spec:
- !include .devcontainer/devcontainer.json
- containerEnv:
ATMOS_BASE_PATH: "/workspace"
CUSTOM_VAR: "value"
devcontainer:
geodesic:
spec:
- !include .devcontainer/devcontainer.json
- containerEnv:
ATMOS_BASE_PATH: "/workspace"
CUSTOM_VAR: "value"
```

This is the **real Atmos `!include` function**—the same powerful YAML processing you use everywhere else in Atmos. It supports deep merging, overrides, and all the template functions you know.
Expand Down Expand Up @@ -222,9 +222,8 @@ Make it even easier with shell aliases in your `atmos.yaml`:

```yaml
# atmos.yaml
cli:
aliases:
shell: "devcontainer shell"
aliases:
shell: "devcontainer shell"
```

Now you can just type:
Expand All @@ -237,9 +236,8 @@ atmos shell
If you have a default devcontainer you always use, you can hardcode it:

```yaml
cli:
aliases:
shell: "devcontainer shell geodesic"
aliases:
shell: "devcontainer shell geodesic"
```

## Additional Lifecycle Commands
Expand Down Expand Up @@ -289,11 +287,10 @@ Works with both Docker and Podman, with automatic runtime detection. No vendor l

```yaml
# Per-devcontainer runtime selection
components:
devcontainer:
geodesic:
settings:
runtime: docker # or podman, or omit for auto-detect
devcontainer:
geodesic:
settings:
runtime: docker # or podman, or omit for auto-detect
```

### 6. Identity Injection
Expand Down Expand Up @@ -333,16 +330,13 @@ Development containers are incredibly valuable across different domains:
- No conflicts between different project requirements
- Onboarding new team members in minutes instead of hours

### Data Engineering
- Jupyter notebooks with pre-installed libraries
- Data processing tools (Spark, Airflow, etc.)
- Database clients and connectors

Development containers are **equally valuable—if not more valuable—for DevOps** than traditional software development. Infrastructure teams juggle more tools, more versions, and more environmental complexity than most application developers.

## Comparison with Traditional Approaches

### Before: Manual Environment Setup
<Tabs>
<TabItem value="before" label="Before: Manual Environment Setup">

```bash
# Install Terraform
brew install terraform
Expand All @@ -367,27 +361,16 @@ brew install helmfile
# Repeat when you switch projects...
```

### After: Atmos Devcontainer
</TabItem>
<TabItem value="after" label="After: Atmos Devcontainer">

```bash
atmos devcontainer shell geodesic
# Everything installed, versioned, ready to use
```

### Comparison with Official devcontainer CLI

| Feature | Official CLI | Atmos Native |
|---------|-------------|--------------|
| Installation | Separate tool | Built-in |
| Primary command | `devcontainer up` | `atmos devcontainer shell` |
| Multiple instances | No | Yes |
| Interactive selection | No | Yes |
| Shell autocomplete | Limited | Full support |
| Named configs | File-based only | Named in atmos.yaml |
| Identity injection | Manual | Coming soon |
| Rich TUI | Basic | Charm ecosystem |
| Runtime choice | Docker only | Docker or Podman |
| `!include` support | No | Yes (native Atmos) |
| Atmos integration | External | Native |
</TabItem>
</Tabs>

## Practical Subset of the Spec

Expand All @@ -410,58 +393,6 @@ Atmos implements a **practical subset** of the [Development Containers specifica

This approach keeps the implementation lean, maintainable, and focused on solving the actual problem: **reproducible development environments for infrastructure teams**.

## Real-World Workflows

### Onboarding a New Team Member

**Old way:**
1. Install Homebrew
2. Install Docker
3. Install Terraform (with tfenv or version manager)
4. Install kubectl
5. Install AWS CLI
6. Configure AWS credentials
7. Install Helm
8. Install Helmfile
9. Install jq, yq, and other tools
10. Debug version conflicts
11. Maybe productive by end of day?

**New way:**
```bash
brew install atmos
cd team-infrastructure
atmos devcontainer shell
# Productive in 2 minutes
```

### Working on Multiple Projects

**Old way:**
- Project A uses one set of tool versions
- Project B uses different tool versions
- Use version managers (tfenv, etc.) to switch constantly
- Hope you remember to switch before running commands

**New way:**
```yaml
# project-a/atmos.yaml
components:
devcontainer:
toolbox:
spec:
image: "cloudposse/geodesic:4.3.0" # Pinned toolbox version

# project-b/atmos.yaml
components:
devcontainer:
toolbox:
spec:
image: "cloudposse/geodesic:4.4.0" # Different toolbox version
```

Each project gets the right tool versions automatically.

## Get Started Now

### 1. Upgrade Atmos
Expand All @@ -473,31 +404,21 @@ brew upgrade atmos

### 2. Check Out the Examples

```bash
# Browse or clone the examples
https://github.com/cloudposse/atmos/tree/main/examples/devcontainer

# Or try it locally
git clone https://github.com/cloudposse/atmos.git
cd atmos/examples/devcontainer
atmos devcontainer shell geodesic
```
<EmbedExample example="devcontainer" title="Devcontainer Example" />

### 3. Add to Your Project

```yaml
# atmos.yaml
components:
devcontainer:
geodesic:
spec:
image: "cloudposse/geodesic:latest"
workspaceFolder: "/workspace"
workspaceMount: "type=bind,source=${PWD},target=/workspace"

cli:
aliases:
shell: "devcontainer shell geodesic"
devcontainer:
geodesic:
spec:
image: "cloudposse/geodesic:latest"
workspaceFolder: "/workspace"
workspaceMount: "type=bind,source=${PWD},target=/workspace"

aliases:
shell: "devcontainer shell geodesic"
```

### 4. Launch Your Environment
Expand Down
Loading
Loading