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 ID
  • REGION: Your AWS region (e.g., us-east-1)
  • APP_ID: Your Amplify app ID
  • ENV: Your environment name (e.g., dev)

Why This Works

This policy grants all necessary permissions for:

  1. CloudFormation operations (creating/updating stacks and changesets)
  2. S3 access for CDK assets
  3. IAM role passing for CDK execution
  4. SSM parameter access for configuration
  5. Role assumption for CDK deployment

Best Practices

While this policy works, you might want to:

  1. Further restrict resources based on your specific needs
  2. Use separate roles for different environments
  3. Consider using AWS Organizations for better permission management
  4. 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.