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

edit override docs #6615

Merged
merged 3 commits into from
Dec 8, 2023
Merged
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export const meta = {
title: 'Overriding resources',
description:
'Learn how to override resources.'
description: 'Learn how to override resources.'
};

export function getStaticProps(context) {
Expand All @@ -13,82 +12,148 @@ export function getStaticProps(context) {

}

When defining resources you can access some underlying AWS CDK construct props to modify resource configurations.
<Callout warning>

## Customize Cognito UserPool email verification settings
Using overrides may cause you to create a backend that the Amplify libraries or client config is unable to interpret properly. Always test changes in a staging environment.

```ts title="amplify/auth/resource.ts"
import { defineAuth } from "@aws-amplify/backend";
</Callout>

export const auth = defineAuth({
loginWith: {
email: {
verificationEmailStyle: "CODE",
verificationEmailBody: (code: string) =>
`Welcome! Your verification code is ${code}.`,
verificationEmailSubject: "Welcome! Here is your verification code",
},
},
When defining resources you can access some underlying [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html) construct properties to modify resource configurations. This allows you to customize backend resources beyond what is offered via the `define*` functions.

Overrides are defined in the `amplify/backend.ts` file after the `defineBackend` call has been made.

```ts title="amplify/backend.ts"
// amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';

const backend = defineBackend({
auth,
data
});

// overrides go here
```

The `backend` object exposes a `resources` property with objects for each of the components passed into the `defineBackend` function. Each of these resource objects exposes underlying L1 and L2 CDK Constructs that you can modify.

For example, here is how you can access the Cognito UserPool that is created by `defineAuth` and set a custom removal policy on the resource.

```ts title="amplify/backend.ts"
// amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { UserPool } from 'aws-cdk-lib/aws-cognito';
import { RemovalPolicy } from 'aws-cdk-lib';

const backend = defineBackend({
auth
});

const userPool = backend.resources.auth.resources.userPool as UserPool;
userPool.applyRemovalPolicy(RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE);
```

Alternatively you can mutate the synthesized CDK constructs directly after setting them on your `backend`:
Most L1 and L2 CDK Constructs that are used by the `define*` functions are accessible in this way.

## Example - Grant access permissions between resources

<Callout info>

**Under active development**: We are actively working to improve the experience of granting one resource access to another. For the time being, overrides can be used to achieve this.

## Override Cognito UserPool password policies
</Callout>

Consider the case that we want to grant a function created by `defineFunction` access to call the Cognito UserPool created by `defineAuth`. This can be accomplished with the following overrides.

```ts title="amplify/backend.ts"
import { Backend } from '@aws-amplify/backend';
// amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { demoFunction } from './functions/demo-function/resource';
import { UserPool } from 'aws-cdk-lib/aws-cognito';
import { Function } from 'aws-cdk-lib/aws-lambda';

const backend = new Backend({
const backend = defineBackend({
auth,
data,
demoFunction
});

const userPool = backend.resources.auth.resources.userPool as UserPool;
const lambdaFunction = backend.resources.demoFunction.resources
.lambda as Function;

// grant the lambdaFunction read access to users
userPool.grant(lambdaFunction, 'cognito:GetUser', 'cognito:ListUsers');

// pass the Lambda the UserPool ID so that the Lambda can use it to make SDK calls
lambdaFunction.addEnvironment('USER_POOL_ID', userPool.userPoolId);
```

## Example - Mutate synthesized CloudFormation

It's possible to reach all the way down to the raw CloudFormation to mutate properties using `addPropertyOverride` on a CDK Construct. To edit the password policies of the Cognito UserPool in `defineAuth`, you can use the following code.

```ts
// amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';

const backend = defineBackend({
auth
});

// override userpool password policies
backend.resources.auth.resources.cfnResources.cfnUserPool.addPropertyOverride(
"Policies",
'Policies',
{
PasswordPolicy: {
MinimumLength: 10,
RequireLowercase: true,
RequireNumbers: true,
RequireSymbols: true,
RequireUppercase: true,
TemporaryPasswordValidityDays: 20,
},
TemporaryPasswordValidityDays: 20
}
}
);
```

Note the usage of `auth.resources.cfnResources`. This property exposes [L1 CDK Constructs](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html#constructs_l1_using). These are constructs that map 1:1 with the underlying CloudFormation properties.

Below are additional example scenarios where you may want to override resources.

The `auth.resources.cfnResources.cfnUserPool` property in the above example directly maps to the [AWS::Cognito::UserPool CloudFormation resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html).

## Add tags to resources
This is different than `auth.resources.userPool` in the first example which is an [L2 CDK Construct](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html#constructs_using). These are constructs that provide a convenient interface around several related L1 constructs.

### Amplify Data's underlying GraphQL API
## Example - Add tags to resources

```ts title="amplify/backend.ts"
import { defineBackend } from "@aws-amplify/backend";
import { auth } from "./auth/resource.js";
import { data } from "./data/resource.js";
// amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
edwardfoyle marked this conversation as resolved.
Show resolved Hide resolved
import { auth } from './auth/resource';
import { data } from './data/resource';

const backend = defineBackend({
auth,
data,
data
});

backend.resources.data.resources.cfnResources.cfnGraphqlApi.addPropertyOverride(
"Tags",
'Tags',
[
{
Key: "graphqlapi-tag-1",
Value: "graphql-tag-value-1",
Key: 'graphqlapi-tag-1',
Value: 'graphql-tag-value-1'
},
{
Key: "graphqlapi-tag-2",
Value: "graphql-tag-value-2",
},
Key: 'graphqlapi-tag-2',
Value: 'graphql-tag-value-2'
}
]
);
```

For even more customization of your backend, see [custom resources](/gen2/build-a-backend/add-aws-services/custom-resources)
Loading