aws / aws-tools-for-powershell

The AWS Tools for PowerShell lets developers and administrators manage their AWS services from the PowerShell scripting environment.
Apache License 2.0
242 stars 80 forks source link

AWSPowerShell: When Possible, Cmdlets Should Fail Immediately if a Region is not Specified. #10

Closed bgshacklett closed 3 years ago

bgshacklett commented 7 years ago

Expected Behavior

If a Cmdlet which requires a region is executed and no region is specified, either by persistent means, shell defaults, or parameter, the Cmdlet should throw an error.

Current Behavior

The Cmdlet will hang for 15 seconds. Some Cmdlets (Get-CfnStackResource, for instance) cannot be killed with ^C

> measure-command {get-ec2instance}
...
get-ec2instance : No region specified or obtained from persisted/shell
defaults.
...
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 15
Milliseconds      : 820
Ticks             : 158205674
TotalDays         : 0.000183108418981481
TotalHours        : 0.00439460205555556
TotalMinutes      : 0.263676123333333
TotalSeconds      : 15.8205674
TotalMilliseconds : 15820.5674

Possible Solution

Unfortunately, I don't have the visibility into why the current behavior exists, which makes it difficult for me to suggest a resolution. I would, however, suggest keeping "fail fast" in mind.

Steps to Reproduce (for bugs)

  1. Ensure that no region is configured via persisted or shell default mechanisms
  2. Initialize the authentication variables
    • AWS_SESSION_TOKEN
    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY
  3. Run Get-Ec2Instance with no parameters.

Context

If I forget to specify a region, it can be up to 15 seconds for the command to time out and allow me to fix my mistake. Fast iteration on command execution is impeded, and it causes frustration.

Your Environment

Platform : Win32NT ServicePack : Version : 10.0.14393.0 VersionString : Microsoft Windows NT 10.0.14393.0

PSVersion 5.1.14393.1480
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.14393.1480}
BuildVersion 10.0.14393.1480
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

PavelSafronov commented 7 years ago

The reason for the slow execution is that the cmdlets try to get the region from the environment, including the EC2 Instance Metadata, which entails making an HTTP request. The request has a 5 second time-out, and we retry this up to 3 times, which is the 15 second slow-down that you are seeing.

To avoid situations like this we recommend setting a region globally for all cmdlets.

bgshacklett commented 7 years ago

Is there nothing that can be done to detect whether it's running on an EC2 instance in a shorter period of time? I understand your perspective, but most of the time that I make use of the AWS PowerShell module, it's on a management workstation outside of the AWS environment.

Additionally, I understand that the Set-DefaultAWSRegion Cmdlet exists for a reason, but it can be painful to use this when jumping from account to account, as there's no real feedback as to when it's set, and commands may be run in the wrong region accidentally.

PavelSafronov commented 7 years ago

Identifying if a given instance is or is not EC2 is a very complex question and one that we haven't found a satisfactory answer to yet.

bgshacklett commented 7 years ago

What about a configuration item which could be set in a user's profile to disable the instance metadata search? It's hackish, but it's a start.

PavelSafronov commented 7 years ago

The PowerShell cmdlets are built on top of the .NET SDK, and that's where the logic is located (source). So while this is in theory possible, it would be a somewhat complex change. We'll brainstorm on this internally a bit.

PavelSafronov commented 7 years ago

We've added this as a feature request onto our PowerShell backlog.

stevejroberts commented 7 years ago

While we determine what best to d, here's something I use in my profile to help me maintain visually what credential and region context I am currently in:

function prompt
{
    $realLASTEXITCODE = $LASTEXITCODE
    $prompt = ""
    Try
    {
        if ($StoredAWSCredentials -ne $null)
        {
            $prompt += "$StoredAWSCredentials"
            if (!$prompt.EndsWith("@")) { $prompt += "@" }
        }
        if ($StoredAWSRegion -ne $null) { $prompt += "$StoredAWSRegion" }
        $prompt += " "
    }
    Catch
    {
        $prompt = "PS "
    }

    $prompt += $pwd.ProviderPath
    $prompt +=
@"

>
"@

    $global:LASTEXITCODE = $realLASTEXITCODE
    $prompt
}
bgshacklett commented 7 years ago

I'm doing something similar now using the posh-git module, which has a convenience feature to set the prompt (setting $GitPromptSettings.DefaultPromptSuffix).

ashishdhingra commented 3 years ago

Hi @bgshacklett,

Good afternoon.

I was going through the backlog and came across this issue. As mentioned in the https://github.com/aws/aws-tools-for-powershell/issues/10#issuecomment-319796231, region detection involves searching in the predefined locations. I'm not sure of a work around which would disable EC2 Instance Metadata search at this stage. Hope this helps.

Please confirm if could close this issue.

Thanks, Ashish

bgshacklett commented 3 years ago

Seems like there's no easy fix. Thanks for looking into it. I'm onboard with closing it out.

sgupta07 commented 3 years ago

AWSpowershell retries 3 times for all command ? is there a way we can change this setting like aws cli ?