A feature I think everyone (including myself!) should use more is AWS Serverless Application Model (SAM) policy templates. This approach is a great example of "syntactic sugar" that characterises the AWS SAM approach.
As an example, a frequent requirement for your serverless application functions is to create, read, update, and delete items on a DyanmoDB table. Rather than give in to the temptation to give your function access to all actions on all tables, you can use the aptly-named DynamoDBCrudPolicy
template that takes a TableName
parameter:
MyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Handler: hello.handler
Runtime: nodejs18.x
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref TableName
These two lines of YAML then gets transformed in to a detailed IAM policy statement that restricts the access to the appropriate IAM actions on the specific DDB table resource:
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:DeleteItem",
"dynamodb:PutItem",
"dynamodb:Scan",
"dynamodb:Query",
"dynamodb:UpdateItem",
"dynamodb:BatchWriteItem",
"dynamodb:BatchGetItem",
"dynamodb:DescribeTable",
"dynamodb:ConditionCheckItem"
],
"Resource": [
{
"Fn::Sub": [
"arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}",
{
"tableName": {
"Ref": "TableName"
}
}
]
},
{
"Fn::Sub": [
"arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}/index/*",
{
"tableName": {
"Ref": "TableName"
}
}
]
}
]
}
]
This approach is quick, clean, and consistent, while avoiding a lot of accidental errors that can creep in to a more complicated policy definition.
You can see a full list of the all the policy templates in the official documentation, and the docs include how to submit your own policy templates.