Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Multi bucket support #1742

Merged
merged 102 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
f48bb2d
feat: init multi-bucket support
0618 Jul 11, 2024
3c49e6f
refactor: BackendOutput type
0618 Jul 11, 2024
a3baa32
update package-lock
0618 Jul 11, 2024
b1f2c85
temp
0618 Jul 12, 2024
c20f71d
feat: update schema and client_config
0618 Jul 13, 2024
df34ec0
feat: increment schema and client_config versions to 1.1
0618 Jul 13, 2024
ed78564
rename to buckets and remove friendlyName
0618 Jul 13, 2024
8b365c1
chore: add changeset
0618 Jul 13, 2024
423f6ba
chore: update API.md
0618 Jul 14, 2024
2ab396b
fix: remove duplicated code
0618 Jul 15, 2024
87f2fd9
fix: construct test
0618 Jul 15, 2024
0bf1075
feat: validate isDefault
0618 Jul 16, 2024
9d28f1a
chore: remove as any
0618 Jul 16, 2024
4b1a471
test: fix client_config_contributor
0618 Jul 16, 2024
421fd59
Merge branch 'main' into multi-bucket-support
0618 Jul 16, 2024
9c27c2c
chore: update package-lock
0618 Jul 16, 2024
17cae19
fix: getOutput
0618 Jul 16, 2024
85130e3
refactor: backend_output_client
0618 Jul 17, 2024
8729889
refactor: DefaultBackendOutputClient
0618 Jul 17, 2024
0913ad5
Merge branch 'main' into multi-bucket-support
0618 Jul 17, 2024
62b2a36
Merge branch 'main' into multi-bucket-support
0618 Jul 17, 2024
e8548cf
revert changes on addBackendOutputEntry, use appendToBackendOutputList
0618 Jul 17, 2024
bc4d412
update JSdocs for construct
0618 Jul 17, 2024
f6a1c12
make storageOutput more specific
0618 Jul 18, 2024
cddcd97
add factoryCounter and hasDefault
0618 Jul 18, 2024
2c03a6d
use factoryCounter as postfix
0618 Jul 18, 2024
3c1c486
update changeset
0618 Jul 18, 2024
77df31d
Merge branch 'main' into multi-bucket-support
0618 Jul 18, 2024
9739169
fix: buckets output schema
0618 Jul 18, 2024
ea59529
feat: add name to buckets
0618 Jul 18, 2024
1b08c09
feat: throw no isdefault error before deploy
0618 Jul 18, 2024
107bcf9
chore: remove post-deploy error
0618 Jul 19, 2024
2f932ec
refactor: use factoryCounter for policy
0618 Jul 19, 2024
d67854e
refactor: pass buckets to appendToBackendOutputList
0618 Jul 19, 2024
4dc5553
Merge branch 'main' into multi-bucket-support
0618 Jul 19, 2024
bacfe86
remove StorageOutputPayloadToStore
0618 Jul 19, 2024
14ddd73
fix construct test
0618 Jul 19, 2024
cb21531
revert BackendOutput type
0618 Jul 19, 2024
b776969
chore: update changeset
0618 Jul 19, 2024
0ded8f7
fix: client_config_contributer_v1 and test
0618 Jul 19, 2024
c1b09b4
fix: pin api-extractor to 7.40.0
0618 Jul 19, 2024
8079d28
chore: update API.md
0618 Jul 19, 2024
ec113d0
refactor: use global factoryCounter for policy
0618 Jul 20, 2024
3380bd9
refactor: use addBackendOutputEntry for default
0618 Jul 22, 2024
92c6299
test: fix storage construct test
0618 Jul 22, 2024
88ea17d
this works
sobolk Jul 22, 2024
96bc326
move DeepPartial
0618 Jul 22, 2024
07194c3
remove StorageBucketsPayload
0618 Jul 22, 2024
50ebda5
refactor: use Aspects to validate storage
0618 Jul 23, 2024
6ced7be
fix: add buckets to metadata
0618 Jul 23, 2024
98567de
fix: factory unit test
0618 Jul 23, 2024
036862b
fix: metadata_output_storage_strategy unit test
0618 Jul 23, 2024
c8a36f7
fix: not export AmplifyStorage
0618 Jul 24, 2024
9843705
refactor: addOrUpdateMetadata
0618 Jul 24, 2024
35527d3
Merge branch 'main' into multi-bucket-support
0618 Jul 25, 2024
b797249
update package-lock
0618 Jul 25, 2024
7b326b6
update package-lock
0618 Jul 25, 2024
ac7e04b
Manual Merge branch 'update-package-lock' into multi-bucket-support
0618 Jul 25, 2024
5bf1cff
Update packages/backend-storage/src/factory.ts
0618 Jul 25, 2024
37f4e44
Update packages/backend-storage/src/factory.ts
0618 Jul 25, 2024
f208b87
refactor: remove redundant code in StorageClientConfigContributor
0618 Jul 25, 2024
440de9e
test: add unit tests for construct and factory
0618 Jul 26, 2024
8647309
Merge branch 'main' into multi-bucket-support
0618 Jul 26, 2024
bc33e54
fix: one bucket no default case
0618 Jul 26, 2024
e9f6859
fix: unit test
0618 Jul 27, 2024
9bc296b
Merge branch 'main' into multi-bucket-support
0618 Jul 30, 2024
4ce8db5
test log currentCodebaseOutputs and npmOutputs
0618 Jul 30, 2024
cba6cec
fix: convert bucketName, storageRegion into bucket_name, aws_region
0618 Jul 30, 2024
5429861
fix: client_config_contributor_v1.test
0618 Jul 30, 2024
3a2dd2b
refactor: use Aspect to replact factory static
0618 Jul 31, 2024
865b947
fix: buckets keys
0618 Jul 31, 2024
ca0d12d
fix: unit test
0618 Jul 31, 2024
cff7306
fix MultipleDefaultBucketError and add more unit tests
0618 Jul 31, 2024
db34c50
remove policyCount static
0618 Aug 1, 2024
98414b0
Update packages/backend-storage/src/factory.ts
0618 Aug 1, 2024
99b483f
refactor StorageValidator
0618 Aug 1, 2024
179a1bb
Refactor: storeOutput to factory
0618 Aug 2, 2024
16999af
Merge branch 'main' into multi-bucket-support
0618 Aug 2, 2024
084bd2c
remove comment
0618 Aug 2, 2024
9cde018
Update packages/backend-storage/src/factory.ts
0618 Aug 5, 2024
3473440
Update packages/backend-storage/src/factory.ts
0618 Aug 5, 2024
d9bb2c2
Update packages/backend-storage/src/factory.ts
0618 Aug 5, 2024
53db426
Update packages/backend-storage/src/construct.ts
0618 Aug 5, 2024
5792d10
Revert "test log currentCodebaseOutputs and npmOutputs"
0618 Aug 5, 2024
cf0d456
rename defaultStorageFound
0618 Aug 5, 2024
0e07a9f
Merge branch 'main' into multi-bucket-support
0618 Aug 5, 2024
436df66
remove firstStorage from getInstance
0618 Aug 5, 2024
3fffaba
rename buckets to storage, and fix unit tests
0618 Aug 5, 2024
cb7cb4f
use isStorageProcessed
0618 Aug 5, 2024
e042ab1
fix construct test
0618 Aug 5, 2024
87a35ca
fix StackMetadataBackendOutputStorageStrategy unit test
0618 Aug 5, 2024
336a517
fix a typo to make lint happy
0618 Aug 6, 2024
9ade76a
Update packages/backend-storage/src/factory.ts
0618 Aug 6, 2024
f0d993e
Update packages/client-config/src/client-config-contributor/client_co…
0618 Aug 6, 2024
f27e98b
fix type error in client_config_contributer_v1
0618 Aug 6, 2024
e329d26
refactor: use early return
0618 Aug 6, 2024
a66fe37
test: fix test name
0618 Aug 6, 2024
0940ed6
refactor: move Aspects to another file
0618 Aug 6, 2024
1a7f095
refactor: remove this.node
0618 Aug 6, 2024
13f20cf
Update packages/backend-storage/src/storage_outputs_aspect.ts
0618 Aug 6, 2024
a825efe
add isMatch to match outputs
0618 Aug 6, 2024
079fd73
add unit test for aspects
0618 Aug 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/yellow-bats-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@aws-amplify/deployed-backend-client': minor
'@aws-amplify/backend-output-schemas': minor
'@aws-amplify/backend-output-storage': minor
'@aws-amplify/backend-storage': minor
'@aws-amplify/client-config': minor
'@aws-amplify/plugin-types': minor
---

add support for multi-buckets
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions packages/backend-output-schemas/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,24 +275,29 @@ export const unifiedBackendOutputSchema: z.ZodObject<{
payload: z.ZodObject<{
bucketName: z.ZodString;
storageRegion: z.ZodString;
buckets: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodString>, "many">>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why typing for buckets is different here than in other places ?

additionally. should we use records here or should be come up with subtype with named properties? (this applies to all buckets introduced in this file)

Copy link
Contributor Author

@0618 0618 Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done d67854e

}, "strip", z.ZodTypeAny, {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
}, {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
}>;
}, "strip", z.ZodTypeAny, {
version: "1";
payload: {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
};
}, {
version: "1";
payload: {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
};
}>]>>;
"AWS::Amplify::Custom": z.ZodOptional<z.ZodDiscriminatedUnion<"version", [z.ZodObject<{
Expand Down Expand Up @@ -391,6 +396,7 @@ export const unifiedBackendOutputSchema: z.ZodObject<{
payload: {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
};
} | undefined;
"AWS::Amplify::Function"?: {
Expand Down Expand Up @@ -455,6 +461,7 @@ export const unifiedBackendOutputSchema: z.ZodObject<{
payload: {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
};
} | undefined;
"AWS::Amplify::Function"?: {
Expand Down Expand Up @@ -684,24 +691,29 @@ export const versionedStorageOutputSchema: z.ZodDiscriminatedUnion<"version", [z
payload: z.ZodObject<{
bucketName: z.ZodString;
storageRegion: z.ZodString;
buckets: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodString>, "many">>;
}, "strip", z.ZodTypeAny, {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
}, {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
}>;
}, "strip", z.ZodTypeAny, {
version: "1";
payload: {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
};
}, {
version: "1";
payload: {
bucketName: string;
storageRegion: string;
buckets?: Record<string, string>[] | undefined;
};
}>]>;

Expand Down
3 changes: 3 additions & 0 deletions packages/backend-output-schemas/src/storage/v1.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { z } from 'zod';

const bucketSchema = z.record(z.string(), z.string());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we type this stronger as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done d67854e


export const storageOutputSchema = z.object({
version: z.literal('1'),
payload: z.object({
bucketName: z.string(),
storageRegion: z.string(),
buckets: z.array(bucketSchema).optional(),
}),
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,19 @@ export class StackMetadataBackendOutputStorageStrategy
new CfnOutput(this.stack, key, { value });
});

const metadataValue =
this.stack.templateOptions.metadata &&
this.stack.templateOptions.metadata[keyName]
? this.stack.templateOptions.metadata[keyName]
: { stackOutputs: [] };

this.stack.addMetadata(keyName, {
...metadataValue,
version: backendOutputEntry.version,
stackOutputs: Object.keys(backendOutputEntry.payload),
stackOutputs: [
...metadataValue.stackOutputs,
...Object.keys(backendOutputEntry.payload),
],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain this change?

Edit: after reading rest of the code I'm guessing this is to solve a problem of "multiple defineStorage contributing to same stack metadata/output key".
I was facing similar problem in the POC I was building for custom client config. This wasn't merged as final approach was different but you might find it useful for this PR, see #946 (comment) (i.e. addBackendOutputEntry and logic around it).

Copy link
Contributor

@rtpascual rtpascual Jul 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we maybe use appendToBackendOutputList (see here) to lazily append multiple buckets to the same output key similar to what is done for functions? See here where we are lazily adding function names to a list as they are synthesized.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point @rtpascual! I somehow didn't see appendToBackendOutputList in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done e8548cf

});
};

Expand Down
7 changes: 5 additions & 2 deletions packages/backend-storage/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { IBucket } from 'aws-cdk-lib/aws-s3';
import { ResourceAccessAcceptor } from '@aws-amplify/plugin-types';
import { ResourceAccessAcceptorFactory } from '@aws-amplify/plugin-types';
import { ResourceProvider } from '@aws-amplify/plugin-types';
import { StorageOutput } from '@aws-amplify/backend-output-schemas';

// @public (undocumented)
export type AmplifyStorageFactoryProps = Omit<AmplifyStorageProps, 'outputStorageStrategy'> & {
Expand All @@ -23,9 +22,13 @@ export type AmplifyStorageFactoryProps = Omit<AmplifyStorageProps, 'outputStorag

// @public (undocumented)
export type AmplifyStorageProps = {
isDefault?: boolean;
name: string;
versioned?: boolean;
outputStorageStrategy?: BackendOutputStorageStrategy<StorageOutput>;
outputStorageStrategy?: BackendOutputStorageStrategy<{
version: '1';
payload: Record<string, string>;
}>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change?
Shouldn't we change StorageOutput type ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StorageOutput is from schema, which is the final output, but the initial output we stored in stack metadata is different, so I introduced a new type, StorageOutputToStore in a new commit f6a1c12

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See how the new commit f6a1c12 looks?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why do we need type StorageOutputToStore .

Auth and Functions are just using their respective outputs, see:

outputStorageStrategy: BackendOutputStorageStrategy<AuthOutput> = new StackMetadataBackendOutputStorageStrategy(

and
private readonly outputStorageStrategy: BackendOutputStorageStrategy<FunctionOutput>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StorageOutput is from schema

StorageOutput is a shape that we store in CFN metadata/outputs. This is not related to client config schemas - that translation happens when client config package reads stacks and transforms it to amplify outputs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There would be some mis-match after CfnOutput sending the output (code), then the output we get from CFN would be like the following

{
 version: "1",
 payload: {
   name: [..., ..., ...],
   bucketName: [..., ..., ...],
   storageRegion: [..., ..., ...],
 }
}

So we need to change the type, and modify the output when parsing to amplify_outputs.json (code).

Is there a way to avoid the change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tl;dr -- When we store output, we store the individual bucket (code) (which has name, bucketName, and storageRegion), but when generate the amplify_outputs.json, we also need to add buckets, and remove name etc. So, there are two different storageOutput .

There might be a way to avoid the complex, and I missed it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way we should evolve this is
Change

export const storageOutputSchema = z.object({
  version: z.literal('1'),
  payload: z.object({
    bucketName: z.string(),
    storageRegion: z.string(),
  }),
});

To

export const storageOutputSchema = z.object({
  version: z.literal('1'),
  payload: z.object({
    bucketName: z.string(),
    storageRegion: z.string(),
    buckets: z.string(), // JSON array as string (serialized buckets, like in functions output), this should likely be optional.
  }),
});

And then in order for this to be backwards compatible we should populate bucketName and storageRegion with the one that's 'isDefault = true'.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then use this trick

outputStorageStrategy.appendToBackendOutputList(functionOutputKey, {
version: '1',
payload: {
definedFunctions: this.resources.lambda.functionName,
},
});
to append to buckets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done d67854e

triggers?: Partial<Record<AmplifyStorageTriggerEvent, ConstructFactory<ResourceProvider<FunctionResources>>>>;
};

Expand Down
19 changes: 15 additions & 4 deletions packages/backend-storage/src/construct.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, it, mock } from 'node:test';
import { AmplifyStorage } from './construct.js';
import { App, Stack } from 'aws-cdk-lib';
import { Capture, Template } from 'aws-cdk-lib/assertions';
import { Capture, Match, Template } from 'aws-cdk-lib/assertions';
import {
BackendOutputEntry,
BackendOutputStorageStrategy,
Expand Down Expand Up @@ -131,14 +131,22 @@ void describe('AmplifyStorage', () => {

const storeOutputArgs = storeOutputMock.mock.calls[0].arguments;
assert.strictEqual(storeOutputArgs.length, 2);
const bucketName = Object.entries(storeOutputArgs[1].payload).filter(
([key]) => key.includes('bucketName')
)[0][0];
const storageRegion = Object.entries(storeOutputArgs[1].payload).filter(
([key]) => key.includes('storageRegion')
)[0][0];
assert.equal(storeOutputArgs[0], storageOutputKey);
assert.equal(storeOutputArgs[1].version, '1');

assert.deepStrictEqual(storeOutputArgs, [
storageOutputKey,
{
version: '1',
payload: {
bucketName: expectedBucketName,
storageRegion: expectedRegion,
[bucketName]: expectedBucketName,
[storageRegion]: expectedRegion,
},
},
]);
Expand All @@ -153,7 +161,10 @@ void describe('AmplifyStorage', () => {
Metadata: {
[storageOutputKey]: {
version: '1',
stackOutputs: ['storageRegion', 'bucketName'],
stackOutputs: [
Match.stringLikeRegexp('storageRegion*'),
Match.stringLikeRegexp('bucketName*'),
],
},
},
});
Expand Down
34 changes: 23 additions & 11 deletions packages/backend-storage/src/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ import {
FunctionResources,
ResourceProvider,
} from '@aws-amplify/plugin-types';
import {
StorageOutput,
storageOutputKey,
} from '@aws-amplify/backend-output-schemas';
import { storageOutputKey } from '@aws-amplify/backend-output-schemas';
import { RemovalPolicy, Stack } from 'aws-cdk-lib';
import {
AttributionMetadataStorage,
Expand All @@ -32,6 +29,11 @@ const storageStackType = 'storage-S3';
export type AmplifyStorageTriggerEvent = 'onDelete' | 'onUpload';

export type AmplifyStorageProps = {
/**
* Whether this storage resource is the default storage resource for the backend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: also add some wording here explaining that it's required if there are multiple storage definitions in the backend

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done
bc4d412

* @default false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the default true? ie if I just have one storage instance and I don't define this field, then it's the default

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I don't know if the default should be true or false because it's conditional. If there's only one bucket, then it's true. If multiple buckets, it's false. Maybe I should update the JSdoc to clarify the conditions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done
bc4d412

*/
isDefault?: boolean;
/**
* Friendly name that will be used to derive the S3 Bucket name
*/
Expand All @@ -42,7 +44,10 @@ export type AmplifyStorageProps = {
* @default false
*/
versioned?: boolean;
outputStorageStrategy?: BackendOutputStorageStrategy<StorageOutput>;
outputStorageStrategy?: BackendOutputStorageStrategy<{
version: '1';
payload: Record<string, string>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @sobolk had a similar comment elsewhere, but we should keep this strongly typed, even if that means updating the type

}>;
/**
* S3 event trigger configuration
* @see https://docs.amplify.aws/gen2/build-a-backend/storage/#configure-storage-triggers
Expand Down Expand Up @@ -122,7 +127,7 @@ export class AmplifyStorage
},
};

this.storeOutput(props.outputStorageStrategy);
this.storeOutput(props.outputStorageStrategy, props.isDefault || false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.storeOutput(props.outputStorageStrategy, props.isDefault || false);
this.storeOutput(props.outputStorageStrategy, props.isDefault ?? false);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isDefault can't be 0 or "" since it's set to be boolean type, so I think || is appropriate here. Even if it was 0 or "", I think we can assume it means false.


new AttributionMetadataStorage().storeAttributionMetadata(
Stack.of(this),
Expand All @@ -146,15 +151,22 @@ export class AmplifyStorage
* Store storage outputs using provided strategy
*/
private storeOutput = (
outputStorageStrategy: BackendOutputStorageStrategy<StorageOutput> = new StackMetadataBackendOutputStorageStrategy(
Stack.of(this)
)
outputStorageStrategy: BackendOutputStorageStrategy<{
version: '1';
payload: Record<string, string>;
}> = new StackMetadataBackendOutputStorageStrategy(Stack.of(this)),
isDefault: boolean = false
): void => {
/* The following code can guarantee there's only one `isDefault`
* because if we can only create one construct with the same `storageRegion` and `bucketName` name.
* The default bucket takes the `storageRegion` and `bucketName` name without a number post-fix.
*/
const num = isDefault ? '' : Math.floor(Math.random() * 100);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't use random generator here. This will cause re-deployments of storage as outputs are going to change every time impacting performance (e.g. this will cause sandbox never hotswapping).
Instead of this we should either apply consistent hashing OR have global counter for storage instances.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Yea, I'm looking for some suggestions to replace the random generator. I'll try those.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do the same thing that we do for auth and data:

keep a static counter in the factory class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done cddcd97

outputStorageStrategy.addBackendOutputEntry(storageOutputKey, {
version: '1',
payload: {
storageRegion: Stack.of(this).region,
bucketName: this.resources.bucket.bucketName,
[`storageRegion${num}`]: Stack.of(this).region,
[`bucketName${num}`]: this.resources.bucket.bucketName,
0618 marked this conversation as resolved.
Show resolved Hide resolved
},
});
};
Expand Down
12 changes: 9 additions & 3 deletions packages/backend-storage/src/storage_access_policy_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,15 @@ export class StorageAccessPolicyFactory {
});
}

return new Policy(this.stack, `${this.namePrefix}${this.policyCount++}`, {
0618 marked this conversation as resolved.
Show resolved Hide resolved
statements,
});
return new Policy(
this.stack,
`${this.bucket.bucketName.slice(0, 6)}${Math.floor(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, this needs consistent hashing or global counter.

Copy link
Contributor Author

@0618 0618 Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 2f932ec

Copy link
Contributor Author

@0618 0618 Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • need to revisit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Using global counter ec113d0

Math.random() * 1000
)}`,
{
statements,
}
);
};

private getStatement = (
Expand Down
14 changes: 13 additions & 1 deletion packages/client-config/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ interface AmazonLocationServiceConfig {
// @public
type AmazonPinpointChannels = 'IN_APP_MESSAGING' | 'FCM' | 'APNS' | 'EMAIL' | 'SMS';

// @public (undocumented)
interface AmplifyStorageBucket {
// (undocumented)
aws_region: string;
// (undocumented)
bucket_name: string;
// (undocumented)
name: string;
}

// @public (undocumented)
export type AnalyticsClientConfig = {
aws_mobile_analytics_app_id?: string;
Expand Down Expand Up @@ -135,6 +145,7 @@ interface AWSAmplifyBackendOutputs {
storage?: {
aws_region: AwsRegion;
bucket_name: string;
buckets?: AmplifyStorageBucket[];
};
version: '1';
}
Expand Down Expand Up @@ -180,7 +191,8 @@ declare namespace clientConfigTypesV1 {
AwsAppsyncAuthorizationType,
AmazonPinpointChannels,
AWSAmplifyBackendOutputs,
AmazonLocationServiceConfig
AmazonLocationServiceConfig,
AmplifyStorageBucket
}
}
export { clientConfigTypesV1 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {
clientConfigTypesV1,
} from '../client-config-types/client_config.js';
import { ModelIntrospectionSchemaAdapter } from '../model_introspection_schema_adapter.js';
import { AwsAppsyncAuthorizationType } from '../client-config-schema/client_config_v1.js';
import {
AmplifyStorageBucket,
AwsAppsyncAuthorizationType,
} from '../client-config-schema/client_config_v1.1.js';

// All categories client config contributors are included here to mildly enforce them using
// the same schema (version and other types)
Expand Down Expand Up @@ -254,6 +257,8 @@ export class StorageClientConfigContributor implements ClientConfigContributor {
config.storage = {
aws_region: storageOutput.payload.storageRegion,
bucket_name: storageOutput.payload.bucketName,
buckets: storageOutput.payload
.buckets as unknown as AmplifyStorageBucket[],
};

return config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ export interface AWSAmplifyBackendOutputs {
storage?: {
aws_region: AwsRegion;
bucket_name: string;
buckets?: AmplifyStorageBucket[];
};
/**
* Outputs generated from backend.addOutput({ custom: <config> })
Expand All @@ -238,3 +239,8 @@ export interface AmazonLocationServiceConfig {
*/
style?: string;
}
export interface AmplifyStorageBucket {
name: string;
bucket_name: string;
aws_region: string;
}
Loading
Loading