jamesMcKey
jamesMcKey

Reputation: 491

Send an Email Using the AWS SDK for PHP

I am trying to set up email using AWS SDK for PHP, so far unsuccessfully. I have done the following:

  1. verified my domain and recipient email addresses.
  2. Generated my AWS access key

3.installed pHP version 7.0.25

4.installed nstall the AWS SDK for PHP version 3.

  1. Created a shared credentials file.

The documentation instructs that I need to save this file to the following location: "~/.aws/credentials" (I am using MAC)

My question is i do not have ".aws" folder, so I created one (hidden aws directory) in my home directory and then saved my "credentials" file in there(containing by access key credentials). I am getting the following error:

 PHP Fatal error:  Uncaught Aws\Exception\CredentialsException: Error 
 retrieving credentials from the instance profile metadata server. (Client 
 error: `GET http://169.254.169.254/latest/meta-data/iam/security-
 credentials/` resulted in a `404 Not Found` response:
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "htt (truncated...)
 ) in /home/ec2-user/vendor/aws/aws-sdk-
 php/src/Credentials/InstanceProfileProvider.php:79
 Stack trace:
 #0 /home/ec2-user/vendor/guzzlehttp/promises/src/Promise.php(203): 
 Aws\Credentials\InstanceProfileProvider->Aws\Credentials\{closure}
 (Object(GuzzleHttp\Exception\ClientException))
 #1 /home/ec2-user/vendor/guzzlehttp/promises/src/Promise.php(156): 
 GuzzleHttp\Promise\Promise::callHandler(2, Array, Array)
 #2 /home/ec2-user/vendor/guzzlehttp/promises/src/TaskQueue.php(47): 
 GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
 #3 /home/ec2-
 user/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(96): 
 GuzzleHttp\Promise\TaskQueue- in /home/ec2-user/vendor/aws/aws-sdk-
 php/src/Credentials/InstanceProfileProvider.php on line 79

PHP script executed in the terminal (as described by aws: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-php.html):

 <?php

 // Replace path_to_sdk_inclusion with the path to the SDK as described in 
 // http://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/basic-
 usage.html
 define('REQUIRED_FILE','path_to_sdk_inclusion'); 

 // Replace [email protected] with your "From" address. 
 // This address must be verified with Amazon SES.
 define('SENDER', '[email protected]');           

 // Replace [email protected] with a "To" address. If your account 
 // is still in the sandbox, this address must be verified.
 define('RECIPIENT', '[email protected]');    

 // Specify a configuration set. If you do not want to use a configuration
 // set, comment the following variable, and the 
 // 'ConfigurationSetName' => CONFIGSET argument below.
 define('CONFIGSET','ConfigSet');

 // Replace us-west-2 with the AWS Region you're using for Amazon SES.
 define('REGION','us-west-2'); 

 define('SUBJECT','Amazon SES test (AWS SDK for PHP)');

 define('HTMLBODY','<h1>AWS Amazon Simple Email Service Test Email</h1>'.
              '<p>This email was sent with <a 
 href="https://aws.amazon.com/ses/">'.
              'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-
 for-php/">'.
              'AWS SDK for PHP</a>.</p>');
 define('TEXTBODY','This email was send with Amazon SES using the AWS SDK for 
 PHP.');

 define('CHARSET','UTF-8');

 require REQUIRED_FILE;

 use Aws\Ses\SesClient;
 use Aws\Ses\Exception\SesException;

 $client = SesClient::factory(array(
     'version'=> 'latest',     
     'region' => REGION
 ));

 try {
      $result = $client->sendEmail([
     'Destination' => [
         'ToAddresses' => [
             RECIPIENT,
        ],
 ],
'Message' => [
    'Body' => [
        'Html' => [
            'Charset' => CHARSET,
            'Data' => HTMLBODY,
        ],
        'Text' => [
            'Charset' => CHARSET,
            'Data' => TEXTBODY,
        ],
    ],
    'Subject' => [
        'Charset' => CHARSET,
        'Data' => SUBJECT,
    ],
],
'Source' => SENDER,
// If you are not using a configuration set, comment or delete the
// following line
     'ConfigurationSetName' => CONFIGSET,
 ]);
 $messageId = $result->get('MessageId');
 echo("Email sent! Message ID: $messageId"."\n");

 } catch (SesException $error) {
 echo("The email was not sent. Error message: ".$error-
 >getAwsErrorMessage()."\n");
 }

 ?>

Upvotes: 0

Views: 1388

Answers (1)

John Hanley
John Hanley

Reputation: 81454

First, you do not manually create ~/.aws/credentials. Let the AWS CLI do this for you.

Install the CLI: pip install awscli --upgrade

Delete the credentials file that you created.

Configure the CLI and credentials: aws configure

Your credentials are now setup correctly.

The error message that you received is caused by the PHP SDK trying to get the credentials from the EC2 Instance Metadata. This was failing as you have not configured an IAM Role to this system. This also means that the credentials are not stored correctly in your profile (~/.aws/credentials).

Note: The better method is to NOT store credentials on your EC2 instances. Instead create an IAM Role and assign that role to the EC2 instance. All AWS SDKs know know how to extract the credentials from the instance metadata.

IAM Roles for Amazon EC2

Upvotes: 1

Related Questions