If you’re a frequent user of the AWS Powershell tools, you’ve probably had this experience: you go to run a couple commands against your AWS environment. You do it all the time, so you know to type
Get-EC2Instance -InstanceId i-1111111111
But out of force of habit you type
Get-Ec2inst
And hit the tab key. Now you’re sitting and waiting for several minutes while Powershell loads all of the AWS modules for IAM, ECS, Cloudfront, S3, etc, etc, etc, even though you only want to interact with EC2. A few minutes later it’s done, and you start typing again
Get-EC2Instance -ins
And without thinking you hit the tab key again, and wait for another few minutes while Powershell loads parameter completion.
Well, AWS recently released AWS.Tools for Powershell. It’s a modularized version of the AWS Powershell tools that promises better load times because you can pick and choose the modules for AWS services that you want. Like most of you, I’m hesitant to try anything new fangled on my main laptop right away. Your boss probably likes hearing, “I can’t help with that issue right now, I broke my management environment” as much as mine does.
So I figured I’d try installing the tools in a docker container first. My current windows 10 version is 1803, so I’ll be using
mcr.microsoft.com/windows/servercore:1803
(Yes, I know server nano is smaller. Yes, I know you can run AWS.Tools on linux with .NET Core. I use a windows laptop, so I’d like to see AWS.Tools running in as close to my laptop as I can get)
docker run -it -v "$($home)/.aws:c:\users\containeradministrator\.aws" mcr.microsoft.com/windows/servercore:1803 powershell
The -v is to map my AWS credentials into the container to use after I install AWS.Tools
Next, following the install instructions here I run
Install-Module -Name AWS.Tools.Installer
I had to accept a new NuGet provider when prompted
NuGet provider is required to continue
PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program
Files\PackageManagement\ProviderAssemblies' or 'C:\Users\ContainerAdministrator\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running
'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install and import the NuGet provider now?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y
And then accept that AWS is technically an untrusted repository
Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to
install the modules from 'PSGallery'?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): Y
Easy enough! Next I tried to use the build in installer function that handles dependencies for you. I’ll start with just the EC2 module for simplicity
Install-AWSToolsModule AWS.Tools.EC2
This command sat for quite a while for me, but when it was done I couldn’t import or use the modle
PS C:\> get-ec2instance
get-ec2instance : The term 'get-ec2instance' is not recognized
I haven’t taken the time to troubleshoot this, but it seems like the documentation promises to install to $env:ProgramFiles\Powershell\Modules
when the container has $env:ProgramFiles\WindowsPowershell\modules
At any rate, let’s try just grabbing the modules ourselves instead of letting AWS abstract it away.
I ran these commands to grab the common module (used by all the AWS.Tools modules) and the EC2 module directly
install-module AWS.Tools.Common
install-module AWS.Tools.EC2
Which seems to work great, and I can now interact with AWS like I’d expect
PS C:\> Get-EC2Instance -InstanceId i-**********
GroupNames : {}
Groups : {}
Instances : {******}
OwnerId : *********
RequesterId : 987******
ReservationId : r-***********
Now that I’ve got it working, I removed all of the modules from my session with
Remove-module AWS*
So I can compare importing the module versions to the monolithic tools on my laptop. I’ll use this command in both environments to see how long it takes to load the modules, and query EC2 for the results:
$start = get-date;$result = Get-EC2Instance -InstanceId i-********;$end = get-date;write-host "$($end - $start)";
Loading the EC2 module result was 00:00:01.5066032, so under 2 seconds! The next run was much faster, with all of the module already loaded
PS C:\> $start = get-date;$result = Get-EC2Instance -InstanceId i-**********;$end = get-date;write-host "$($end - $start)";
00:00:00.8229332
Under a second! Let’s try that with the old AWSPowershellTools back on my laptop (which loads all of the AWS powershell modules when you call any command)
PS C:\Users\bolson> $start = get-date;$result = Get-EC2Instance -InstanceId i-***********;$end = get-date
;write-host "$($end - $start)";
00:00:08.1064289
Over 8 seconds! It’s not a huge price to pay, but I’ll take a second load time over 8 any day.
Finally, I used this blog post to submit a new issue: https://github.com/aws/aws-tools-for-powershell/issues/118. I haven’t had time to debug what could be wrong, hoping someone else can pick up the torch.