Skip to content
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

InstanceProfile is too slow compared to credentials #2778

Closed
bounlu opened this issue Sep 15, 2023 · 3 comments
Closed

InstanceProfile is too slow compared to credentials #2778

bounlu opened this issue Sep 15, 2023 · 3 comments
Assignees
Labels
response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@bounlu
Copy link

bounlu commented Sep 15, 2023

Describe the bug

I have run the identical PHP code in an EC2 instance to access an RDS instance with:

  1. Credentials file (~/.aws/credentials)
  2. IAM role (temporary instance credentials)

Both work as expected, no issue with getting the credentials and making calls to other services (RDS, SecretsManager, STS) to retrieve data.

However, the 2. option with instance credentials is much slower causing terrible user experience on the website. It takes 2 seconds for each call stacking up to longer waiting times for multiple calls.

I used the sample code provided by AWS:

		require '../vendor/autoload.php';

		// AWS resources
		$host = "xxx";
		$database = "yyy";
		$region = "zzz";
		$secretName = 'sss';

		// Use the default credential provider
		$provider = \Aws\Credentials\CredentialProvider::defaultProvider();

		// Create a Secrets Manager Client
		$client = new \Aws\SecretsManager\SecretsManagerClient([
			'version' => 'latest',
			'region' => $region,
			'credentials' => $provider
		]);

		try {
			$result = $client->getSecretValue([
				'SecretId' => $secretName,
			]);
		} catch (\Aws\Exception\AwsException $e) {
			$error = $e->getAwsErrorCode();
			if ($error == 'DecryptionFailureException') {
				// Secrets Manager can't decrypt the protected secret text using the provided AWS KMS key.
				throw $e;
			}
			if ($error == 'InternalServiceErrorException') {
				// An error occurred on the server side.
				throw $e;
			}
			if ($error == 'InvalidParameterException') {
				// You provided an invalid value for a parameter.
				throw $e;
			}
			if ($error == 'InvalidRequestException') {
				// You provided a parameter value that is not valid for the current state of the resource.
				throw $e;
			}
			if ($error == 'ResourceNotFoundException') {
				// We can't find the resource that you asked for.
				throw $e;
			}
		}

		// Decrypts secret using the associated KMS CMK.
		// Depending on whether the secret is a string or binary, one of these fields will be populated.
		if (isset($result['SecretString'])) {
			$secret = $result['SecretString'];
		} else {
			$secret = base64_decode($result['SecretBinary']);
		}

		$secretArray = json_decode($secret, true);
		$username = $secretArray['username'];
		$password = $secretArray['password'];

Also tried with this code for the provider:

		// Passing Aws\Credentials\AssumeRoleCredentialProvider options directly
		$profile = new \Aws\Credentials\InstanceProfileProvider();

		$assumeRoleCredentials = new \Aws\Credentials\AssumeRoleCredentialProvider([
			'client' => new \Aws\Sts\StsClient([
				'version' => 'latest',
				'region' => $region,
				'credentials' => $profile
			]),
			'assume_role_params' => [
				'RoleArn' => $arn,
				'RoleSessionName' => $sessionName
			]
		]);

		// To avoid unnecessarily fetching STS credentials on every API operation,
		// the memoize function handles automatically refreshing the credentials when they expire
		$provider = \Aws\Credentials\CredentialProvider::memoize($assumeRoleCredentials);

Expected Behavior

Fast response

Current Behavior

Slow response

Reproduction Steps

See the code above

Possible Solution

No response

Additional Information/Context

No response

SDK version used

3

Environment details (Version of PHP (php -v)? OS name and version, etc.)

PHP 8.2, Ubuntu, Docker

@bounlu bounlu added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Sep 15, 2023
@yenfryherrerafeliz
Copy link
Contributor

Hi @bounlu, sorry to hear about your issues. I guess that you are using container, and if so then, this issue is caused because your ec2 instance hop limit is set to either 1 or less, but your container would need an extra one so that the SDK is able to resolve the credential in the first try and using the IMDSv2.
So, here is the what you can do to solve this issue:
From the terminal, please run the following command to increase your hop limit to 2.

aws ec2 modify-instance-metadata-options
        --instance-id YOUR-INSTANCE-ID \
    --http-put-response-hop-limit 2

Note: please make sure that you have CLI installed and that you replace "YOUR-INSTANCE-ID" with your ec2 instance id

Please let me know if that helps!

Thanks!

@yenfryherrerafeliz yenfryherrerafeliz added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Sep 18, 2023
@yenfryherrerafeliz yenfryherrerafeliz self-assigned this Sep 18, 2023
@bounlu
Copy link
Author

bounlu commented Sep 19, 2023

Hi @yenfryherrerafeliz

Yes I am using container and this setting solved the problem. Thanks for pointing me to this.

@bounlu bounlu closed this as completed Sep 19, 2023
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

2 participants