I'm using AWS SAM to provision API Gateway, Lambda functions, and an RDS database. I'd like to automate schema changes with a tool such as Alembic, but the database is in a private subnet and I don't want to maintain an EC2 instance solely for running migrations. What's the best way to execute migrations securely as part of deployment, possibly through CI/CD or a serverless component?
3 Answers
You don’t need an EC2 host for this. Since your SAM Lambdas can run inside the VPC and reach the database, package Alembic and the required database driver into a migration Lambda. Invoke it once per deployment, either through a deployment step or a CloudFormation custom resource. Make sure the function uses the right private subnets, security groups, secrets, and network access.
You can also use a database proxy or another controlled connection layer if the migration runner needs a stable address or connection management. Whichever approach you choose, treat migrations as a separate deployment step, prevent multiple migration jobs from running at once, and test both forward and rollback migrations carefully. A serverless migration function is convenient, but rollback planning is still your responsibility.
A CI/CD job is another good option. The job doesn’t need a permanent server—you can use an ephemeral runner or a managed build service, configure it with access to the VPC, install your migration dependencies, and run Alembic after the infrastructure update. This keeps schema changes in the deployment pipeline while avoiding an always-on EC2 instance.
The important part is that the build environment must actually be able to route to the private RDS endpoint. Simply running the command in a public CI worker won’t work unless you provide private network connectivity.

That makes sense. I was assuming the migration runner had to be a long-lived server, but a one-time Lambda invocation should work if it has the same VPC access.