AWS dynamodb - connection to my local dynamodb and create the table - php

I am in need of an AWS dynamodb as the backend for my project.. I have already completed the below tasks:
established jar for dynamodb local server to start listening
downloaded PHP SDK from AWS
created an iam user from AWS console and copied the credentials.ini file into .aws folder
Executed the php script to connect my local dynamodb and create the table.
After all those tasks have been completed, localhost gives me a message stating the 'table created'. However am not able to find my table in the AWS console. What could be the problem?.
Am I doing it correctly? .. can someone please shed some light on this?
Here's my connection through PHP:
$client = new Aws\Sdk([
//'profile' => 'default',
'region' => 'us-west-2',
'version' => 'latest',
'endpoint' => 'http://localhost:8000',
'credentials' => [
'key' => '',
'secret' => '']
]);

Firstly, when you are using local host, the table would be created in your local machine (i.e. not in AWS). You have mentioned AWS console, I understood that as you are looking for the table on "AWS Management Console". When you use endpoint as "http://localhost:8000", the API will never interact with actual AWS.
It refers to the local dynamodb instance.
To check the table on local dynamodb instance:-
1) If you have AWS CLI installed on your system, you can check the existence of the table using below command.
aws dynamodb describe-table --table-name yourTableName --endpoint-url http://localhost:8000
2) Otherwise, go to http://localhost:8000/shell/
var docClient = new AWS.DynamoDB({
region: 'us-east-1',
endpoint: "http://localhost:8000"
});
var params = {TableName:'yourTableName'};
docClient.describeTable(params, function(err, data) {
if (err) {
console.log(err, err.stack);
} else {
console.log(data);
// php.var_dump(data);
}
});
If table exists:-
It will show the definition of the table
If table doesn't exists:-
You will get the below error message.
"message":"Cannot do operations on a non-existent table"

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)

AWS dynamodb query from php

I have a react application and i'm trying to use aws dynamodb, i installed the php sdk but i don't know how to query my db.
I copied the tutorial here and i changed the endpoint to: "https://dynamodb.us-west-2.amazonaws.com".
I get this error: {"__type":"com.amazon.coral.service#UnrecognizedClientException","message":"The security token included in the request is invalid."}. I guess i have to add a security token somewhere, i don't know where and neither where to find it.
Any suggestion?
Based on your error, i think you need to check your aws secret key and access key. You can try to install aws cli then create user access programmatically from aws console from this link
Then you can try your source code after that.
The following code example shows how to get an item from a DynamoDB table.
// '/path/to/aws-autoloader.php' to import AWS SDKs.
require 'vendor/autoload.php';
use Aws\DynamoDb\DynamoDbClient;
use Aws\Exception\AwsException;
use Aws\DynamoDb\Exception\DynamoDbException;
// Create an SDK class used to share configuration across clients.
$sdk = new Aws\Sdk([
'region' => 'us-west-2',
'version' => 'latest'
]);
// Use an Aws\Sdk class to create the dynamoDbClient object.
$dynamoDbClient = $sdk->createDynamoDb();
try {
$dynamoDbClient->getItem([
'Key' => [
'id' => [
'N' => 1,
],
],
'TableName' => 'products',
]);
} catch (DynamoDbException $e) {
// Catch a DynamoDb-specific exception.
echo $e->getMessage();
} catch (AwsException $e) {
// This catches the more generic AwsException. You can grab information
// from the exception using methods of the exception object.
echo $e->getAwsRequestId() . "\n";
echo $e->getAwsErrorType() . "\n";
echo $e->getAwsErrorCode() . "\n";
// This dumps any modeled response data, if supported by the service
// Specific members can be accessed directly (e.g. $e['MemberName'])
var_dump($e->toArray());
}
Notice that we did not explicitly provide credentials to the client. That’s because the SDK should detect the credentials from environment variables (via AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY), an AWS credentials INI file in your HOME directory, AWS Identity and Access Management (IAM) instance profile credentials, or credential providers.
If we don’t provide a credentials option, the SDK attempts to load credentials from your environment in the following order:
Load credentials from environment variables.
Load credentials from a credentials .ini file.
Load credentials from IAM role.
We can also directly create the service-specific client object like below:
$dynamoDbClient = new DynamoDbClient(
[
'region' => 'us-west-2',
'version' => 'latest',
]
But AWS highly recommended that you use the Sdk class to create clients if you’re using multiple client instances in your application. As per AWS docs:-
The Sdk class automatically uses the same HTTP client for each SDK
client, allowing SDK clients for different services to perform
nonblocking HTTP requests. If the SDK clients don’t use the same
HTTP client, then HTTP requests sent by the SDK client might block
promise orchestration between services.
You can refer to the AWS document pages:-
AWS SDK PHP - BASIC USAGE
AWS SDK PHP - DynamoDB Examples
AWS SDK PHP - Configuration guide
AWS SDK PHP - APIs
I hope this helps.

Error retrieving credentials from the instance profile metadata server error in AWS SDK

I am developing an web application using PHP. I am storing the user credentials on the AWS Cognito service. I am logging in the user to the Cognito using PHP SDK.
I developed the feature successfully. I tested it locally on my machine, it was working. Then I deployed it onto the staging server, it was working on the staging server as well. But when I deployed it on to the live server, it gave me this error:
(1/1) CredentialsException
Error retrieving credentials from the instance profile metadata server. (cURL error 7: Failed to connect to 169.254.169.254 port 80: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html))
This is my code
try{
$client = new CognitoIdentityProviderClient([
'version' => 'latest',
'region' => 'eu-west-2'// env('AWS_REGION', '')
]);
$result = $client->adminInitiateAuth([
'AuthFlow' => 'ADMIN_NO_SRP_AUTH',
'ClientId' => COGNITO_APP_CLIENT_ID,
'UserPoolId' => COGNITO_USER_POOL_ID,
'AuthParameters' => [
'USERNAME' => $request->email,
'PASSWORD' => $request->password,
],
]);
$auth_result = $result->get('AuthenticationResult');
$cognito_access_token = $auth_result['AccessToken'];
if(!empty($cognito_access_token))
{
//register the user
$reg_user = $this->accRepo->register($request);
if($reg_user)
{
Auth::login($reg_user);
$token = $reg_user->createToken($this->tokenTag)->accessToken;
unset($reg_user->password);
return response()->json([ 'success' => true, 'access_token' => $token, 'account' => $reg_user ], SUCCESS_RESPONSE_CODE);
}
}
}
catch(Exception $e)
{
}
I am using the exact code and setting and credentials as the local machine and the staging server for the live server. But it does not work on the live server. Working on the other environments. What might be the error? I am deploying it on Heroku.
I am not familiar with Cognito, but the error you're seeing is that your code is attempting to access the Instance Metadata available in EC2. The AWS PHP SDK has a specific order in which it attempts to locate credentials. Here is an outline of different credential methods using the PHP SDK.
So, I suspect it works on your local machine because you have an IAM profile configured using the AWS CLI aws configure command.
It most likely works on your staging server because that server has an IAM Role attached to the EC2 instance. The PHP doesn't find a locally configured IAM profile, so it then skips to attempting to access the EC2 metadata, which it does successfully, so it gets authenticated.
Now, when you deploy to Heroku, it is no longer on an EC2 instance, or in your local environment. So, your CredentialProvider fails. My suggestion would be to utilize Config Vars in Heroku, then change your code to use CredentialProvider::env() as outlined here. You would need to create an IAM user with the same role as your EC2 instance that works (or enough permissions to do what you need to do). This would allow your application to securely access Cognito from an environment external to AWS.

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.

Amazon SES version field

I've migrated servers and updated AWS phar, however once i've done that i'm getting the following error:
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Missing required client configuration options: 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 "email": * "2010-12-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.' in phar:////includes/3rdparty/aws/aws.phar/Aws/ in phar:////includes/3rdparty/aws/aws.phar/Aws/ClientResolver.php on line 328
I've tried adding it via different method and looking into the actual documentation without any luck.
Here's my code right now:
$client = SesClient::factory(array(
'user' => 'uuuuu',
'key' => 'aaaaa',
'secret' => 'bbbb',
'region' => 'us-east-1',
));
$client->version("2010-12-01");
//Now that you have the client ready, you can build the message
$msg = array();
//more code after this...
Any help would be appreciated!
Apparenty, the 'version' field is mandatory now, so you must pass it to the factory.
Source: http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/migration.html
// Instantiate the client with your AWS credentials
$client = SqsClient::factory(array(
'credentials' => $credentials,
'region' => 'us-east-1',
'version' => '2012-11-05'
));

Categories