AWS credentials on AWS Lambda
When your PHP application runs on AWS Lambda, it automatically has access to AWS credentials. This means you don't need to manage AWS access keys or credentials in your code - Lambda handles this for you.
Don't deploy AWS access keys in your Lambda functions or environment variables. Lambda provides credentials automatically.
This is a common mistake when migrating an existing application to AWS Lambda.
How it works
Lambda functions automatically get AWS access keys in their environment variables. These credentials are temporary and managed by AWS, so you don't have to worry about rotating them or keeping them secure.
echo $_SERVER['AWS_ACCESS_KEY_ID']; // AKIAIOSFODNN7EXAMPLE
echo $_SERVER['AWS_SECRET_ACCESS_KEY']; // wJalrXUtnFEM
echo $_SERVER['AWS_SESSION_TOKEN']; // AQoEXAMPLEH4aoAH0gNCAPy...
The PHP AWS SDK automatically detects and uses them. Here's an example with S3:
$s3 = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $_SERVER['AWS_REGION'],
// No credentials needed, the SDK uses the environment variables automatically
]);
// Use S3 normally
$result = $s3->putObject([
'Bucket' => 'my-bucket',
'Key' => 'file.txt',
'Body' => 'Hello from Lambda!'
]);
// Note that this also works with https://async-aws.com
Note that Laravel and Symfony automatically pick up these permissions too.
These credentials have access controlled by an IAM role defined in serverless.yml
.
By default, Lambda functions don't have any access (principle of least privilege). To access other AWS services (like S3 or SQS), you need to add permissions to that IAM role in serverless.yml
(read below).
Adding permissions
To grant your Lambda function access to AWS services, add IAM statements to your serverless.yml
:
service: my-app
provider:
name: aws
iam:
role:
statements:
# IAM statements here...
functions:
# ...
Example: S3
To read and write files to an S3 bucket:
provider:
name: aws
iam:
role:
statements:
# Allow Lambda to read and write to S3
- Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:DeleteObject
Resource: arn:aws:s3:::my-bucket/*
# Allow listing bucket contents
- Effect: Allow
Action: s3:ListBucket
Resource: arn:aws:s3:::my-bucket
If you use the Lift storage
construct to create S3 buckets, it automatically adds the necessary permissions (opens in a new tab) to your functions. No need to set up permissions manually!
Example: SQS
To send and receive messages from SQS queues:
provider:
name: aws
iam:
role:
statements:
# Allow Lambda to access an SQS queue
- Effect: Allow
Action:
- sqs:SendMessage
- sqs:ReceiveMessage
- sqs:DeleteMessage
- sqs:GetQueueAttributes
Resource: arn:aws:sqs:${aws:region}:${aws:accountId}:my-queue
If you use the Lift queue
construct to create SQS queues, it automatically adds the necessary permissions (opens in a new tab) to your functions. No need to set up permissions manually!
Common services and permissions
Here are the IAM actions you'll typically need for common AWS services:
DynamoDB
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- dynamodb:Query
- dynamodb:Scan
Resource: arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/my-table
Secrets Manager
- Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:my-secret-*
SNS (notifications)
- Effect: Allow
Action: sns:Publish
Resource: arn:aws:sns:${aws:region}:${aws:accountId}:my-topic
EventBridge
- Effect: Allow
Action: events:PutEvents
Resource: arn:aws:events:${aws:region}:${aws:accountId}:event-bus/my-event-bus
SSM Parameter Store
- Effect: Allow
Action:
- ssm:GetParameter
- ssm:GetParameters
Resource: arn:aws:ssm:${aws:region}:${aws:accountId}:parameter/my-app/*
Troubleshooting
Access Denied errors
If you get "Access Denied" errors when trying to use AWS services:
- Check that you've added the correct IAM permissions in
serverless.yml
- Verify the resource ARN is correct (bucket name, queue name, etc.)
- Make sure you've redeployed after adding permissions
- Check the logs for the exact error message
Testing locally
When testing locally remember that you will need to provide AWS credentials since you're not running on Lambda. You can set them up via long-lived AWS access keys or IAM roles with SSO.
Permissions per function
If you want to define permissions per function, instead of globally (ie: in the provider), you can install the plugin serverless-iam-roles-per-function
(opens in a new tab) and then use the iamRoleStatements
at the function definition block.