DEV Community

Cover image for Migrate EC2-Classic RDS to a VPC - Step 2 - DNS
bright inventions
bright inventions

Posted on • Originally published at miensol.pl

3 3

Migrate EC2-Classic RDS to a VPC - Step 2 - DNS

In the plan blog post I sketched a plan to migrate an EC2-Classic RDS database to a VPC. Now we can perform the 2nd step of the plan. This is a simple step. Albeit, we have to understand what are the consequences. In your case, this approach might need adjustments!

The RDS endpoint DNS

When you create an RDS database instance or RDS database cluster AWS provides you with endpoint addresses. The addresses can be used to connect to the database. You cannot change the endpoint address of the RDS database. It is something generated by AWS that you have no influence over.

As planned we want to update the DNS entry when migrating to VPC based RDS instance. For this to work, we need a custom DNS entry. One that we can control.

Private hosted zone

Often, when deploying services inside a VPC it makes sense to use a private DNS hosted zone. Such an approach allows us to define e.g.internal DNS space which we can freely use. With AWS-CDK defining such hosted zone is simple:

class NetworkStack extends Stack {
  readonly privateHostedZone: IPrivateHostedZone
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const vpc = new Vpc(this, 'vpc', {
      ...
    })

    this.privateHostedZone = new PrivateHostedZone(this, 'internal', {
      vpc: vpc,
      zoneName: 'internal',
      comment: 'private DNS space for registering services'
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Custom DNS record for database endpoint

Now that we have a private hosted zone we can define a custom DNS record for the database. The record should be used to connect to the database from our service(s). This way once we change the record the application will establish connections to a new database running inside VPC.

new CnameRecord(this, 'database cname record', {
  domainName: 'current-classical-database-endpoint',
  zone: this.privateHostedZone,
  recordName: 'database'
})
Enter fullscreen mode Exit fullscreen mode

With the above configuration deployed all that is left to do is to update our service configuration. The database hostname that we set should now look like database.internal. Please note that we are still connected to the non-VPC, classical RDS instance.

Important considerations

The approach that we have selected is simple. However, it is not without downsides. The main issue is that the DNS update will not immediately cause all services to connect to the new database. In many cases this is fine. Moreover, we need to make sure that our database clients do not cache DNS entries for too long.

If you need the connections to be moved to a new database instance in a more controllable fashion it is still possible. A deployment with an update of the database configuration of services might be enough. If such a deployment is not an option we can introduce a network proxy e.g. using a network load balancer, ProxySQL or HAProxy.

By Piotr Mionskowski, Team Leader, Technology Evangelist @ Bright Inventions

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →