PHP Upload file to an Amazon S3 bucket via pre-signed url

I'm trying to upload a file to an Amazon S3 bucket via a presigned URL, that I've got from a third service. Meaning, I'm not generating this URL. I've been through AWS documentation, but I can't put it all together. Here is what I'm referring to.

Currently, my code looks like this. Please note, $key is the presigned URL.

use Aws\S3\S3Client;
use Aws\Exception\AwsException;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\CachingStream;

$client = new GuzzleHttp\Client(['verify' => false ]);
$response = $client->get($image_url);
$s3 = new Aws\S3\S3Client([
  'version'   => 'latest',
  'region'    => 'eu-west-1',
  'signature_version' => 'v4'
  )        
]);

$s3->putObject([
  'Bucket'        => '<BUCKET NAME HERE>',
  'Key'           => $key,
  'ContentLength' => get_headers($image_url,1)['Content-Length'],
  'ContentType'   => 'image/png',
  'Body'          => $response->getBody(),
  'ACL'           => 'private-write',
]);

Currently, I'm getting this error: PHP Fatal error: Uncaught Aws\Exception\CredentialsException: Error retrieving credentials from the instance profile metadata service. (cURL error 7: (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://169.254.169.254/latest/meta-data/iam/security-credentials/) in <PATH TO SITE>\vendor\aws\aws-sdk-php\src\Credentials\InstanceProfileProvider.php:242

Any help is much appreciated.

Answer

Solution:

The problem here is that you have not passed credentials i.e. AccessKey and Secret Key while initializing S3 client.

$s3 = new Aws\S3\S3Client([
  'version'   => 'latest',
  'region'    => 'eu-west-1',
  'signature_version' => 'v4',
  'credentials' => [
            'key'    => 'access-key',
            'secret' => 'secret-key' ,
        ]
  )        
]);

If you want to pass AccessKey and SecretKey from a file as opposed to hardcoded strings, you can check the accepted answer here.

Source