In my amplify (Gen2) project my basic amplify file structure is:
├── amplify
│ ├── backend.ts
│ ├── custom-functions
│ │ └── helloworld
│ │ ├── index.py
│ │ └── resource.ts
│ ├── data
│ │ └── resource.ts
│ ├── package.json
│ └── tsconfig.json
This is the file ./amplify/data/resource.ts
:
import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
import { sayHello } from "../custom-functions/helloworld/resource";
const schema = a.schema({
Procurement: a
.model({
name: a.string(),
price: a.float(),
account: a.string(),
s3AttachmentCount: a.integer(),
s3Attachments: a.string(),
comments: a.string()
})
.authorization((allow) => [allow.publicApiKey(), allow.resource(sayHello).to(['read','write','delete'])]),
});
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({
schema,
authorizationModes: {
defaultAuthorizationMode: "apiKey",
// API Key is used for a.allow.public() rules
apiKeyAuthorizationMode: {
expiresInDays: 30,
},
},
})
});
The issue is I want the lambda function to be allowed to access my data.
But the allow variable doesn't have the function resource because it is of type BaseAllowModifier
which is defined as
export type BaseAllowModifier = Omit<AllowModifier, 'resource'>;
Here is what the documentation says:
import { defineStorage } from '@aws-amplify/backend';
import { generateMonthlyReports } from '../functions/generate-monthly-reports/resource';
export const storage = defineStorage({
name: 'myReports',
access: (allow) => ({
'reports/*': [
allow.resource(generateMonthlyReports).to(['read', 'write', 'delete'])
]
})
});
I recognize defineStorage
is a different function but I am hoping there is a similar solution.
Thanks
Hey took a while but I figured out a solution. In the backend.ts file you can add iam policy statements to the lambda function.
So your backend.ts will look something like this:
import { defineBackend } from '@aws-amplify/backend';
import { data } from './data/resource';
import { sayhello } from './custom-functions/helloworld/resource';
import * as sns from "aws-cdk-lib/aws-sns"
import * as iam from "aws-cdk-lib/aws-iam"
const backend = defineBackend({
data,
sayhello,
});
// Adds the IAM role/policy for lambda to access the DynamoData
const pythonLambda = backend.sayhello.resources.lambda
const topicStack = backend.createStack("LambdaStack")
const topic = new sns.Topic(topicStack, "Topic", {
displayName: "LambdaStackTopic",
})
const statement = new iam.PolicyStatement({
sid: "AllowLambdaReadWriteDynamo",
actions: [
"dynamodb:*",
],
resources: [
topic.topicArn,
'arn:aws:ssm:eu-west-1:<SOME OTHER ACCOUNT ARN>'
]
})
pythonLambda.addToRolePolicy(statement)
```