Deploying Serverless Functions with AWS Amplify Gen 2: A Complete Guide
When deploying serverless functions with AWS Amplify Gen 2, you’ll likely encounter two main challenges. First, Amplify’s CI/CD pipeline won’t automatically pick up your functions for deployment. Then, once that’s resolved, you’ll face CDK permission issues during the build process. This guide will walk you through solving both problems.
Getting Started
First, scaffold your Amplify project using the latest version:
npm create amplify@latest
This command will set up a new Amplify Gen 2 project, but note that it won’t create the functions directory structure. You’ll need to create the amplify/functions
directory and its contents manually. You can find basic function scaffolding examples in the Amplify dashboard documentation.
Project Structure
A typical Amplify Gen 2 project with serverless functions follows this structure:
your-project/
├── amplify/
│ └── auth/
│ └── data/
│ └── functions/
│ ├── say-hello/
│ │ └── handler.ts
│ │ └── resource.ts
│ └── backend.ts
| └── package.json
| └── tsconfig.json
├── app/
│ └── package.json
└── amplify.yml
The amplify/functions
directory contains all your serverless functions, each with its own source code and configuration.
Challenge 1: Function Deployment in CI/CD
The first issue you’ll encounter is that Amplify’s CI/CD pipeline doesn’t automatically detect and deploy your functions. This happens because the default build configuration doesn’t include backend deployment steps.
Solution: Configure amplify.yml
To fix this, you need to add a backend section to your amplify.yml
. This configuration tells Amplify to build and deploy your serverless functions:
version: 1
backend:
phases:
build:
commands:
- npm ci --cache .npm --prefer-offline
- npx ampx pipeline deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
artifacts:
baseDirectory: dist
files:
- '**/*'
frontend:
phases:
build:
commands:
- npm ci --cache .npm --prefer-offline
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- .next/cache/**/*
- .npm/**/*
- node_modules/**/*
Challenge 2: CDK Permission Issues
Once your functions are being picked up by the CI/CD pipeline, you’ll hit the second challenge: CDK permission errors. This occurs because Amplify Gen 2 uses CDK under the hood to deploy functions, but creates a build role with minimal permissions by default.
The build process needs permissions to:
- Access CDK bootstrap resources
- Create and manage CloudFormation stacks
- Pass IAM roles
- Access S3 buckets for assets
- Read SSM parameters
Solution: Bootstrap CDK and Add Permissions
Step 1: Bootstrap CDK
First, bootstrap CDK in your AWS account:
cdk bootstrap aws://YOUR_ACCOUNT_ID/YOUR_REGION \
--trust YOUR_ACCOUNT_ID \
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \
--trust-for-lookup YOUR_ACCOUNT_ID
Step 2: Add Comprehensive IAM Policy
Add this comprehensive IAM policy to your Amplify build role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudformation:CreateChangeSet",
"cloudformation:DeleteChangeSet",
"cloudformation:DescribeChangeSet",
"cloudformation:ExecuteChangeSet",
"cloudformation:ListChangeSets",
"cloudformation:DescribeStacks",
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:DeleteStack",
"cloudformation:ListStacks",
"cloudformation:DescribeStackEvents",
"cloudformation:GetTemplateSummary",
"cloudformation:ValidateTemplate"
],
"Resource": [
"arn:aws:cloudformation:REGION:ACCOUNT_ID:stack/amplify-APP_ID-ENV-branch-*/*",
"arn:aws:cloudformation:REGION:ACCOUNT_ID:stack/CDKToolkit/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::cdk-hnb659fds-assets-ACCOUNT_ID-REGION",
"arn:aws:s3:::cdk-hnb659fds-assets-ACCOUNT_ID-REGION/*"
]
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": [
"arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-cfn-exec-role-ACCOUNT_ID-REGION",
"arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-deploy-role-ACCOUNT_ID-REGION",
"arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-file-publishing-role-ACCOUNT_ID-REGION"
]
},
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-deploy-role-ACCOUNT_ID-REGION",
"arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-file-publishing-role-ACCOUNT_ID-REGION"
]
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath"
],
"Resource": [
"arn:aws:ssm:REGION:ACCOUNT_ID:parameter/amplify/APP_ID/ENV/*",
"arn:aws:ssm:*:*:parameter/cdk-bootstrap/*"
]
}
]
}
Replace the following placeholders:
ACCOUNT_ID
: Your AWS account IDREGION
: Your AWS region (e.g., us-east-1)APP_ID
: Your Amplify app IDENV
: Your environment name (e.g., dev)
Why This Works
This policy grants all necessary permissions for:
- CloudFormation operations (creating/updating stacks and changesets)
- S3 access for CDK assets
- IAM role passing for CDK execution
- SSM parameter access for configuration
- Role assumption for CDK deployment
Best Practices
While this policy works, you might want to:
- Further restrict resources based on your specific needs
- Use separate roles for different environments
- Consider using AWS Organizations for better permission management
- Regularly audit and update permissions as needed
Conclusion
Deploying serverless functions with AWS Amplify Gen 2 presents two main challenges: configuring the CI/CD pipeline to recognize your functions and setting up the correct CDK permissions. By properly configuring your amplify.yml
with both frontend and backend build phases, and implementing the comprehensive IAM policy outlined above, you can successfully automate your function deployments.
With these configurations in place, you can confidently deploy serverless functions through Amplify’s CI/CD pipeline while maintaining proper security controls.