-
Notifications
You must be signed in to change notification settings - Fork 208
Fix AWS Region with Default region #478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix AWS Region with Default region #478
Conversation
If you're new to commit signing, there are different ways to set it up: Sign commits with
|
c743f7f
to
2d45c84
Compare
Default region should only be used to fill in a region when awsConfig.Region doesn't exist (and set it accordingly, but not be the sole determinant on if there is a difference. It should defer to what is already does in the `else if` later, where it sets it if it isn't blank, but doesn't error. Right now, it will error if `default region` is set in the 1Password item, but in reality, it should only do that if `region` (aka: `hasRegularRegion`) is set. This updates this logic to reflect that.
Now not used by the error check below, so removing.
2d45c84
to
ec4ef7a
Compare
97aed46
to
f3cded3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution.
I've left some comments concerning the backwards compatibility of these changes. Could you please take a look and adjust your changes accordingly?
Let me know if you have any questions or need additional guidance. 😄
@@ -643,14 +643,14 @@ func TestResolveLocalAnd1PasswordConfigurations(t *testing.T) { | |||
description: "has region both in 1Password and local config, but values differ", | |||
itemFields: map[sdk.FieldName]string{ | |||
fieldname.OneTimePassword: "515467", | |||
fieldname.DefaultRegion: "us-east-2", | |||
fieldname.Region: "us-east-2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of changing this test, can you add a new one in which the Region is configurerd? In this way, we ensure that this change is backwards compatible.
@@ -250,8 +248,8 @@ Learn how to add an OTP field to your item: | |||
https://developer.1password.com/docs/cli/shell-plugins/aws/#optional-set-up-multi-factor-authentication`, awsConfig.MfaSerial) | |||
} | |||
|
|||
if hasRegion && awsConfig.Region != "" && region != awsConfig.Region { | |||
return fmt.Errorf("your local AWS configuration (config file or environment variable) has a different default region than the one specified in 1Password") | |||
if hasRegularRegion && awsConfig.Region != "" && region != awsConfig.Region { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looks backwards incompatible to me.
What we're trying to achieve is the following:
- If the 1Password item doesn't have any region defined (
default region
norregion
), then look for the default region in the config - If the 1Password item contains
default region
, use that one - If the 1Password item contains
region
, use that one - If the 1Password item contains
default region
and we set the environment variableAWS_REGION
, then use the value fromAWS_REGION
Out of these the following scenario seems to fail now:
A user has a default region in
~/.aws/config
file and adefault region
defined in 1Password item. The shell plugin will now use the value in~/.aws/config
instead of the one in the 1Password item.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this table explains it better in terms of the expected order of precedence:
AWS config file | 1P item default region field | 1P item region field | AWS_REGION env var |
Expected result |
---|---|---|---|---|
✅ | ❌ | ❌ | ❌ | AWS config file value |
✅ | ✅ | ❌ | ❌ | 1P item default region value |
✅ | ❌ | ✅ | ❌ | 1P item region value |
✅ | ✅ | ❌ | ✅ | AWS_REGION env var value |
Out of these 4 cases, the second one doesn't work as expected with the current changes.
Are there any other scenarios that you're thinking of that should be covered by this PR in terms of order of precendence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, getting back to this as I have been a bit swamped at work lately, and as you will probably notice below... it isn't a simple "one line" response to your answer...
If the 1Password item contains default region, use that one
So, this is where I have disagreement, though, recognize it has a nuanced take, and won't die on a hill over it. However, I think it is worth stating all the facts before making a decision.
To start, what is currently in place is wrong: treating "region" and "default region" as the same, when "default region" should only be used to in absence of a --region
and $AWS_REGION
.
In addition, up in the test file you say this:
Instead of changing this test, can you add a new one in which the Region is configurerd? In this way, we ensure that this change is backwards compatible.
about this change:
description: "has region both in 1Password and local config, but values differ",
itemFields: map[sdk.FieldName]string{
fieldname.OneTimePassword: "515467",
- fieldname.DefaultRegion: "us-east-2",
+- fieldname.Region: "us-east-2",
I personally take issue with it for two reasons:
- The spec description doesn't match the arguments that are passed. It passes
DefaultRegion
from thefieldname
, but theregion
is what is being described in thedescription:
. So this test will need to change regardless to properly reflect what it is actually trying to test. - I disagree with the premise this should stay the same for backwards compatibility, because again, I think this functionality is broken. Either:
a. It should be describingfieldname.region
, which then there should be an error when conflicting with what is in the~/.aws/config
already (what I changed the test to be currently).
b. It should be describingfieldname.defaultRegion
, where we then need to set up a proper order of precedence for this plugin and then describe what should actually be tested here.
And to be clear, I should write another test case in addition to what was already there, but when I original was writing this up (9 months ago at this point), I was having trouble getting specs working locally, so I sorta gave up... but I will add another test once we decide on the a
/b
from above (or, as I get to later, a better understanding of how this plugin should behave, as I argue it is unclear).
So regarding the existing region
/default_region
precedence from AWS, we have a decent number documents to sort of derive what it is for the AWS CLI/SDK before introducing the logic from this plugin:
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html#envvars-list-AWS_DEFAULT_REGION
- https://docs.aws.amazon.com/sdkref/latest/guide/feature-region.html
- https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/region.html
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
- https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#general-options
- https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/configure-gosdk.html
I think the first 3 links are the most useful for trying to understand the general patterns across the CLI and all of the SDKs AWS provides, but from what I found, the description in the Ruby (my main language, so also am most comfortable with it) was the most concise example for an SDK.
Generally speaking, region precedence is derived in this order of priority of CLI FLAGS > ENV VARS > ~/.aws/config
, with a more detail list below (ordered from highest precedence to least):
- Directly with a CLI flag (
--region
) or client object (in Ruby...AWS::EC2::Client.new(:region => "...")
) - Directly in a SDK's config object (if it exists)
- in Ruby:
Aws.config(:region => "...")
- in Ruby:
$AWS_REGION
set in the ENV$AWS_DEFAULT_REGION
set in the ENV- The
region =
for the current~/.aws/config
profile, either provided as:--profile
(for the CLI specifically)AWS_PROFILE="my_profile"
(everything)- (you might be able to define a profile in a SDK programmatically as well, but didn't take the time to look up a example)
- The
region
for thedefault
config in the~/.aws/config
- I will refer to this as
[default]region
going forward
- I will refer to this as
Of note is the $AWS_DEFAULT_REGION
env var. My default assumption (prior to researching and looking it up), would be to think that it would be of a lesser priority than then current profile's region (so if AWS_PROFILE=foo
is set, and the [foo]region
is set, it actually supersede that that and $AWS_DEFAULT_REGION
will have the higher priority).
The following example can be used as an example explain a bunch of different scenarios (though, I don't think it is exhaustive):
~/.aws/config
[default]
region = "us-east-1"
[uk]
region = "eu-west-2"
$ aws sts get-caller-identity --debug 2>&1 | grep client_region
# sets the region to us-east-1 (from `default` profile in `~/.aws/config`)
$ AWS_REGION=us-west-1 aws sts get-caller-identity --debug 2>&1 | grep client_region
# sets the region to us-west-1 (from `AWS_REGION`)
$ AWS_DEFAULT_REGION=ca-central-1 aws sts get-caller-identity --debug 2>&1 | grep client_region
# sets the region to ca-central-1 (from `AWS_DEFAULT_REGION`)
$ AWS_DEFAULT_REGION=ca-central-1 AWS_REGION=us-west-1 aws sts get-caller-identity --debug 2>&1 | grep client_region
# sets the region to us-west-1 (from `AWS_REGION`)
$ AWS_DEFAULT_REGION=ca-central-1 aws sts get-caller-identity --profile uk --debug 2>&1 | grep client_region
# sets the region to ca-central-1 (from `AWS_DEFAULT_REGION`)
$ aws sts get-caller-identity --profile uk --debug 2>&1 | grep client_region
# sets the region to eu-west-2 (from `uk` profile in `~/.aws/config`)
Again, I would personally would assume normally that AWS_DEFAULT_REGION
would be treated more like [default]region
in the ~/.aws/config
, just with a slightly higher priority, but instead, it completely supersedes the precedence even the [uk]region
above. I guess the thought process from AWS' perspective is any ENV takes priority over anything in the ~/.aws/config
, versus anything "default region" being evaluated first, then anything specifically "region" being evaluated after (how I personally would like it to be and makes more sense in my eyes).
Where I think a decision needs to be made is where 1Password
, and this plugin, should inject itself in this mess, which I think is a non-trival question to answer.
For me personally , I think having defaultRegion
be the lowest priority beyond anything above makes the most sense to me. Basically, set region to that if nothing else exists to set it, otherwise use what is provided through any other means (including fieldname.region
from 1Password), and not error at all. This will act different than how fieldname.region
currently works, where it will error if there is a conflict. To me, this is the most useful, where I don't want to be editing my defaultRegion
in 1Password ever, and it is simply there to provide something when all else is absent, and probably most people will be using ~/.aws/config
anyway, so a default can really be set there.
If, instead, we are treating this more similar to $AWS_DEFAULT_REGION
, which, based on the current documentation is a reasonable conclusion to come to:
Then I don't really see this having errors on around it, and it is simply a backup or initial setting of $AWS_DEFAULT_REGION
isn't already set, but still will take more precedence than what is in the ~/.aws/config
. What was here previously was then erroring if either fieldname.region
or fieldname.defaultRegion
is defined, which I think don't think makes any sense all, and what I am trying to change here. But I can at least understand logically making it behave more like the existing $AWS_DEFAULT_REGION
ENV var it is meant to stand in for, regardless if it is confusing to me personally or not.
With region
, I can more understand that field having errors, since without them, you could mask errors/unintended behaviour when used in conjunction with ~/.aws/config
. However, I don't see anywhere in the docs above where fieldname.region
is even mentioned to define it, so I this as kind of a hidden feature anyway and makes it hard to for me to determine what the expectations are. I may had a bit better of an idea of the intentions when I original wrote up this PR, as I did spend some time doing some git
history explanation into this plugin, but any knowledge of that has escaped me at this point.
Personally, I don't see any utility in having the region
in 1Password without it being able to be overwritten by a profile anyway (so, the errors are kind of an anti-feature to me), but also that isn't my biggest concern with this PR, and instead separating fieldname.defaultRegion
from the fieldname.region
is.
Main point with all of this is that without defining the order of precedence, and what each of these fields are supposed to do in the context of the greater existing precedence and expectations (set by AWS), then there isn't much else that I can do here before that and we should probably define that first (ideally in the documentation).
At this point, I could see what I am writing here more as the start of a GitHub Issue, which in hindsight, maybe is what I should have started with in the first place (miscalculation on the quagmire I was getting myself into I guess, so mostly self induced and a realization in hindsight). So if that makes more sense, we can do that and disregard this PR until the expectations of how this plugin should treat these fields is determined. I would say even having this discussion in regards to the documentation makes more sense, but I am not sure there is a opensource repo for me to do that against so that might not be an option.
Curious on your thoughts on what makes sense going forward. Thanks.
Overview
When using the
aws
plugin, if theDEFAULT_REGION
is set in the 1Password item, it will override any usage ofAWS_REGION
, which should take president normally with theaws
cli, preventing the usage of being able to connect to other regions unless you regularly change theDEFAULT_REGION
value in the1Password
each time.Type of change
Related Issue(s)
How To Test
DEFAULT_REGION
value in your 1Password item you use for theaws
pluginaws s3 ls
(or something similar)DEFAULT_REGION
AWS_REGION=different-region aws s3 ls
, using adifferent-region
then the one you have configuredIn the previous version, this would return the same value for both commands, and this should fix that.
Other options is quering for something specific by ARN that exists in only in the
DEFAULT_REGION
, and with this patch, the second command will fail, where previously it would find it.Changelog
Fix
DEFAULT_REGION
logic foraws
plugin to allow for overrides usingAWS_REGION
.