WSL Tutorial¶
In this tutorial, we will customize a Windows Subsystem for Linux (WSL) instance using cloud-init on Ubuntu.
How to use this tutorial¶
In this tutorial, the commands in each code block can be copied and pasted
directly into a PowerShell
Window . Omit the prompt before each
command, or use the “copy code” button on the right-hand side of the block,
which will copy the command for you without the prompt.
Prerequisites¶
This tutorial assumes you are running within a Windows 11
or Windows
Server 2022
environment. If wsl
is already installed, you must be
running version 2. You can check your version of wsl
by running the
following command:
PS> wsl --version
Example output:
WSL version: 2.1.5.0
Kernel version: 5.15.146.1
WSLg version: 1.0.60
MSRDC version: 1.2.5105
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.20348.2402
If running this tutorial within a virtualized environment (including in the cloud), ensure that nested virtualization is enabled.
Install WSL¶
Note
If you have already installed WSL, you can skip this section.
PS> wsl --install
Example output:
Installing: Virtual Machine Platform
Virtual Machine Platform has been installed.
Installing: Windows Subsystem for Linux
Windows Subsystem for Linux has been installed.
Installing: Ubuntu
Ubuntu has been installed.
The requested operation is successful. Changes will not be effective until the system is rebooted.
Reboot the system when prompted.
Create our user data¶
User data is the primary way for a user to customize a cloud-init instance. Open Notepad and paste the following:
#cloud-config
write_files:
- content: |
Hello from cloud-init
path: /var/tmp/hello-world.txt
permissions: '0777'
Save the file to %USERPROFILE%\.cloud-init\Ubuntu-24.04.user-data
.
For example, if your username is me
, the path would be
C:\Users\me\.cloud-init\Ubuntu-24.04.user-data
.
Ensure that the file is saved with the .user-data
extension and
not as a .txt
file.
Note
We are creating user data that is tied to the instance we just created, but by changing the filename, we can create user data that applies to multiple or all WSL instances. See WSL Datasource reference page for more information.
What is user data?¶
Before moving forward, let’s inspect our user-data
file.
We created the following contents:
#cloud-config
write_files:
- content: |
Hello from cloud-init
path: /var/tmp/hello-world.txt
permissions: '0770'
The first line starts with #cloud-config
, which tells cloud-init
what type of user data is in the config. Cloud-config is a YAML-based
configuration type that tells cloud-init how to configure the instance
being created. Multiple different format types are supported by
cloud-init. For more information, see the
documentation describing different formats.
The remaining lines, as per
the Write Files module docs, creates a file
/var/tmp/hello-world.txt
with the content Hello from cloud-init
and
permissions allowing anybody on the system to read or write the file.
Obtain the Ubuntu WSL image¶
Ubuntu 24.04 is the first Ubuntu version to support cloud-init in WSL, so that is the image that we’ll use.
We have two options to obtain the Ubuntu 24.04 WSL image: the Microsoft Store and the Ubuntu image server.
Option #1: The Microsoft Store¶
If you have access to the Microsoft Store, you can download the Ubuntu 24.04 WSL image from within the app.
Click on the “Install” button to download the image. Then click “Open” to install the image.
Alternatively, you can use the following command to download and install the image:
PS> wsl --install --distribution Ubuntu-24.04
Option #2: The Ubuntu image server¶
If the Microsoft Store is not an option, we can instead download the Ubuntu 24.04 WSL image from the Ubuntu image server.
Create a directory under the user’s home directory to store the WSL image and install data.
PS> mkdir ~\wsl-images
Download the Ubuntu 24.04 WSL image.
PS> Invoke-WebRequest -Uri https://cloud-images.ubuntu.com/wsl/noble/current/ubuntu-noble-wsl-amd64-wsl.rootfs.tar.gz -OutFile wsl-images\ubuntu-noble-wsl-amd64-wsl.rootfs.tar.gz
Import the image into WSL storing it in the wsl-images
directory.
PS> wsl --import Ubuntu-24.04 wsl-images .\wsl-images\ubuntu-noble-wsl-amd64-wsl.rootfs.tar.gz
Example output:
Import in progress, this may take a few minutes.
The operation completed successfully.
Start the Ubuntu WSL instance
PS> wsl --distribution Ubuntu-24.04
Setup the Ubuntu WSL instance¶
The Ubuntu WSL instance will start, and you may be prompted for a username and password.
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username:
New password:
Retype new password:
Once the credentials have been entered, you should see a welcome screen similar to the following:
Welcome to Ubuntu Noble Numbat (GNU/Linux 5.15.146.1-microsoft-standard-WSL2 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Mon Apr 22 21:06:49 UTC 2024
System load: 0.08 Processes: 51
Usage of /: 0.1% of 1006.85GB Users logged in: 0
Memory usage: 4% IPv4 address for eth0: 172.29.240.255
Swap usage: 0%
This message is shown once a day. To disable it please create the
/root/.hushlogin file.
root@machine:/mnt/c/Users/me#
You should now be in a shell inside the WSL instance.
Verify that cloud-init
ran successfully¶
Before validating the user data, let’s wait for cloud-init
to complete
successfully:
$ cloud-init status --wait
Which provides the following output:
status: done
Now we can now see that cloud-init has detected that we running in WSL:
$ cloud-id
Which provides the following output:
wsl
Verify our user data¶
Now we know that cloud-init
has been successfully run, we can verify that
it received the expected user data we provided earlier:
$ cloud-init query userdata
Which should print the following to the terminal window:
#cloud-config
write_files:
- content: |
Hello from cloud-init
path: /var/tmp/hello-world.txt
permissions: '0770'
We can also assert the user data we provided is a valid cloud-config:
$ cloud-init schema --system --annotate
Which should print the following:
Valid schema user-data
Finally, let us verify that our user data was applied successfully:
$ cat /var/tmp/hello-world.txt
Which should then print:
Hello from cloud-init
We can see that cloud-init
has received and consumed our user data
successfully!
What’s next?¶
In this tutorial, we used the Write Files module to write a file to our WSL instance. The full list of modules available can be found in our modules documentation. Each module contains examples of how to use it.
You can also head over to the examples page for examples of more common use cases.
Cloud-init’s WSL reference documentation can be found on the WSL Datasource reference page.