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

Support adding policy statements in function created with defineFunction() #2385

Closed
malaquf opened this issue Jan 2, 2025 · 2 comments
Closed
Labels
function Issue pertaining to Amplify Function pending-triage Incoming issues that need categorization

Comments

@malaquf
Copy link

malaquf commented Jan 2, 2025

Environment information

System:
  OS: macOS 15.1
  CPU: (10) arm64 Apple M1 Max
  Memory: 817.06 MB / 64.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 21.7.3 - /opt/homebrew/bin/node
  Yarn: 1.22.21 - /opt/homebrew/bin/yarn
  npm: 10.5.0 - /opt/homebrew/bin/npm
  pnpm: 8.14.1 - /opt/homebrew/bin/pnpm
NPM Packages:
  @aws-amplify/auth-construct: 1.5.1
  @aws-amplify/backend: 1.11.0
  @aws-amplify/backend-auth: 1.4.2
  @aws-amplify/backend-cli: 1.4.5
  @aws-amplify/backend-data: 1.3.0
  @aws-amplify/backend-deployer: 1.1.12
  @aws-amplify/backend-function: 1.10.0
  @aws-amplify/backend-output-schemas: 1.4.0
  @aws-amplify/backend-output-storage: 1.1.4
  @aws-amplify/backend-secret: 1.1.5
  @aws-amplify/backend-storage: 1.2.4
  @aws-amplify/cli-core: 1.2.1
  @aws-amplify/client-config: 1.5.4
  @aws-amplify/deployed-backend-client: 1.5.0
  @aws-amplify/form-generator: 1.0.3
  @aws-amplify/model-generator: 1.0.11
  @aws-amplify/platform-core: 1.4.0
  @aws-amplify/plugin-types: 1.6.0
  @aws-amplify/sandbox: 1.2.8
  @aws-amplify/schema-generator: 1.2.6
  aws-amplify: 6.11.0
  aws-cdk: 2.173.2
  aws-cdk-lib: 2.173.2
  typescript: 5.7.2

Describe the feature

At the moment, there's no way to customize policy statements for the role of a lambda created using defineFunction().
This is a very basic requirement.

Use case

My use case is to add a mutation for deleting user data. Therefore, I created a function using defineFunction so I can reference it in the data schema as a mutation (notice I already had to workaround the env vars by using values generated by output creating a nasty dependency with a build artifact during build time, which should also be improved):

export const deleteUserDataFunction = defineFunction({
  name: 'DeleteUserDataFunction',
  entry: '../functions/database/deleteUserData.ts',
  timeoutSeconds: 30,
  environment: {
    USERS_TABLE_NAME: amplifyOutputs.custom.USERS_TABLE_NAME,
    USER_PROGRESS_TABLE_NAME: amplifyOutputs.custom.USERPROGRESS_TABLE_NAME,
    USER_BOOKMARKS_TABLE_NAME: amplifyOutputs.custom.USERBOOKMARKS_TABLE_NAME,
  },
});

Then I have something like this in my data schena:

const schema = a.schema({
  deleteUserData: a
    .mutation()
    .returns(a.string())
    .handler(a.handler.function(deleteUserDataFunction))
    .authorization((allow) => [allow.authenticated('userPools')]),
...
}).authorization((allow) => [
  allow.resource(deleteUserDataFunction)
])

I dont want to use Amplify's API in this function for accessing data because it's inefficient for this use case, and as far as I've seen, it also involves more workarounds. We should be able to access the DB directly.

I've also tried something like this, but functions is undefined:

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

backend.data.resources.functions.deleteUserDataFunction.addToRolePolicy(
  new PolicyStatement({
    actions: ['dynamodb:DeleteItem', 'dynamodb:Scan'],
    resources: [
      backend.data.resources.tables.Users.tableArn,
      backend.data.resources.tables.UserProgress.tableArn,
      backend.data.resources.tables.UserBookmarks.tableArn
    ],
  })
);

I've tried to access it for example through backend.data.resources.functions, but functions is undefined.

@malaquf malaquf added the pending-triage Incoming issues that need categorization label Jan 2, 2025
@ykethan
Copy link
Member

ykethan commented Jan 2, 2025

Hey @malaquf, thank you for reaching out. I would suggest adding the permissions directly on the function by adding the function to defineBackend

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

backend.deleteUserDataFunction.resources.lambda.addToRolePolicy(
  new PolicyStatement({
    actions: ['dynamodb:DeleteItem', 'dynamodb:Scan'],
    resources: [
      backend.data.resources.tables.Users.tableArn,
      backend.data.resources.tables.UserProgress.tableArn,
      backend.data.resources.tables.UserBookmarks.tableArn
    ],
  })
);

further note, on the defineFunction I would also suggest adding resourceGroupName as data if you experience an circular dependency as if the function is already being used in the data access property then adding the permissions by depending on the data table may create a circular dependency.

@ykethan ykethan added pending-response Issue is pending response from author function Issue pertaining to Amplify Function labels Jan 2, 2025
@malaquf
Copy link
Author

malaquf commented Jan 7, 2025

Hi @ykethan! Thanks for your reply. Interesting... I tried the same approach with 'auth' recently and it didn't solve the circular dependency issue, but with 'data' it does work as intended!

For reference about the same issue but with 'auth':
aws-amplify/amplify-flutter#5790

I'm closing this one. Thanks!

@malaquf malaquf closed this as completed Jan 7, 2025
@github-actions github-actions bot removed the pending-response Issue is pending response from author label Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
function Issue pertaining to Amplify Function pending-triage Incoming issues that need categorization
Projects
None yet
Development

No branches or pull requests

2 participants