A Cloud-based Gaming PC?
Having found myself without my main PC for a weekend, I wondered if it would be possible to create something similar to GeForce Now, but with a better selection. Surprisingly, it is (almost) possible to do this using Azure (or AWS) and Steam. Maybe you will have better luck than I did, or perhaps you will find a way to make the network between Azure and your desktop more reliable. It is certainly on the verge of possible, and by the time you read this, it may well be worth doing.
This configuration now works streaming 30fps at 1080p. Please see the addendum past the conclusions for the changes required.
You will need:
- An OpenVPN Access Server (AS) virtual appliance
- A Microsoft 365 E3 License
- Sufficient CPU quota in NV family to build a decent gaming PC. I used NV8as_v4, an 8-vCPU processor backed by an AMD Radeon Instinct MI25.
- A really good Internet connection, probably fibre
Some words on each of these below.
OpenVPN Access Server
Being reasonably privacy-oriented and somewhat security-minded, I don’t like having my PCs directly connected to the Internet. So, I’d like to keep all communication with the cloud gaming PC private. There are a few ways into Azure, but this is probably the only realistic option for an individual. The license cost for up to 2 simultaneous connections is free, and the infrastructure cost of the A2 required to host it is about $20CAD/mo.
The deployment of the OpenVPN Access Server marketplace image takes only a few minutes. You will generate a private key during this setup. Use the username you provided and the private key you downloaded in this step to connect via SSH to the AS, e.g.:
ssh -i mygeneratedkey.pem firstname.lastname@example.org
You will be greeted with a text-based setup and license agreement. Finish the setup noting the default values (or changing them as desired).
Once the setup completes, you’ll need to login again, because you need to set the password for the openvpn user.
sudo passwd openvpn
Once the password is set, you can login to the Access Portal on the port you chose during setup (e.g. https://my.vpn.gateway:943/admin/) and those credentials.
In order to configure for Steam, a few setup items need to change. Let’s go through screen by screen and comment where necessary.
Hostname should match the CN of the server certificate if you want to avoid the browser warnings. You can get one at letsencrypt.org if it makes you feel better :)
You should leave “Listen on all interfaces” turned on, but turn off “Multi-daemon mode” and turn on UDP. Change the port number to 1194 (the OpenVPN default).
Note or change the network address assigned to users (and groups if you wish. You probably won’t need to use the groups feature). Add all of the Azure networks you wish to add, at minimum the subnet where you will build your gaming PC.
I’m not sure if this is strictly necessary, but I felt it best to eliminate any address translation. Setting up the routing is relatively straightforward: you need only create a route table, and assign it to the subnets you will access with your VPN client. Create a route table in Azure and edit its routes as follows (e.g.):
SN-192.168.0.0_24 gateway (virtual appliance) my.internal.openvpnas.address
SN-192.168.1.0_24 virtual network
In the example above, the home network is 192.168.0.0/24, and the Azure virtual network is 192.168.1.0/24. The general idea is that you need to add a route to all of your VPN networks using the AS as a gateway. Don’t forget the virtual network and Internet routes!
At this point, after applying your changes to the AS, you should be able to connect to it using the profile imported from https://my.openvpn.gateway:943. You should also have network connectivity to the networks you defined in the AS above.
Steam uses UDP broadcast to find other computers on the network. We’ll need to get UDP broadcast traffic to traverse the tunnel if we’re going to see the cloud PC. Fortunately, AS has an option to do just that. However it cannot be set from the web portal, and must be set from the command line. SSH into the AS using its internal address, the administrative username you provided when building it and the generated private key (as above). If you can connect to the SSH internally, you may want to close the public SSH port. You can always open it again if you run into trouble.
./sacli — key “vpn.routing.allow_mcast” — value “true” ConfigPut
This will apply the UDP multicast option to the AS. The AS is now correctly configured.
Microsoft E3 License
The Microsoft E3 license provides all of the Microsoft software you use on a regular basis, as well as multi-tenant hosting rights on Azure. Alternatively, you may find that the Windows 10 Preview image is sufficient, in which case being a Windows Insider will get you permission to build a development machine in Azure. I won’t go into a great deal of detail on obtaining an E3 license, except to say that you can purchase them from the Billing blade in the Office 365 portal.
In any case, you cannot proceed without obtaining some kind of license to build a Windows 10 machine in Azure.
NV Series VM
The default vCPU quota for NV-series VMs is only 4. You will need 8 cores to build a gaming PC, so you’ll need to request more quota under Help and Support from the Azure portal. These requests are often auto-approved, so you shouldn’t have to wait too long.
The NV v4 Series is built on AMD GPUs (specifically the Radeon Instinct MI25). Build an NV8as_v4 VM using a suitable Windows 10 Image (you can install the AMD GPU drivers on any Pro or Enterprise version up to 20H2). You’ll probably want to use SSD storage, but in considering whether to use Premium Storage, you should consider the costs of leaving the machine sit deallocated. Premium storage is considerably more expensive. You probably don’t want to allocate premium storage to your games drive at any rate, as you will spend a lot of money even when the machine is deallocated. I went with standard SSD storage.
Don’t worry about the full cost of running the machine 24/7 for an entire month. You will be diligent in turning off your machine when not using it, right? You will even enable auto-shutdown if you have some kind of predictable schedule so that it will turn off when you forget, right? Look at the hourly cost, and the cost of storage to estimate your monthly usage.
When creating the VM, add a data drive to hold your games, and install the AMD GPU extension. I also enabled AAD login so that I can use Windows Hello to authenticate to the VM.
Once the machine is installed, login to it and download the drivers for Radeon Instinct from AMD website. You should be able to install the drivers without any issue, and verify in the Device Manager that you now have a Radeon Instinct MI25 display adapter. Partition and format your Games drive. Install Steam and a game to play (on your Games drive).
You’ll need to send Steam to the console to be able to stream from the cloud PC. You can accomplish this as follows (run as Administrator):
tscon 2 /dest:console
I created a shortcut on the desktop to do this (called e.g. Disconnect). You’ll need to add administrative permissions to the shortcut.
OK, so Steam is running and you’ve sent it to the console? You should now be able to see your cloud PC from your desktop and launch your game.
Cost-wise, this essentially becomes the same as leasing a gaming PC. You can only upgrade every 3 years for the price you pay in Azure. An upgrade becomes a simple matter of recreating a later VM model with the same disk. Overall, there are some benefits to working in Azure, not the least of which is the Pay-as-you-Go approach to leasing that minimizes your costs when not actively using it. And that Instinct MI25 is pretty nice too.
Feasibility-wise, this isn’t really there yet. I’m not impressed with the performance of the Haswell vCPUs, and the VPN network just doesn’t seem to be up to the task. I’m not sure whether that’s an issue on the Azure side, but it seems like the public IP doesn’t have a great egress rate. I had unexpected client disconnects a couple of times, but was able to get a game to load. Unfortunately “playable” is a pretty generous term to use. Still, this is the method to make it work when the network catches up.
Practicality-wise, probably not. You need a degree in computer science and a fair bit of experience to pull this off. This is not for your average user. But if you have that degree and experience, maybe give it a shot.
Surprisingly, this can be made to work with only some very minor tweaks to the OpenVPN configuration above. After digging into the OpenVPN configuration, I found I was only getting 25Mbps through the tunnel despite having a 1Gbps connection on either side of the tunnel. Some research into this suggested that the main source of poor throughput was fragmentation. After some experimentation, I found the following:
That the jumbo frames often mentioned do not work over the Internet, so don’t use them
That fragmentation occurs because of inconsistent tun-mtu or link-mtu values. Setting the tun-mtu to 1500 explicitly seems to improve matters
That routing is unnecessary. The UDP broadcast traffic will reach the cloud PC regardless of NAT.
That throughput is slightly better on TCP than UDP
Based on the above, I made the following changes to the configuration:
Change to TCP Port 443
Change from Routing to NAT
Remove the Routing Table
Add tun-mtu 1500, txqueuelen 1000, mssfix 0, fragment 0
Testing this with iPerf, I was able to sustain around 70Mbps over 10 streams for a 1GB transfer. Steam Link reports the speed at over 100Mbps. This is sufficient to play Beautiful quality at 30fps. The input lag is still about 80ms, but it is still playable for most purposes.
One last note is that the Steam Streaming Speakers did not get installed with Steam on the cloud PC, presumably because there is no audio device. You can install these directly from the INF files stored in C:\Program Files (x86)\Common\Steam\drivers. You must go through the Add Legacy Hardware… route and “Have Disk…” to install the speakers and microphone correctly.
GLHF! Just remember to watch your costs, and always turn off and STOP the machine in the Azure Portal to deallocate it and reduce costs.