coiai Logo

This article is an English translation of the original Japanese post. Read the Japanese original →

[WSL Basics] Setting Up a Full Dev Toolchain on Ubuntu on WSL2 — Git / nvm / pnpm / AWS CLI / Terraform

July 28, 2026

Categories: 未分類

In the previous post, we got WSL2 installed on Windows and Ubuntu up and running.
But a fresh Ubuntu install is really just a blank Linux box. Before you can actually start developing, you need to install the tools for version control, runtimes, and cloud operations yourself.

In this article, we'll set up the following tools in order, using only the steps published in each tool's official documentation.

  1. Base tooling (build environment and network utilities)
  2. Git (plus Git Credential Manager, which shares credentials with the Windows side)
  3. nvm → Node.js
  4. pnpm
  5. AWS CLI v2
  6. Terraform

Each section ends with a link to the source documentation, so if a step ever feels out of date, check there. There's also a full list of sources at the end of the article.

Environment tested
Windows 11 / WSL2 / Ubuntu 24.04 LTS (x86_64)
Verified: July 28, 2026

Version numbers reflect the time of writing. The install commands themselves are generally of the "always fetch the latest" variety, so you can run them as-is without worry.


Before We Start: The Golden Rule of WSL Development

One thing before we get to the commands. There's an important principle that Microsoft's official documentation repeats over and over.

Store your files on the same OS side as the tools you plan to use.
If you're working with Linux tools from a Linux command line, keep your files in the WSL file system for the best performance.

Concretely, put your projects here:

Anything under /mnt/c/ crosses the file system boundary, which makes commands like npm install and git status noticeably slower. All the tools we're about to install in this second installment assume you're working out of your Linux-side home directory.

Source: Set up a WSL development environment — Microsoft Learn


1. Base Tooling First

Once Ubuntu is running, the first thing to do is update your packages. Microsoft's official documentation says as much:

We recommend that you regularly update and upgrade your packages using your distribution's preferred package manager.
Windows does not automatically update or upgrade your Linux distributions.

sudo apt update && sudo apt upgrade

apt update refreshes the package lists, and apt upgrade performs the actual upgrades. WSL won't update itself, so it's worth making this a monthly habit.

Next, let's install all the tools we'll need later in this article in one go.

sudo apt install -y \
  build-essential \
  curl \
  wget \
  unzip \
  ca-certificates \
  gnupg \
  software-properties-common

Here's what each package is for:

HashiCorp's official tutorial includes this same step as a prerequisite before installing Terraform:

sudo apt-get update && sudo apt-get install -y gnupg software-properties-common

Sources:


2. Git

2-1. Install Git on Both Windows and WSL

First, an important premise to understand. Microsoft's official documentation puts it this way:

You will need to install Git on each file system that you intend to use it with.

WSL has its own file system, separate from Windows. That means Git on the Windows side and Git on the WSL side are entirely separate installations, each with its own version and its own config files. In this article we'll install the WSL side, but installing Git for Windows on the Windows side is also recommended (the reason comes up in the Credential Manager section below).

2-2. Installation

Ubuntu usually ships with Git preinstalled, but it's often an older version. The official Git site recommends the PPA as the way to get the latest stable release on Ubuntu/Debian.

sudo add-apt-repository ppa:git-core/ppa
sudo apt update
sudo apt install git

ppa:git-core/ppa is the official PPA maintained by the Git maintainers, and it provides newer versions than Ubuntu's standard repositories.

If you're not picky about the version, the standard repository is fine too.

sudo apt install git

Verify:

git --version

2-3. Setting Your User Info

Set the name and email address that will be stamped on your commits.

git config --global user.name "Your Name"
git config --global user.email "youremail@domain.com"

If you'd rather edit the config file directly, open it with nano ~/.gitconfig.

2-4. Sharing Credentials with Windows via Git Credential Manager

This is where WSL gets genuinely convenient.

Git Credential Manager (GCM) is a .NET-based credential helper that supports multi-factor authentication for GitHub, Azure DevOps, and Bitbucket. It stores your authentication tokens securely in the Windows Credential Manager, so once you've authenticated, you can push and pull without ever re-authenticating.

To use it with WSL, you need Windows 10 version 1903 or later (GCM uses wsl.exe to interoperate with Git on the WSL side).

The recommended approach is to install Git for Windows on the Windows side. GCM ships bundled with Git for Windows, so all you have to do is choose "use GCM as the default credential helper" during installation.

Once Git for Windows is installed, check that GCM is visible from the WSL side.

git-credential-manager.exe --version
2.7.3+5fa7116896c82164996a609accd1c5ad90fe730a

If it returns a version like this, you're good.

⚠️ There's one trap in Microsoft's official documentation here.
The docs give git --version; git credential-manager --version as the verification command, but running that on the WSL side fails.

$ git --version; git credential-manager --version
git version 2.54.0
git: 'credential-manager' is not a git command. See 'git --help'.

The git credential-manager syntax works by having Git search the PATH for an executable named git-credential-manager. But the actual binary visible from WSL is git-credential-manager.exe, and the Linux build of Git does not append the .exe extension for you. So Git can't find it and errors out.

This doesn't mean GCM isn't installed, so no need to panic. Run it with the explicit .exe as shown above and it will verify fine. You can also just check that the file exists directly.

ls -l "/mnt/c/Program Files/Git/mingw64/bin/git-credential-manager.exe"

Next, tell Git on the WSL side to delegate authentication to GCM (this is the procedure from the official GCM repository).

git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/bin/git-credential-manager.exe"

Note that the space in the path is escaped with \. To confirm the setting took effect, run:

git config --global credential.helper

From now on, every git operation you run inside WSL goes through GCM. If credentials are already cached on the Windows side, those get used; if not, a Windows dialog will pop up asking you to authenticate — even though you're working in a Linux console.

If you use Azure DevOps / Azure Repos, you'll need this additional setting:

git config --global credential.https://dev.azure.com.useHttpPath true

There are two caveats to be aware of.

  1. GCM does not read the WSL-side git config. Because GCM runs as a Windows application, it reads its configuration from %UserProfile%\.gitconfig on the Windows side. Settings like proxies need to be written in both places — the Windows side and the WSL side (\\wsl$\distro\home\$USER\.gitconfig).
  2. GCM only works with HTTP(S) remotes. If you want to work over SSH, skip GCM and set up your keys by following GitHub's SSH connection guide instead.

It's also possible to keep everything on the WSL side without installing Git for Windows, but in that case GCM runs as a Linux application, which means you lose access to Windows' authentication and credential storage features. The steps are in the relevant section of the official GCM documentation.

2-5. Line Endings (This Trips Up a Lot of People)

When you touch the same repository from both Windows and Linux, Git may suddenly report that a huge number of files have been modified. The contents are identical — only the line endings differ.

The fix is one of the following:

The details are covered in the VS Code troubleshooting documentation.

2-6. .gitignore

Every project should have a .gitignore. GitHub publishes a collection of templates organized by use case, so the quickest route is to copy one from there.

Sources:


3. nvm and Node.js

3-1. Why nvm?

You could install Node.js with apt install nodejs, but the version in Ubuntu's standard repositories is quite old, and you can't switch versions per project. With nvm (Node Version Manager), multiple versions of Node.js can coexist, and switching between them is a single command.

3-2. Installation

This is the install command from the official nvm repository (the latest at the time of writing is v0.40.6).

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash

If you prefer wget:

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash

⚠️ Note that the version number (v0.40.6) is embedded directly in the URL. A newer version may well have been released by the time you read this. To be safe, check the latest tag on nvm-sh/nvm Releases before running it, and swap in the current version.

The script automatically appends the following to your ~/.bashrc (if it doesn't get added properly, add it by hand):

export NVM_DIR="$( [ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

After that, close and reopen your terminal (or run source ~/.bashrc).

3-3. Verify

command -v nvm

If it prints nvm, you're all set.

⚠️ You can't verify it with which nvm. That's because nvm is loaded as a shell function, not an executable. The official README goes out of its way to call this out — it's a spot where plenty of people panic because "I installed it but which can't find it."

3-4. Installing Node.js

nvm install --lts     # 最新のLTSを入れる(本番用途はこれ)
nvm install 24        # メジャーバージョンを指定して入れる
nvm use 24            # 使うバージョンを切り替える
node -v               # 確認

As of July 2026, the Node.js release lineup looks like this:

When in doubt, nvm install --lts to get the Active LTS and you can't go wrong.

💡 If you create a file named .nvmrc in your project root containing the version (e.g. 24), a plain nvm use in that directory switches to it automatically. Quietly effective on team projects.

Sources:


4. pnpm

pnpm is an npm-compatible package manager. Its content-addressable store shares dependency packages on disk, which makes installs fast and keeps disk usage low.

The official pnpm docs describe three installation methods. Let's go through them in order.

Option A: Via Corepack (Officially Recommended)

corepack enable pnpm
corepack use pnpm@latest-11

The advantage of Corepack is that the package manager version gets recorded in package.json, so the whole team uses the same version. A good fit for projects where reproducibility matters.

⚠️ Corepack is no longer bundled with Node.js 25 and later.
On March 19, 2025, the Node.js TSC formally decided to stop distributing Corepack starting with v25. On Node.js 24 and earlier, it remains available as an experimental feature.

If you want to use Corepack on Node 25 or later, you'll need to install it separately:

npm install -g corepack

As long as you're on the Active LTS v24, it's still bundled, so for the time being corepack enable pnpm works as-is.

Option B: Via npm

If Node.js is already installed, this is the simplest route.

npm install -g pnpm@latest-11

Since it doesn't depend on whether Corepack is bundled, Option B is the most straightforward choice for the setup in this article (Node installed via nvm).

Option C: Standalone Script

This method works even without Node.js installed.

curl -fsSL https://get.pnpm.io/install.sh | sh -

The wget version:

wget -qO- https://get.pnpm.io/install.sh | sh -

To pin a specific version:

curl -fsSL https://get.pnpm.io/install.sh | env PNPM_VERSION=<version> sh -

Caveats and Verification

A few notes from the official documentation:

Verify:

pnpm --version

The latest at the time of writing is 11.17.0.

Sources:


5. AWS CLI v2

5-1. Installation (Quick Version)

These are the three copy-paste lines the official AWS documentation provides, for x86_64 (64-bit Intel/AMD):

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

On ARM machines (such as Snapdragon-based PCs), swap the URL:

curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

By default, the files land in /usr/local/aws-cli, with a symlink created in /usr/local/bin. The sudo is needed for write permission to those directories.

Verify:

aws --version
aws-cli/2.36.9 Python/3.13.4 Linux/5.15.167.4-microsoft-standard-WSL2 exe/x86_64.ubuntu.24

Output like this means you're good (the version and environment details will vary on your machine).

If the aws command isn't found, try restarting your terminal.

5-2. [Recommended] Verify the Signature Before Installing

AWS explicitly notes that "the quick steps above do not verify the integrity of the download." The zip is PGP-signed, so verifying it is the safer path.

Step 1: Install GPG (skip this if you installed it in the base tooling section)

sudo apt install gnupg

Step 2: Save the AWS CLI public key to a file

Save the following under a filename like aws-cli-key.asc.

-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBF2Cr7UBEADJZHcgusOJl7ENSyumXh85z0TRV0xJorM2B/JL0kHOyigQluUG
ZMLhENaG0bYatdrKP+3H91lvK050pXwnO/R7fB/FSTouki4ciIx5OuLlnJZIxSzx
(中略:全文は下記の公式ドキュメントからコピーしてください)
-----END PGP PUBLIC KEY BLOCK-----

The key details are as follows. Make sure they match what you have:

Key ID:           A6310ACC4672475C
Type:             RSA
Size:             4096/4096
Created:          2019-09-18
Expires:          2027-07-01
User ID:          AWS CLI Team <aws-cli@amazon.com>
Key fingerprint:  FB5D B77F D5C1 18B8 0511  ADA8 A631 0ACC 4672 475C

Step 3: Import the key

gpg --import aws-cli-key.asc

Step 4: Download the signature file

curl -o awscliv2.sig https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip.sig

Step 5: Verify

gpg --verify awscliv2.sig awscliv2.zip

If you see Good signature from "AWS CLI Team <aws-cli@amazon.com>", it worked.

You'll also see a warning that says WARNING: This key is not certified with a trusted signature! — this is expected and not a problem. It just means there's no chain of trust between your own PGP key and the AWS key. The official AWS documentation says exactly that.

Once the verification passes, extract and install:

unzip awscliv2.zip
sudo ./aws/install

5-3. How to Update

AWS CLI v2 does not update itself. To update, download a fresh installer and run it with the --update flag:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip -u awscliv2.zip
sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update

Using unzip -u (the update flag) skips the overwrite confirmation prompts.

If you've lost track of where your existing installation lives, these commands will tell you:

which aws                    # --bin-dir に渡すパス
ls -l /usr/local/bin/aws     # リンク先 = --install-dir に渡すパス

5-4. Side Note: The snap Option

If you're happy always running the latest version and don't need to pin one, snap is also officially supported.

sudo snap install aws-cli --classic

The upside of snap is automatic updates, but the official docs explain that it has no built-in support for selecting a minor version, so the command-line installer is a better fit if your team needs to pin versions.

Note also that the AWS documentation warns: "Because AWS doesn't maintain third-party repositories other than snap, there's no guarantee they contain the latest version." It's safest to steer clear of apt install awscli.

Source: Installing or updating to the latest version of the AWS CLI — AWS documentation


6. Terraform

HashiCorp provides an official apt repository for Terraform, so once you register it, future updates come through a plain apt upgrade.

6-1. Register the GPG Key

wget -O- https://apt.releases.hashicorp.com/gpg | \
  gpg --dearmor | \
  sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null

6-2. Verify the Key Fingerprint

The official tutorial includes this step.

gpg --no-default-keyring \
  --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
  --fingerprint

Check that the fingerprint in the output matches the one for the signing key HashiCorp publishes officially.

6-3. Add the Repository

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/hashicorp.list

It's a long command, but what it does is simple:

6-4. Installation

sudo apt update
sudo apt-get install terraform

Verify:

terraform -version

The latest stable at the time of writing is v1.15.8 (released July 8, 2026).

6-5. Enable Tab Completion

This one genuinely changes the day-to-day experience.

terraform -install-autocomplete

After running it and restarting your shell, typing terraform pl and hitting Tab completes to terraform plan.

Sources:


7. Final Check

Let's verify everything in one pass.

git --version
node -v
npm -v
pnpm --version
aws --version
terraform -version

For reference, here are the versions as of the time of writing (July 28, 2026):

ToolVersion at time of writingInstall method
Git2.5x series (latest stable from the PPA)ppa:git-core/ppa
nvmv0.40.6install.sh
Node.jsv24 (Active LTS)nvm install --lts
pnpm11.17.0npm or Corepack
AWS CLI2.36.9Official installer (zip)
Terraform1.15.8HashiCorp apt repository

Gotchas Recap

To wrap up, here's a final rundown of every pitfall we hit in this second installment.

1. Don't put projects under /mnt/c/
Crossing the file system boundary is measurably slow. Keep projects under ~/.

2. The Windows side and the WSL side are separate environments
Git needs to be installed on both, and git config is stored separately for each. "I set it on Windows but it doesn't apply in WSL" is by design.

3. which nvm doesn't work
nvm is a shell function, so verify it with command -v nvm.

4. Corepack isn't bundled with Node.js 25 and later
If you manage pnpm through Corepack, things will break the moment you upgrade Node. Check your CI and Dockerfiles too.

5. The AWS CLI doesn't auto-update
You have to reinstall with the --update flag. It's easy to forget, so a recurring calendar reminder is a good idea.

6. Git line endings
Working across Windows and Linux produces mountains of spurious diffs. Declaring line endings in .gitattributes is the reliable fix.

7. git credential-manager --version doesn't work in WSL
It's the verification command listed in Microsoft's official docs, but the Linux build of Git doesn't append .exe, so you get is not a git command. Write it as git-credential-manager.exe --version and it works. It does not mean GCM is missing.


Closing Thoughts

And with that, your Ubuntu on WSL2 has a complete foundational dev kit. Managing code with Git, running frontends with Node.js and pnpm, and driving the cloud with the AWS CLI and Terraform — the groundwork is all in place.

Next time, I'd like to build on this environment and cover remote development with the VS Code WSL extension, and perhaps Docker integration.


Sources

All verified on July 28, 2026.

WSL / environment in general

Git

Node.js / nvm

pnpm

AWS CLI

Terraform