简体   繁体   中英

AWS Lambda send SMS via AWS-PHP-SDK doesn't work

Problem description:

I am unable to send SMS from AWS Lambda.

Controller Code

    try {
        $sms = AwsFacade::createClient('sns');
        $result = $sms->publish([
            'MessageAttributes' => [
                'AWS.SNS.SMS.SenderID' => [
                    'DataType' => 'String',
                    'StringValue' => 'CyQuer',
                ],
                'AWS.SNS.SMS.SMSType' => [
                    'DataType' => 'String',
                    'StringValue' => 'Transactional',
                ],
            ],
            'Message' => "Hello John Doe".PHP_EOL."Use following Code to Login:".PHP_EOL."123456",
            'PhoneNumber' => $phone,
        ]);
        Log::info($result);
    } catch (Exception $e) {
        Log::error($e->getMessage());
    }

Error message:

via web
{"message": "Internal server error"}
Task timed out after 28.00 seconds

via Artisan
Task timed out after 120.00 seconds

Setup

Laravel application running on AWS Lambda using bref/laravel-bridge
IAM user for this application has been created. Locally everything works. Online everything works too except sending SMS.

Tried solutions:

The following packages were tried.

https://github.com/aws/aws-sdk-php

https://github.com/aws/aws-sdk-php-laravel

All the following described approaches worked locally on AWS Lambda but not.
Write AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY directly into config/aws.php
Write AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY directly in the code

        $sms = AwsFacade::createClient('sns',[
            'credentials' => [
                'key'    => '********************',
                'secret' =>  '****************************************',
            ],
            'region' => env('AWS_REGION', 'eu-central-1'),
            'version' => 'latest',
            'ua_append' => [
                'L5MOD/' . AwsServiceProvider::VERSION,
            ],
        ]);

Giving all IAM users full admin access didn't work either.

Does anyone know the problem and have a solution for it? I've been trying to find a way for more than 24 hours. My last approach would be to rebuild the complete call via CURL and try it out, but I hope someone has/finds a solution.

For anyone facing similar issue, this could be/ most likely is due to lambda being configured in a VPC (most likely to give it access to RDS) and therefore losing inte.net connection, and by extension of that, access to other AWS services. One of the ways to work around this is to enable inte.net access to your VPC-bound lambda via setting up a NAT gateway (guide here ). Alternatively, you can also use VPC Endpoints if the desired AWS service is supported. More info here .

In my experience, I had issues being unable to use specific credentials for certain clients in the AWS PHP SDK. I've seen that the best solution is to include the IAM permissions needed in the policy statements for the lambda function itself.

In this case for example, you may need to include the relevant statement for SNS like below:

{
    "Action": [
        "ses:*"
    ],
    "Resource": "*",
    "Effect": "Allow"
}

If you're using serverless to deploy, you may define it under provider.iamRoleStatements in the serverless.yml file like below:

provider:
  name: aws
  iamRoleStatements:
    - Effect: Allow
      Action:
        - sns:*
      Resource: '*'

IMPORTANT: Do provide only the minimum permissions that your lambda needs. The above statements are just examples.

After the relevant permissions are applied in this way, you may drop the specific credentials from the constructor of your AWS client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM