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.
- Base tooling (build environment and network utilities)
- Git (plus Git Credential Manager, which shares credentials with the Windows side)
- nvm → Node.js
- pnpm
- AWS CLI v2
- 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, 2026Version 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:
- ✅
\\wsl$\Ubuntu\home\<ユーザー名>\Project(the Linux side =~/Project) - ❌
C:\Users\<ユーザー名>\Project(=/mnt/c/Users/...as seen from WSL)
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:
- build-essential — gcc, make, and friends. Needed when building native Node.js modules
- curl / wget — Used to fetch install scripts. These show up in nearly every section below
- unzip — Required to extract the AWS CLI zip (AWS explicitly lists it as a prerequisite)
- ca-certificates / gnupg — Used for HTTPS communication and GPG signature verification. Needed when registering the Terraform repository
- software-properties-common — Provides the
add-apt-repositorycommand. Used to add the Git PPA
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 givegit --version; git credential-manager --versionas 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-managersyntax works by having Git search the PATH for an executable namedgit-credential-manager. But the actual binary visible from WSL isgit-credential-manager.exe, and the Linux build of Git does not append the.exeextension 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
.exeas 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.
- GCM does not read the WSL-side git config. Because GCM runs as a Windows application, it reads its configuration from
%UserProfile%\.gitconfigon 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). - 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:
- Add a
.gitattributesfile to the repository to declare line endings explicitly (recommended) - Disable line-ending conversion globally on the Windows side
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 butwhichcan'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:
- Active LTS: v24 (Krypton) ← this is the one recommended for production
- Maintenance LTS: v22 (Jod)
- Current: v26
When in doubt, nvm install --lts to get the Active LTS and you can't go wrong.
💡 If you create a file named
.nvmrcin your project root containing the version (e.g.24), a plainnvm usein 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 corepackAs long as you're on the Active LTS v24, it's still bundled, so for the time being
corepack enable pnpmworks 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:
- The minimum Node.js requirement is v22 (for pnpm 11.x). If you installed v24 LTS via nvm, you're fine
- On minimal Linux containers,
libatomic.so.1may need to be installed separately - The docs also mention that the standalone build doesn't work on Intel Macs, where you should use npm / Corepack / Homebrew instead (irrelevant on WSL, but worth knowing)
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
awscommand 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:
$(dpkg --print-architecture)— auto-detects the CPU architecturesigned-by=...— restricts signature verification to the key we just registered$(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs)— automatically picks up the Ubuntu codename (e.g.noble), falling back tolsb_release -csif it can't
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):
| Tool | Version at time of writing | Install method |
|---|---|---|
| Git | 2.5x series (latest stable from the PPA) | ppa:git-core/ppa |
| nvm | v0.40.6 | install.sh |
| Node.js | v24 (Active LTS) | nvm install --lts |
| pnpm | 11.17.0 | npm or Corepack |
| AWS CLI | 2.36.9 | Official installer (zip) |
| Terraform | 1.15.8 | HashiCorp 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
- Get started using Git on WSL — Microsoft Learn
- Git — Downloading Package (Linux)
- Git Credential Manager — WSL setup documentation
- GitHub's .gitignore template collection
Node.js / nvm
pnpm
- pnpm Installation — official documentation
- pnpm/pnpm Releases — GitHub
- Node.js TSC Votes to Stop Distributing Corepack — Socket
AWS CLI
- Installing or updating to the latest version of the AWS CLI — AWS documentation
- AWS CLI version 2 Changelog — GitHub
Terraform