Editing your HOSTS file with Powershell for your AWS Instance

Published on 05 May 2020

Introduction

I have a Linux2 instance in AWS that I used for playing around with Python. I connect to it using Remote Explorer (which uses SSH) in VSCode which means I can do the Python bits on my own Windows 10 device, but the code actually runs (and lives) on the instance. All good, but I don't want to keep my t2.micro running all the time, and I don't want to have to keep editing the SSH target information everytime I stop and start the instance. Lastly, I don't want to pay for an elastic IP.

VScode1

The easiest way to do this then, is to configure my SSH target to be a name, rather than an IP address, and then to programatically edit my HOSTS file. The solution was to create a function that I call call whenever I want to connect to Python. Basically, it will start the instance, wait for a public IP address, and then add that into my hosts file.

Start-PythonServer Function

This function then can be run from an administrative window (it needs to be to edit the hosts file). It also edits the hosts file to set the IP address of an entry called "PythonVM". If yours is called something else, it won't find it. PythonVM is the name that I use within the VSCode configuration.

    Function start-PythonServer {
        # Will only run from an elevated prompt

        do {
            $instances = get-ec2instance -region "us-east-1"
            $PythonVM = $instances.instances | select-object instanceid, state, publicIPaddress, @{Name = "Name"; Expression = { $_.tags | where key -eq "Name" | select Value -expand Value } } | where Name -like "*PythonVM*"
            start-ec2instance -instanceID $pythonVM.instanceID -region "us-east-1"
            $IP = $pythonVM.PublicIpAddress
            start-sleep 3
        } Until ($ip) 

        #backup the hosts file
        $Hostsfile = "$env:windir\System32\drivers\etc\hosts"
        copy-item -path $hostsfile -Destination "$env:windir\System32\drivers\etc\hosts.old"
        $myHosts = Get-Content $hostsfile
        
        $urltext = "PythonVM"
        $regex1 = '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\s+' + [regex]::escape($urltext)
        $regex2 = "$ip`t$urltext"
        If ($myhosts -match $regex1) {
            #There is an existing entry, so modify it
            $myhosts = ($myHosts -replace $regex1, $regex2 )
        }
        else {
            #Entry not found, so need to add
            $myhosts += $regex2
        }
        #Write the new data to hosts
        if (test-path $hostsfile) {
            remove-item -path $hostsfile -force 
            $myhosts > $hostsfile
            Clear-DnsClientCache
        }
    }

Implementing

Don't forget that you will need to stop your instance after (you could use a "stop-python" script, or a lambda function that shuts it after an event or on a schedule). I assume you already have the AWS CLI tools installed and credentials configured to connect to your AWS environment.

After that, it should be much less of a headache to start and stop your instance and remote to it!

VScode2

comments powered by Disqus