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

Accessing graphql api via custom lambda function #2996

Closed
jayarerita opened this issue Oct 31, 2024 · 5 comments
Closed

Accessing graphql api via custom lambda function #2996

jayarerita opened this issue Oct 31, 2024 · 5 comments
Assignees
Labels
data-schema Gen 2 pending-community-response Issue is pending a response from the author or community. question Further information is requested

Comments

@jayarerita
Copy link

Amplify CLI Version

Amplify Gen 2 ampx v1.0.4

Question

I have a lambda function which is listening to dynamodb events for one of my tables. Below is a basic example of how my table and function are defined in my backend.ts file.

const backend = defineBackend({
  auth,
  data,
  storage
});
const tableA =  backend.data.resources.tables["TableA"];

const functionA= new LambdaFunction(backend.storage.resources.bucket.stack, 'FunctionA', {
  runtime: LambdaRuntime.NODEJS_20_X,
  handler: 'index.handler',
  code: lambdaCodeFromAssetHelper(
    path.resolve('amplify/functions/function-a/handler.ts'),
    { buildMode: BuildMode.Esbuild }
  ),
  logRetention: RetentionDays.ONE_WEEK,
  timeout: Duration.seconds(120)
});

functionA.addEnvironment("TABLE_A_NAME", tableA.tableName);

const functionAdbPolicy = new PolicyStatement({
  actions: [
    "dynamodb:UpdateItem",
    "dynamodb:GetItem",
  ],
  resources: [
    aTable.tableArn
  ],
});

functionA.addToRolePolicy(functionAdbPolicy);

const functionAStreamsPolicy = new PolicyStatement({
  effect: Effect.ALLOW,
  actions: [
    "dynamodb:DescribeStream",
    "dynamodb:GetRecords",
    "dynamodb:GetShardIterator",
    "dynamodb:ListStreams",
  ],
  resources: [
    Fn.sub("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${TableName}/stream/*", {
      TableName: tableA.tableName,
    })  ],
});

functionA.addToRolePolicy(functionAStreamsPolicy);

const functionAMapping = new EventSourceMapping(functionStack, "FunctionATableAEventStreamMapping", {
  target: functionA,
  eventSourceArn: tableA.tableStreamArn,
  startingPosition: StartingPosition.LATEST,
});

In the docs you are instructed to add your defined lambda functions as allow.resource(functionWithDataAccess) on the data schema.

I assume this adds permissions, which I can do via cdk, but also provides some key env variables like env.<amplifyData>_GRAPHQL_ENDPOINT and env.AWS_ACCESS_KEY_ID which seem to be needed to configure the amplify data client and perform operations on the graphql api.

It looks like I might be able to access the endpoint url via backend.data.graphqlUrl, but I am not sure where I can get access to the authorization values.

@chrisbonifacio
Copy link
Member

chrisbonifacio commented Nov 25, 2024

Hi @jayarerita can you confirm that the environment variables are not being added to the Lambda in the AWS Console?

Can you also share the schema?

@chrisbonifacio chrisbonifacio added the pending-community-response Issue is pending a response from the author or community. label Nov 25, 2024
@jayarerita
Copy link
Author

@chrisbonifacio I can confirm that the function does not have any of these environment variables in the lambda function in the console.

The data.resource schema does not seem consequential. I can share a simple example though....

import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
import { postConfirmation } from "../auth/post-confirmation/resource";

const schema = a
    .schema({
      TableA: a
        .model({
          id: a.id().required(),
          title: a.string(),
          description: a.string(),
          owner: a.string(),
        })
        .authorization((allow) =>[
          allow.owner(),
        ]),
      UserProfile: a.model({
        name: a.string(),
        email: a.string().required(),
        role: a.enum(["user", "admin"]),
        profileOwner: a.string(),
        id: a.id().required(),
      })
      .authorization((allow) => [
        allow.ownerDefinedIn("profileOwner"),
      ]),
  })
  .authorization((allow) => ([
    allow.resource(postConfirmation),
  ]))


export type Schema = ClientSchema<typeof schema>;

export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: "apiKey",
    apiKeyAuthorizationMode: {
      expiresInDays: 30,
    },
  },
});

@github-actions github-actions bot added pending-maintainer-response Issue is pending a response from the Amplify team. and removed pending-community-response Issue is pending a response from the author or community. labels Dec 2, 2024
@chrisbonifacio
Copy link
Member

chrisbonifacio commented Dec 9, 2024

Hi @jayarerita apologies for the delay. I was not able to reproduce the issue but I'm curious if you tried adding the graphql url as an environment variable through CDK as you did with the table name. That could serve as a workaround until we figure out why allow.resource didn't work in this instance.

This might be due to the lambda not having been created by defineFunction().

This part of the AWS docs may be helpful:

https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-lambda.html

It seems like a workaround would be to provide the permissions via the addToRolePolicy function and access the IAM credentials using a function like fromEnv().

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/#fromenv

Also, if you haven't already, please upgrade to the latest versions of @aws-amplify/backend and @aws-amplify/backend-cli

you can also upgrade the @aws-amplify/data-schema package by running:

npm update @aws-amplify/data-schema

@chrisbonifacio chrisbonifacio added pending-community-response Issue is pending a response from the author or community. and removed investigating pending-maintainer-response Issue is pending a response from the Amplify team. labels Dec 9, 2024
@chrisbonifacio
Copy link
Member

Hi 👋 Closing this as we have not heard back from you. If you are still experiencing this issue and in need of assistance, please feel free to comment and provide us with any information previously requested by our team members so we can re-open this issue and be better able to assist you.

Thank you!

@chrisbonifacio chrisbonifacio closed this as not planned Won't fix, can't repro, duplicate, stale Dec 16, 2024
Copy link

This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data-schema Gen 2 pending-community-response Issue is pending a response from the author or community. question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants