Skip to content

Commit

Permalink
Partial revertion of environment variable fallback (#1224) (#1355)
Browse files Browse the repository at this point in the history
fixes #1353

SUMMARY

#1224 exposed that the removal of support for passing both profiles and security tokens was only partially implemented in release 5.0.0 (#834)

Since we had already announced that support would be dropped for passing both (back in 2020 with release 1.2.0), I think it's reasonable to still fully drop support in 6.0.0. The documentation was originally very fuzzy about when we'd fallback and use which variables.

ISSUE TYPE

- Bugfix Pull Request

COMPONENT NAME

plugins/module_utils/botocore.py
plugins/module_utils/modules.py

ADDITIONAL INFORMATION
  • Loading branch information
tremble authored Feb 22, 2023
1 parent 3259187 commit a7790ac
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 19 deletions.
7 changes: 7 additions & 0 deletions changelogs/fragments/1353-revert-env-fallback.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bugfixes:
- revert breaking change introduced in 5.2.0 when passing credentials through a mix of environment variables and parameters (https://github.com/ansible-collections/amazon.aws/issues/1353).
deprecated_features:
- support for passing both profile and security tokens through a mix of environment variables and parameters has been deprecated and support will be removed in release 6.0.0.
After release 6.0.0 it will only be possible to pass either a profile or security tokens, regardless of mechanism used to pass them. To explicitly block a parameter coming from an environment variable pass an empty string as the parameter value```
Support for passing profile and security tokens together was originally deprecated in release 1.2.0, however only partially implemented in release 5.0.0
(https://github.com/ansible-collections/amazon.aws/pull/1355).
16 changes: 13 additions & 3 deletions plugins/doc_fragments/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class ModuleDocFragment(object):
U(https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys).
- The C(AWS_ACCESS_KEY_ID), C(AWS_ACCESS_KEY) or C(EC2_ACCESS_KEY)
environment variables may also be used in decreasing order of
preference.
preference. Prior to release 6.0.0 these environment variables will be
ignored if the I(profile) parameter is passed. After release 6.0.0
I(access_key) will always fall back to the environment variables if set.
- The I(aws_access_key) and I(profile) options are mutually exclusive.
- The I(aws_access_key_id) alias was added in release 5.1.0 for
consistency with the AWS botocore SDK.
Expand All @@ -36,7 +38,9 @@ class ModuleDocFragment(object):
U(https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys).
- The C(AWS_SECRET_ACCESS_KEY), C(AWS_SECRET_KEY), or C(EC2_SECRET_KEY)
environment variables may also be used in decreasing order of
preference.
preference. Prior to release 6.0.0 these environment variables will be
ignored if the I(profile) parameter is passed. After release 6.0.0
I(secret_key) will always fall back to the environment variables if set.
- The I(secret_key) and I(profile) options are mutually exclusive.
- The I(aws_secret_access_key) alias was added in release 5.1.0 for
consistency with the AWS botocore SDK.
Expand All @@ -53,6 +57,9 @@ class ModuleDocFragment(object):
U(https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys).
- The C(AWS_SESSION_TOKEN), C(AWS_SECURITY_TOKEN) or C(EC2_SECURITY_TOKEN)
environment variables may also be used in decreasing order of preference.
Prior to release 6.0.0 these environment variables will be
ignored if the I(profile) parameter is passed. After release 6.0.0
I(session_token) will always fall back to the environment variables if set.
- The I(security_token) and I(profile) options are mutually exclusive.
- Aliases I(aws_session_token) and I(session_token) were added in release
3.2.0, with the parameter being renamed from I(security_token) to
Expand All @@ -70,7 +77,10 @@ class ModuleDocFragment(object):
- A named AWS profile to use for authentication.
- See the AWS documentation for more information about named profiles
U(https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html).
- The C(AWS_PROFILE) environment variable may also be used.
- The C(AWS_PROFILE) environment variable may also be used. Prior to release 6.0.0 the
C(AWS_PROFILE) environment variable will be ignored if any of I(access_key), I(secret_key),
or I(session_token) are passed. After release 6.0.0 I(profile) will always fall back to the
C(AWS_PROFILE) environment variable if set.
- The I(profile) option is mutually exclusive with the I(aws_access_key),
I(aws_secret_key) and I(security_token) options.
type: str
Expand Down
61 changes: 49 additions & 12 deletions plugins/module_utils/botocore.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ def get_aws_region(module, boto3=None):

# here we don't need to make an additional call, will default to 'us-east-1' if the below evaluates to None.
try:
# Botocore doesn't like empty strings, make sure we default to None in the case of an empty
# string.
profile_name = module.params.get('profile') or None
profile_name = module.params.get('profile')
return botocore.session.Session(profile=profile_name).get_config_variable('region')
except botocore.exceptions.ProfileNotFound:
return None
Expand All @@ -171,25 +169,64 @@ def get_aws_connection_info(module, boto3=None):
ca_bundle = module.params.get('aws_ca_bundle')
config = module.params.get('aws_config')

# Only read the profile environment variables if we've *not* been passed
# any credentials as parameters.
if not profile_name and not access_key and not secret_key:
if os.environ.get('AWS_PROFILE'):
profile_name = os.environ.get('AWS_PROFILE')
if os.environ.get('AWS_DEFAULT_PROFILE'):
profile_name = os.environ.get('AWS_DEFAULT_PROFILE')

if profile_name and (access_key or secret_key or session_token):
module.fail_json(msg="Passing both a profile and access tokens is not supported.")

# Botocore doesn't like empty strings, make sure we default to None in the case of an empty
# string.
if not access_key:
access_key = None
# AWS_ACCESS_KEY_ID is the one supported by the AWS CLI
# AWS_ACCESS_KEY is to match up with our parameter name
if os.environ.get('AWS_ACCESS_KEY_ID'):
access_key = os.environ['AWS_ACCESS_KEY_ID']
elif os.environ.get('AWS_ACCESS_KEY'):
access_key = os.environ['AWS_ACCESS_KEY']
# Deprecated - 'EC2' implies just EC2, but is global
elif os.environ.get('EC2_ACCESS_KEY'):
access_key = os.environ['EC2_ACCESS_KEY']
else:
# in case access_key came in as empty string
access_key = None

if not secret_key:
secret_key = None
# AWS_SECRET_ACCESS_KEY is the one supported by the AWS CLI
# AWS_SECRET_KEY is to match up with our parameter name
if os.environ.get('AWS_SECRET_ACCESS_KEY'):
secret_key = os.environ['AWS_SECRET_ACCESS_KEY']
elif os.environ.get('AWS_SECRET_KEY'):
secret_key = os.environ['AWS_SECRET_KEY']
# Deprecated - 'EC2' implies just EC2, but is global
elif os.environ.get('EC2_SECRET_KEY'):
secret_key = os.environ['EC2_SECRET_KEY']
else:
# in case secret_key came in as empty string
secret_key = None

if not session_token:
session_token = None
# AWS_SESSION_TOKEN is supported by the AWS CLI
if os.environ.get('AWS_SESSION_TOKEN'):
session_token = os.environ['AWS_SESSION_TOKEN']
# Deprecated - boto
elif os.environ.get('AWS_SECURITY_TOKEN'):
session_token = os.environ['AWS_SECURITY_TOKEN']
# Deprecated - 'EC2' implies just EC2, but is global
elif os.environ.get('EC2_SECURITY_TOKEN'):
session_token = os.environ['EC2_SECURITY_TOKEN']
else:
# in case secret_token came in as empty string
session_token = None

if profile_name:
boto_params = dict(
aws_access_key_id=None,
aws_secret_access_key=None,
aws_session_token=None,
profile_name=profile_name,
)
boto_params = dict(aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None)
boto_params['profile_name'] = profile_name
else:
boto_params = dict(
aws_access_key_id=access_key,
Expand Down
4 changes: 0 additions & 4 deletions plugins/module_utils/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,15 +380,13 @@ def _aws_common_argument_spec():
deprecated_aliases=[
dict(name='ec2_access_key', date='2024-12-01', collection_name='amazon.aws'),
],
fallback=(env_fallback, ['AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY', 'EC2_ACCESS_KEY']),
no_log=False,
),
secret_key=dict(
aliases=['aws_secret_access_key', 'aws_secret_key', 'ec2_secret_key'],
deprecated_aliases=[
dict(name='ec2_secret_key', date='2024-12-01', collection_name='amazon.aws'),
],
fallback=(env_fallback, ['AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_KEY', 'EC2_SECRET_KEY']),
no_log=True,
),
session_token=dict(
Expand All @@ -398,12 +396,10 @@ def _aws_common_argument_spec():
dict(name='security_token', date='2024-12-01', collection_name='amazon.aws'),
dict(name='aws_security_token', date='2024-12-01', collection_name='amazon.aws'),
],
fallback=(env_fallback, ['AWS_SESSION_TOKEN', 'AWS_SECURITY_TOKEN', 'EC2_SECURITY_TOKEN']),
no_log=True,
),
profile=dict(
aliases=['aws_profile'],
fallback=(env_fallback, ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']),
),

endpoint_url=dict(
Expand Down

0 comments on commit a7790ac

Please sign in to comment.