问题
I get the following error when trying to create an SNSClient
object.
InstanceProfileCredentialsException in InstanceMetadataClient.php line 85: Error retrieving credentials from the instance profile metadata server. When you are not running inside of Amazon EC2, you must provide your AWS access key ID and secret access key in the "key" and "secret" options when creating a client or provide an instantiated Aws\Common\Credentials\CredentialsInterface object. (Client error response
[status code] 404
[reason phrase] Not Found
[url] http://169.254.169.254/latest/meta-data/iam/security-credentials/)
I don't understand why I have this error when I have my aws.php
in the config folder of my laravel setup. Here the access key and secret key are stored.
I don't really like this since this causes my credentials to be stored in the folder setup where other's may SFTP into.
What I also have is the aws credentials and config files in my server root folder, in a path like this: ~/.aws/
but for some reason the application is not happy.
Here's what my code looks like:
public function about(){
// Instantiate a client with the credentials from the project1 profile
$snsClient = SnsClient::factory(array(
'profile' => 'default',
'region' => 'us-west-2',
));
// Get the application's endpoints
$iOS_AppArn = "arn:aws:sns:us-west-2:235418406768:app/APNS_SANDBOX/ClashTarget";
$iOS_model = $snsClient->listEndpointsByPlatformApplication(array('PlatformApplicationArn' => $iOS_AppArn));
}
Note that I am using the default
profile which should take the credentials from the root aws directory where the config and credential files are stored.
For now, as a temporary solution I did this: http://blog.ianholden.com/aws-s3-with-php-on-apache/ which makes everything work but I'm not happy having my credential keys living in the application code. It doesn't feel right.
Can someone guide me in getting this error resolved please?
Update 1: Comment: What is the content of config at ~/.aws/
This is the content of the config file in the ~/.aws/
folder
[default]
output = json
region = us-west-2
回答1:
Your ~/.aws/credentials
file should look like this:
[default]
aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
[project1]
aws_access_key_id = ANOTHER_AWS_ACCESS_KEY_ID
aws_secret_access_key = ANOTHER_AWS_SECRET_ACCESS_KEY
The following function is used by the library to determine the directory in which to look for the .aws/credentials
file:
private static function getHomeDir()
{
// On Linux/Unix-like systems, use the HOME environment variable
if ($homeDir = getenv('HOME')) {
return $homeDir;
}
// Get the HOMEDRIVE and HOMEPATH values for Windows hosts
$homeDrive = getenv('HOMEDRIVE');
$homePath = getenv('HOMEPATH');
return ($homeDrive && $homePath) ? $homeDrive . $homePath : null;
}
As you can see, if the HOME
or the HOMEDRIVE
and HOMEPATH
environment variables are not set, the library will not be able to find your credentials file.
In addition to being able to find the file, it also needs to be readable by PHP, and in an INI format (as described above).
Edit
From comments, it sounds like the HOME
environment variable is not set. Because of this, the library cannot find your credentials file. There are a few options for where to go from here.
Option 1:
Fix your server so that the HOME environment variable is set correctly. You will need to do some research on the best way to do this, as the solution may be highly dependent on server/apache/php configurations...
Option 2:
Since you're using Laravel 5, you can add your credentials to your .env
file, and then access them in the code. So, for example, add the following two lines to the end of your .env
file:
AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY
Now, in your code, you can do:
public function about() {
// add "use Aws\Credentials\Credentials;" at the top of your file
// the env() method reads the values from the .env file. ideally you should never
// use the env() method outside of a config file, though, so I'd suggest adding
// a new config file that uses the env statements and using the config here.
$credentials = new Credentials(env('AWS_ACCESS_KEY_ID'), env('AWS_SECRET_ACCESS_KEY'));
// if using the 'credentials' key, do not use the 'profile' key
$snsClient = SnsClient::factory(array(
'region' => 'us-west-2',
'credentials' => $credentials
));
}
Option 3:
Call the CredentialProvider::ini()
method yourself and pass in the profile and full path to your ini file. This will bypass the need for the library to try and determine the home directory.
public function about() {
// add "use Aws\Credentials\CredentialProvider;" at the top of your file
// the first parameter is the profile, the second parameter is the full path to
// your credentials file. You may want to add this to your .env file, and
// access using env()/config() instead of hardcoding here, though.
$credentials = CredentialProvider::ini('default', '/root/.aws/credentials');
// if using the 'credentials' key, do not use the 'profile' key
$snsClient = SnsClient::factory(array(
'region' => 'us-west-2',
'credentials' => $credentials
));
}
回答2:
I can't see exactly reason why you are getting the error, but
I don't really like this since this causes my credentials to be stored in the folder setup where other's may SFTP into.
I suppose you certainly need to setup IAM Role at AWS console to allow connect to SNS from your EC2 instance(s). In this way you won't need to provide any credentials
回答3:
From @Pavan's comment on his question in which he shows the contents of the credentials file in ~/.aws
, it seems that there are 2 files there. I only have one file
$ cat ~/.aws/credentials
[default]
aws_access_key_id = blablabla
aws_secret_access_key = blablabla
region = us-west-2
来源:https://stackoverflow.com/questions/30627029/aws-php-sdk-credentials-error-s