Skip to content

Commit 8882f9f

Browse files
fix(storage): update instructions for adding/integrating with external S3 buckets
1 parent 198fbfc commit 8882f9f

File tree

1 file changed

+195
-28
lines changed
  • src/pages/[platform]/build-a-backend/storage/use-with-custom-s3

1 file changed

+195
-28
lines changed

src/pages/[platform]/build-a-backend/storage/use-with-custom-s3/index.mdx

+195-28
Original file line numberDiff line numberDiff line change
@@ -44,36 +44,41 @@ To do this, go to **Amazon S3 console** > **Select the S3 bucket** > **Permissio
4444

4545
![Showing Amplify console showing Storage tab selected](/images/gen2/storage/s3-console-permissions.png)
4646

47-
The policy will look something like this
47+
The policy will look something like this:
4848

4949
```json
5050
{
51-
"Version": "2012-10-17",
52-
"Statement": [
53-
{
54-
"Sid": "Statement1",
55-
"Principal": { "AWS": "arn:aws:iam::<AWS-account-ID>:role/<role-name>" },
56-
"Effect": "Allow",
57-
"Action": [
58-
"s3:PutObject",
59-
"s3:GetObject",
60-
"s3:DeleteObject",
61-
"s3:ListBucket"
62-
],
63-
"Resource": [
64-
"arn:aws:s3:::<bucket-name>/*"
65-
]
66-
}
67-
]
51+
"Version": "2012-10-17",
52+
"Statement": [
53+
{
54+
"Sid": "Statement1",
55+
"Principal": { "AWS": "arn:aws:iam::<AWS-account-ID>:role/<role-name>" },
56+
"Effect": "Allow",
57+
"Action": [
58+
"s3:PutObject",
59+
"s3:GetObject",
60+
"s3:DeleteObject",
61+
"s3:ListBucket"
62+
],
63+
"Resource": [
64+
"arn:aws:s3:::<bucket-name>/",
65+
"arn:aws:s3:::<bucket-name>/*"
66+
]
67+
}
68+
]
6869
}
6970
```
7071
Replace `<AWS-account-ID>` with your AWS account ID and `<role-name>` with the IAM role associated with your Amplify Auth setup. Replace `<bucket-name>` with the S3 bucket name.
7172

7273
You can refer to [Amazon S3's Policies and Permissions documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-language-overview.html) for more ways to customize access to the bucket.
7374

75+
<Callout warning>
76+
In order to make calls to your S3 bucket from your application, you must also set up a CORS Policy for your S3 bucket. This applies only to manually-configured S3 buckets. Learn more about [setting up a CORS Policy for your S3 bucket](/[platform]/build-a-backend/storage/extend-s3-resources/#for-manually-configured-s3-resources).
77+
</Callout>
78+
7479
### Specify S3 bucket in Amplify's backend config
7580

76-
Next, use the `addOutput` method from the backend definition object to define a custom s3 bucket by specifying the name and region of the bucket in your **amplify/backend.ts** file.
81+
Next, use the `addOutput` method from the backend definition object to define a custom S3 bucket by specifying the name and region of the bucket in your **amplify/backend.ts** file.
7782

7883
<Callout>
7984

@@ -85,7 +90,10 @@ If you specify a custom S3 bucket, no sandbox storage resource will be created.
8590

8691
</Callout>
8792

88-
```javascript
93+
Below is an example of configuring the backend to define a custom S3 bucket:
94+
95+
{/* cSpell:disable */}
96+
```ts title="amplify/backend.ts"
8997

9098
import { defineBackend } from '@aws-amplify/backend';
9199
import { auth } from './auth/resource';
@@ -100,12 +108,119 @@ const backend = defineBackend({
100108
backend.addOutput({
101109
storage: {
102110
aws_region: "<region>",
103-
bucket_name: "<bucket-name>"
111+
bucket_name: "<bucket-name>",
112+
// optional: `buckets` can be used when setting up more than one existing bucket
113+
buckets: [
114+
{
115+
aws_region: "<region>",
116+
bucket_name: "<bucket-name>",
117+
name: "<bucket-name>",
118+
// optional: `paths` can be used to set up access to specific bucket prefixes,
119+
// and configure access to those prefixes for different user types
120+
// @ts-expect-error: Amplify backend type issue — https://github.com/aws-amplify/amplify-backend/issues/2569
121+
paths: {
122+
"public/*": {
123+
guest: ["get", "list"],
124+
authenticated: ["get", "list", "write", "delete"],
125+
},
126+
"admin/*": {
127+
groupsadmin: ["get", "list", "write", "delete"],
128+
authenticated: ["get", "list", "write", "delete"],
129+
},
130+
},
131+
}
132+
]
104133
},
105134
});
106-
//highlight-end
107135

136+
// Define an inline policy to attach to Amplify's un-auth role
137+
// This policy defines how unauthenticated users can access your existing bucket
138+
const unauthPolicy = new Policy(backend.stack, 'customBucketUnauthPolicy', {
139+
statements: [
140+
new PolicyStatement({
141+
effect: Effect.ALLOW,
142+
actions: ['s3:GetObject'],
143+
resources: [`arn:aws:s3:::${customBucketName}/public/*`],
144+
}),
145+
new PolicyStatement({
146+
effect: Effect.ALLOW,
147+
actions: ['s3:ListBucket'],
148+
resources: [`arn:aws:s3:::${customBucketName}`],
149+
conditions: {
150+
StringLike: {
151+
's3:prefix': ['public/', 'public/*'],
152+
},
153+
},
154+
}),
155+
],
156+
});
157+
158+
// Define an inline policy to attach to Amplify's auth role
159+
// This policy defines how authenticated users can access your existing bucket
160+
const authPolicy = new Policy(backend.stack, "customBucketAuthPolicy", {
161+
statements: [
162+
new PolicyStatement({
163+
effect: Effect.ALLOW,
164+
actions: ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
165+
resources: [
166+
`arn:aws:s3:::${customBucketName}/public/*`,
167+
`arn:aws:s3:::${customBucketName}/admin/*`,
168+
],
169+
}),
170+
new PolicyStatement({
171+
effect: Effect.ALLOW,
172+
actions: ["s3:ListBucket"],
173+
resources: [
174+
`arn:aws:s3:::${customBucketName}`,
175+
`arn:aws:s3:::${customBucketName}/*`,
176+
],
177+
conditions: {
178+
StringLike: {
179+
"s3:prefix": ["public/*", "public/", "admin/*", "admin/"],
180+
},
181+
},
182+
}),
183+
],
184+
});
185+
186+
// Define an inline policy to attach to Admin user group role
187+
// This policy defines how authenticated users with "admin" user group role can access your existing bucket
188+
const adminPolicy = new Policy(backend.stack, "customBucketAdminPolicy", {
189+
statements: [
190+
new PolicyStatement({
191+
effect: Effect.ALLOW,
192+
actions: ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
193+
resources: [`arn:aws:s3:::${customBucketName}/admin/*`],
194+
}),
195+
new PolicyStatement({
196+
effect: Effect.ALLOW,
197+
actions: ["s3:ListBucket"],
198+
resources: [
199+
`arn:aws:s3:::${customBucketName}`,
200+
`arn:aws:s3:::${customBucketName}/*`,
201+
],
202+
conditions: {
203+
StringLike: {
204+
"s3:prefix": ["admin/*", "admin/"],
205+
},
206+
},
207+
}),
208+
],
209+
});
210+
211+
// Add the policies to the unauthenticated user role
212+
backend.auth.resources.unauthenticatedUserIamRole.attachInlinePolicy(
213+
unauthPolicy,
214+
);
215+
216+
// Add the policies to the authenticated user role
217+
backend.auth.resources.authenticatedUserIamRole.attachInlinePolicy(authPolicy);
218+
219+
// Add the policies to the admin user group role
220+
backend.auth.resources.groups["admin"].role.attachInlinePolicy(adminPolicy);
221+
//highlight-end
108222
```
223+
{/* cSpell:enable */}
109224

110225
<InlineFilter filters={["javascript", "nextjs", "react", "angular", "vue", "react-native", "android", "swift"]}>
111226

@@ -137,7 +252,7 @@ In addition to manually configuring your storage options, you will also need to
137252
### Using Amplify configure
138253
Existing storage resource setup can be accomplished by passing the resource metadata to `Amplify.configure`. This will configure the Amplify Storage client library to interact with the additional resources. It's recommended to add the Amplify configuration step as early as possible in the application lifecycle, ideally at the root entry point.
139254

140-
255+
{/* cSpell:disable */}
141256
```ts
142257
import { Amplify } from 'aws-amplify';
143258

@@ -153,22 +268,40 @@ Amplify.configure({
153268
buckets: {
154269
'<your-default-bucket-friendly-name>': {
155270
bucketName: '<your-default-bucket-name>',
156-
region: '<your-default-bucket-region>'
271+
region: '<your-default-bucket-region>',
272+
// required: `paths` is needed to set up access to specific bucket prefixes,
273+
// and configure access to those prefixes for different user types
274+
// @ts-expect-error: Amplify backend type issue — https://github.com/aws-amplify/amplify-backend/issues/2569
275+
paths: {
276+
'public/*': {
277+
guest: ["get", "list"],
278+
authenticated: ["get", "list", "write", "delete"],
279+
},
280+
"admin/*": {
281+
groupsadmin: ["get", "list", "write", "delete"],
282+
authenticated: ["get", "list", "write", "delete"],
283+
},
284+
}
157285
},
158286
'<your-additional-bucket-friendly-name>': {
159287
bucketName: '<your-additional-bucket-name>',
160-
region: '<your-additional-bucket-region>'
288+
region: '<your-additional-bucket-region>',
289+
paths: {
290+
// add more paths for the bucket
291+
}
161292
}
162293
}
163294
}
164295
}
165296
});
166-
167297
```
298+
{/* cSpell:enable */}
299+
168300
### Using Amplify outputs
169301

170302
Alternatively, existing storage resources can be used by creating or modifying the `amplify_outputs.json` file directly.
171303

304+
{/* cSpell:disable */}
172305
```ts title="amplify_outputs.json"
173306
{
174307
"auth": {
@@ -182,15 +315,49 @@ Alternatively, existing storage resources can be used by creating or modifying t
182315
{
183316
"name": "<your-default-bucket-friendly-name>",
184317
"bucket_name": "<your-default-bucket-name>",
185-
"aws_region": "<your-default-bucket-region>"
318+
"aws_region": "<your-default-bucket-region>",
319+
// required: `paths` is needed to set up access to specific bucket prefixes,
320+
// and configure access to those prefixes for different user types
321+
"paths": {
322+
"public/*": {
323+
"guest": [
324+
"get",
325+
"list"
326+
],
327+
"authenticated": [
328+
"get",
329+
"list",
330+
"write",
331+
"delete"
332+
]
333+
},
334+
"admin/*": {
335+
"authenticated": [
336+
"get",
337+
"list",
338+
"write",
339+
"delete"
340+
],
341+
"groupsadmin": [
342+
"get",
343+
"list",
344+
"write",
345+
"delete"
346+
]
347+
}
348+
}
186349
},
187350
{
188351
"name": "<your-additional-bucket-friendly-name>",
189352
"bucket_name": "<your-additional-bucket-name>",
190-
"aws_region": "<your-additional-bucket-region>"
353+
"aws_region": "<your-additional-bucket-region>",
354+
"paths": {
355+
// add more paths for the bucket
356+
}
191357
}
192358
]
193359
}
194360
}
195361
```
362+
{/* cSpell:enable */}
196363
</InlineFilter>

0 commit comments

Comments
 (0)