|
26 | 26 | import sys
|
27 | 27 | import tarfile
|
28 | 28 | import tempfile
|
| 29 | + |
29 | 30 | from six.moves.urllib.parse import urlparse
|
30 | 31 | from threading import Thread
|
31 | 32 |
|
@@ -630,24 +631,52 @@ def _aws_credentials(session):
|
630 | 631 | creds = session.get_credentials()
|
631 | 632 | access_key = creds.access_key
|
632 | 633 | secret_key = creds.secret_key
|
633 |
| - |
634 |
| - # if there is a Token as part of the credentials, it is not safe to |
635 |
| - # pass them as environment variables because the Token is not static, this is the case |
636 |
| - # when running under an IAM Role in EC2 for example. By not passing credentials the |
637 |
| - # SDK in the container will look for the credentials in the EC2 Metadata Service. |
638 |
| - if creds.token is None: |
| 634 | + token = creds.token |
| 635 | + |
| 636 | + # The presence of a token indicates the credentials are short-lived and as such are risky to be used as they |
| 637 | + # might expire while running. |
| 638 | + # Long-lived credentials are available either through |
| 639 | + # 1. boto session |
| 640 | + # 2. EC2 Metadata Service (SageMaker Notebook instances or EC2 instances with roles attached them) |
| 641 | + # Short-lived credentials available via boto session are permitted to support running on machines with no |
| 642 | + # EC2 Metadata Service but a warning is provided about their danger |
| 643 | + if token is None: |
| 644 | + logger.info("Using the long-lived AWS credentials found in session") |
639 | 645 | return [
|
640 | 646 | 'AWS_ACCESS_KEY_ID=%s' % (str(access_key)),
|
641 | 647 | 'AWS_SECRET_ACCESS_KEY=%s' % (str(secret_key))
|
642 | 648 | ]
|
| 649 | + elif not _aws_credentials_available_in_metadata_service(): |
| 650 | + logger.warn("Using the short-lived AWS credentials found in session. They might expire while running.") |
| 651 | + return [ |
| 652 | + 'AWS_ACCESS_KEY_ID=%s' % (str(access_key)), |
| 653 | + 'AWS_SECRET_ACCESS_KEY=%s' % (str(secret_key)), |
| 654 | + 'AWS_SESSION_TOKEN=%s' % (str(token)) |
| 655 | + ] |
643 | 656 | else:
|
| 657 | + logger.info("No AWS credentials found in session but credentials from EC2 Metadata Service are available.") |
644 | 658 | return None
|
645 | 659 | except Exception as e:
|
646 |
| - logger.info('Could not get AWS creds: %s' % e) |
| 660 | + logger.info('Could not get AWS credentials: %s' % e) |
647 | 661 |
|
648 | 662 | return None
|
649 | 663 |
|
650 | 664 |
|
| 665 | +def _aws_credentials_available_in_metadata_service(): |
| 666 | + import botocore |
| 667 | + from botocore.credentials import InstanceMetadataProvider |
| 668 | + from botocore.utils import InstanceMetadataFetcher |
| 669 | + |
| 670 | + session = botocore.session.Session() |
| 671 | + instance_metadata_provider = InstanceMetadataProvider( |
| 672 | + iam_role_fetcher=InstanceMetadataFetcher( |
| 673 | + timeout=session.get_config_variable('metadata_service_timeout'), |
| 674 | + num_attempts=session.get_config_variable('metadata_service_num_attempts'), |
| 675 | + user_agent=session.user_agent()) |
| 676 | + ) |
| 677 | + return not (instance_metadata_provider.load() is None) |
| 678 | + |
| 679 | + |
651 | 680 | def _write_json_file(filename, content):
|
652 | 681 | with open(filename, 'w') as f:
|
653 | 682 | json.dump(content, f)
|
|
0 commit comments