Skip to content

Commit dd7d5cc

Browse files
authored
Merge pull request #1985 from brefphp/docs-aws-credentials
Add a documentation page for AWS credentials
2 parents 44f0f4e + 605b1db commit dd7d5cc

File tree

5 files changed

+195
-31
lines changed

5 files changed

+195
-31
lines changed

docs/environment/_meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
"database-public": {
1010
"display": "hidden"
1111
},
12+
"aws-credentials": "AWS credentials",
1213
"performances": "Performance"
1314
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import { NextSeo } from 'next-seo';
2+
import { Callout, Tabs } from 'nextra/components';
3+
4+
<NextSeo description="Access other AWS services from AWS Lambda by using the built-in AWS credentials." />
5+
6+
# AWS credentials on AWS Lambda
7+
8+
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.
9+
10+
<Callout type="warning">
11+
Don't deploy AWS access keys in your Lambda functions or environment variables. Lambda provides credentials automatically.
12+
13+
This is a common mistake **when migrating an existing application to AWS Lambda**.
14+
</Callout>
15+
16+
## How it works
17+
18+
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.
19+
20+
```php
21+
echo $_SERVER['AWS_ACCESS_KEY_ID']; // AKIAIOSFODNN7EXAMPLE
22+
echo $_SERVER['AWS_SECRET_ACCESS_KEY']; // wJalrXUtnFEM
23+
echo $_SERVER['AWS_SESSION_TOKEN']; // AQoEXAMPLEH4aoAH0gNCAPy...
24+
```
25+
26+
The PHP AWS SDK automatically detects and uses them. Here's an example with S3:
27+
28+
```php
29+
$s3 = new \Aws\S3\S3Client([
30+
'version' => 'latest',
31+
'region' => $_SERVER['AWS_REGION'],
32+
// No credentials needed, the SDK uses the environment variables automatically
33+
]);
34+
35+
// Use S3 normally
36+
$result = $s3->putObject([
37+
'Bucket' => 'my-bucket',
38+
'Key' => 'file.txt',
39+
'Body' => 'Hello from Lambda!'
40+
]);
41+
42+
// Note that this also works with https://async-aws.com
43+
```
44+
45+
Note that **Laravel and Symfony automatically pick up these permissions** too.
46+
47+
These credentials have access controlled by an IAM role defined in `serverless.yml`.
48+
49+
<Callout type="info">
50+
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).
51+
</Callout>
52+
53+
## Adding permissions
54+
55+
To grant your Lambda function access to AWS services, add IAM statements to your `serverless.yml`:
56+
57+
```yaml
58+
service: my-app
59+
60+
provider:
61+
name: aws
62+
iam:
63+
role:
64+
statements:
65+
# IAM statements here...
66+
67+
functions:
68+
# ...
69+
```
70+
71+
### Example: S3
72+
73+
To read and write files to an S3 bucket:
74+
75+
```yaml
76+
provider:
77+
name: aws
78+
iam:
79+
role:
80+
statements:
81+
# Allow Lambda to read and write to S3
82+
- Effect: Allow
83+
Action:
84+
- s3:GetObject
85+
- s3:PutObject
86+
- s3:DeleteObject
87+
Resource: arn:aws:s3:::my-bucket/*
88+
# Allow listing bucket contents
89+
- Effect: Allow
90+
Action: s3:ListBucket
91+
Resource: arn:aws:s3:::my-bucket
92+
```
93+
94+
<Callout>
95+
If you use the [Lift `storage` construct](./storage.mdx#s3-storage) to create S3 buckets, it [automatically adds the necessary permissions](https://github.com/getlift/lift/blob/master/docs/storage.md#permissions) to your functions. No need to set up permissions manually!
96+
</Callout>
97+
98+
### Example: SQS
99+
100+
To send and receive messages from SQS queues:
101+
102+
```yaml
103+
provider:
104+
name: aws
105+
iam:
106+
role:
107+
statements:
108+
# Allow Lambda to access an SQS queue
109+
- Effect: Allow
110+
Action:
111+
- sqs:SendMessage
112+
- sqs:ReceiveMessage
113+
- sqs:DeleteMessage
114+
- sqs:GetQueueAttributes
115+
Resource: arn:aws:sqs:${aws:region}:${aws:accountId}:my-queue
116+
```
117+
118+
<Callout>
119+
If you use the [Lift `queue` construct](../use-cases/sqs.mdx#creating-sqs-queues) to create SQS queues, it [automatically adds the necessary permissions](https://github.com/getlift/lift/blob/master/docs/queue.md#permissions) to your functions. No need to set up permissions manually!
120+
</Callout>
121+
122+
## Common services and permissions
123+
124+
Here are the IAM actions you'll typically need for common AWS services:
125+
126+
### DynamoDB
127+
```yaml
128+
- Effect: Allow
129+
Action:
130+
- dynamodb:GetItem
131+
- dynamodb:PutItem
132+
- dynamodb:UpdateItem
133+
- dynamodb:DeleteItem
134+
- dynamodb:Query
135+
- dynamodb:Scan
136+
Resource: arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/my-table
137+
```
138+
139+
### Secrets Manager
140+
```yaml
141+
- Effect: Allow
142+
Action: secretsmanager:GetSecretValue
143+
Resource: arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:my-secret-*
144+
```
145+
146+
### SNS (notifications)
147+
```yaml
148+
- Effect: Allow
149+
Action: sns:Publish
150+
Resource: arn:aws:sns:${aws:region}:${aws:accountId}:my-topic
151+
```
152+
153+
### EventBridge
154+
```yaml
155+
- Effect: Allow
156+
Action: events:PutEvents
157+
Resource: arn:aws:events:${aws:region}:${aws:accountId}:event-bus/my-event-bus
158+
```
159+
160+
### SSM Parameter Store
161+
```yaml
162+
- Effect: Allow
163+
Action:
164+
- ssm:GetParameter
165+
- ssm:GetParameters
166+
Resource: arn:aws:ssm:${aws:region}:${aws:accountId}:parameter/my-app/*
167+
```
168+
169+
## Troubleshooting
170+
171+
### Access Denied errors
172+
173+
If you get "Access Denied" errors when trying to use AWS services:
174+
175+
1. Check that you've added the correct IAM permissions in `serverless.yml`
176+
2. Verify the resource ARN is correct (bucket name, queue name, etc.)
177+
3. Make sure you've redeployed after adding permissions
178+
4. [Check the logs](./logs.mdx) for the exact error message
179+
180+
### Testing locally
181+
182+
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.
183+
184+
## Permissions per function
185+
186+
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`](https://github.com/functionalone/serverless-iam-roles-per-function) and then use the `iamRoleStatements` at the function definition block.
187+
188+
## Learn more
189+
190+
- [`serverless.yml` IAM guide](https://github.com/oss-serverless/serverless/blob/main/docs/guides/iam.md)
191+
- [Documentation of the AWS SDK for PHP](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/)

docs/environment/database-public.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ introduction: Configure RDS to expose a RDS database publicly so that you can ac
1212

1313
A secure alternative is to set up an SSH tunnel instead, for example **[using 7777](https://port7777.com/?utm_source=bref)**.
1414

15-
## Limitations
16-
17-
Aurora Serverless databases cannot be made publicly accessible.
18-
1915
## How to
2016

2117
Open the RDS instance in the [RDS console](https://console.aws.amazon.com/rds/home#databases:):

docs/environment/serverless-yml.mdx

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -148,33 +148,9 @@ Note that it is possible to mix PHP functions with functions written in other la
148148

149149
### Permissions
150150

151-
If your lambda needs to access other AWS services (S3, SQS, SNS…), you will need to add the proper permissions via the [`iam.role.statements` section](https://serverless.com/framework/docs/providers/aws/guide/functions#permissions):
151+
If your lambda needs to access other AWS services (S3, SQS, SNS…), you will need to add the proper permissions via the `iam.role.statements` section.
152152

153-
```yaml
154-
provider:
155-
name: aws
156-
timeout: 10
157-
runtime: provided.al2
158-
iam:
159-
role:
160-
statements:
161-
# Allow to put a file in the `my-bucket` S3 bucket
162-
- Effect: Allow
163-
Action: s3:PutObject
164-
Resource: 'arn:aws:s3:::my-bucket/*'
165-
# Allow to query and update the `example` DynamoDB table
166-
- Effect: Allow
167-
Action:
168-
- dynamodb:Query
169-
- dynamodb:Scan
170-
- dynamodb:GetItem
171-
- dynamodb:PutItem
172-
- dynamodb:UpdateItem
173-
- dynamodb:DeleteItem
174-
Resource: 'arn:aws:dynamodb:us-east-1:111110002222:table/example'
175-
```
176-
177-
If you only want to define some permissions **per function**, instead of globally (ie: in the provider), you should install and enable the Serverless plugin [`serverless-iam-roles-per-function`](https://github.com/functionalone/serverless-iam-roles-per-function) and then use the `iamRoleStatements` at the function definition block.
153+
Read more about [AWS credentials in the documentation](./aws-credentials.mdx).
178154

179155
## Stage parameters
180156

docs/environment/storage.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ constructs:
4242
type: storage
4343
```
4444
45-
Read more <a href="https://github.com/getlift/lift/blob/master/docs/storage.md">in the Lift documentation</a>.
45+
Read more [in the Lift documentation](https://github.com/getlift/lift/blob/master/docs/storage.md).
4646
4747
## Application cache
4848

0 commit comments

Comments
 (0)