How to start an AWS Ec2 instance via https using PHP? - php

I'm using the AWS SDK for PHP version 2 to start and stop an Ec2 instance.
How can i set the Ec2Client object (or what method should i choose) to use an https connection instead of http?
Can someone help me?
Thanks.

Is it not already using an https connection by default?
You can set the EC2 client to use either http or https using the "scheme" option when instantiating the client.
$client = Aws\Ec2\Ec2Client::factory(array(
'key' => '<aws access key>',
'secret' => '<aws secret key>',
'region' => '<region name>',
'scheme' => 'https',
));

Related

Error when calling AWS Lambda from PHP script hosted on Apache but can from same script run directly

I have a PHP (8.1.8) page hosted on Apache (2.4) on a Windows Server 2019 EC2 instance in AWS. It attempts to send an event to a Lambda Function. The page is called with HTTP, not HTTPS (don't ask - required for external calling system).
If I run the script in VSCode (for example) it works fine and I get a response from the Lambda Function (so I believe the EC2 instance has no problem talking to the Lambda Function). However if I request the page through a browser I get an error (XXXXX represents my Lambda Function name, obfuscated):
Fatal error: Uncaught exception 'Aws\Lambda\Exception\LambdaException' with message 'Error executing "Invoke" on "https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/XXXXX/invocations"; AWS HTTP error: Connection refused for URI https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/XXXXX/invocations' GuzzleHttp\Exception\ConnectException: Connection refused for URI https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/XXXXX/invocations in C:\Apache24\htdocs\vendor\guzzlehttp\guzzle\src\Handler\StreamHandler.php:328
The script is:
<?php
require 'vendor/autoload.php';
use Aws\Credentials\Credentials;
use Aws\Lambda\LambdaClient;
$data = 'TEST PAYLOAD';
$array_obj = array("xml" => $data);
$json_obj = json_encode($array_obj);
$credentials = new Aws\Credentials\Credentials('<<KEY>>', '<<SECRET>>');
$client = new Aws\Lambda\LambdaClient([
'version' => 'latest',
'region' => 'eu-west-1',
'credentials' => $credentials,
'debug' => false,
]);
$lambda_result = $client->invoke([
'FunctionName' => 'XXXXX',
'InvocationType' => 'RequestResponse',
'LogType' => 'None',
'Payload' => $json_obj,
]);
print_r(json_decode($lambda_result->get('Payload')->getContents(), true))
?>
I'm pretty sure I'm just missing some config that will allow the web page script to call the Lambda, but I'm drawing a blank searching around for an answer.
EDIT:
Edited to clarify that this is running on a Windows Server 2019 EC2 instance, and the page is called with HTTP, not HTTPS.
EDIT 2:
I get the same issue with SQS, so its not a Lambda thing specifically. Seems to be generally about accessing AWS resources through the SDK APIs? (Tags adjusted accordingly)

Cannot pull SQS message from my EC2 instance

When I deploy my application to a EC2 instance, it fails to fetch messages from my SQS queue. And instead throws an exception with the status code 403 Forbidden, access to the resource {sqs queue} is denied. However, when I run the same code from my local environment my application can fetch messages from the SQS queue.
My application uses the symfony framework and passes pre-configured AWS credentials, for a user who has access to this queue, from the parameters.yml into \Aws\Sqs\SqsClient().
If on the EC2 instance I run aws configure and configure the aws cli with the same credentials the application can pull messages from the SQS queue. I am concerned here because it is like the aws sdk is overriding the credentials I pass it.
As a example the following code even with hard coded parameters which I have checked are valid credentials, returns a 403 when ran on a EC2 instances.
$sqs = new \Aws\Sqs\SqsClient([
[
'key' => '{my key}',
'secret' => '{my secret}'
],
'region' => 'us-east-1',
'version' => 'latest'
]);
$response = $sqs->receiveMessage([
'QueueUrl' => 'https://sqs.us-east-1.amazonaws.com/{my account}/{my queue}'
]);
Does anyone have any suggestions about what may be happening here?
Try with credentials key in config.
$sqs = new \Aws\Sqs\SqsClient([
'credentials' => [
'key' => '{my key}',
'secret' => '{my secret}',
],
'region' => 'us-east-1',
'version' => 'latest'
]);
$response = $sqs->receiveMessage([
'QueueUrl' => 'https://sqs.us-east-1.amazonaws.com/{my accoun}/{my queue}'
]);
This might help you to debug your issue.
Run aws sqs list-queues on command line. If your queue not listed in the result set, that means your AWS key doesn't have permission.
Run aws sqs receive-message --queue-url <queue_url> where queue_url is your queue's complete url received from step 1. You should see all your messages in the queue.
If there are no errors in above both steps, there might be an issue in your application end.
It's a bad practice to store AWS credentials in EC2 instances, It's much better to create an IAM role with sqs:receiveMessage permission then attach that IAM role to your EC2 instance.

Missing required client configuration options: region

I am trying to check bucket existence on Amazon S3 using below code:
$credentials = new Aws\Common\Credentials\Credentials($creds['access_key_id'], $creds['secret_access_key']);
$client = Aws\S3\S3Client::factory(array( 'credentials' => $credentials ) );
if( ! $client->doesBucketExist($creds['bucket']) ) {
throw new Exception("Bucket (" . $creds['bucket'] . ") does not exist.");
}
It is working on localhost (wamp) but when I tried this on server it is not working. I am getting following error:
Missing required client configuration options: region: (string) A "region" configuration value is required for the "s3" service (e.g., "us-west-2"). A list of available public regions and endpoints can be found at http://docs.aws.amazon.com/general/latest/gr/rande.html. version: (string) A "version" configuration value is required. Specifying a version constraint ensures that your code will not be affected by a breaking change made to the service. For example, when using Amazon S3, you can lock your API version to "2006-03-01". Your build of the SDK has the following version(s) of "s3": * "2006-03-01" You may provide "latest" to the "version" configuration value to utilize the most recent available API version that your client's API provider can find. Note: Using 'latest' in a production application is not recommended. A list of available API versions can be found on each client's API documentation page: http://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html. If you are unable to load a specific API version, then you may need to update your copy of the SDK.
I don't know why it is not working on server but same code is working on localhost.
I had the same problem and I needed to clear my config cache to fix it.
$ artisan config:clear
Set region explicitly when creating s3 client instead of relying on defaults.
use Aws\Credentials\Credentials;
use Aws\S3\S3Client;
$result = $stsClient->getSessionToken();
$credentials = new Credentials(
$result['Credentials']['AccessKeyId'],
$result['Credentials']['SecretAccessKey'],
$result['Credentials']['SessionToken']
);
$s3Client = new S3Client([
'version' => '2006-03-01',
'region' => 'us-west-2',
'credentials' => $credentials
]);
Check .env file variables are matching with filesystems.php
's3' => [
'driver' => 's3',
'key' => env('S3_KEY'),
'secret' => env('S3_SECRET'),
'region' => env('S3_REGION'),
'bucket' => env('S3_BUCKET'),
],
1) Ensure you have S3_KEY, S3_SECRET, S3_REGION, S3_BUCKET etc configured in your .env file
2) Your environment file might have changed after the autoload/caches were generated. Run:
php artisan config:cache

How can I set a timeout in SNS publish method?

I'm using the AWS SNS service in my PHP application to send messages to a queue.
If internet connection is down, the application should keep running without writing the messages. But the method that publish messages on the queue has a very long timeout, it makes the application unusable without internet.
I didn't found any place in AWS SDK where I could set a smaller timeout.
Is there some way to do this?
Here is an example of the construct of the snsClient object.
I've edit the params to use http timeout as #Anthony Neace told, I also try to use request.options connect_timeout as I found here http://docs.aws.amazon.com/aws-sdk-php/v2/guide/configuration.html
I've changed the gateway of my PC to simulate when the internet is down and I got the exception [curl] 28: Resolving timed out after 3000 milliseconds https://sns.sa-east-1.amazonaws.com/
use Aws\Sns\SnsClient;
SnsClient::factory([
'version' => '...',
'region' => '...',
'credentials' => [
'key' => '...',
'secret' => '...',
],
'http' => [
'timeout' => 5
],
'request.options' => [
'connect_timeout' => 5
]
]);
You can set a timeout in your client's constructor. This will apply to all requests you make with that client, including SnsClient Publish.
Here's an example from the documentation, modified to use SnsClient:
use Aws\Sns\SnsClient;
// Timeout after 5 seconds.
$client = new SnsClient([
'region' => 'us-west-2',
'version' => 'latest',
'http' => [
'timeout' => 5
]
]);
Further Reading:
AWS SDK for PHP - AWSClient Constructor (SnsClient inherits this constructor)
AWS SDK for PHP - SnsClient
AWS SDK for PHP - Client Configuration Options - Timeout

Amazon SNS not working

I have imported 'aws-autoloader.php' and used AWS-SDK php library
$sns = SnsClient::factory(array('key' => "******",
'secret' => "*******",
'region' => "us-east-1"));
But I cant able to get any responds. I already used this key and secret in AWS S3 but here its not working help me regarding this.

Categories