<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daniel Chapman [AWS]</title>
    <description>The latest articles on DEV Community by Daniel Chapman [AWS] (@danielthomaschapman).</description>
    <link>https://dev.to/danielthomaschapman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2129544%2Fb4ede9bc-b69d-4395-be16-a8203a7227f2.JPG</url>
      <title>DEV Community: Daniel Chapman [AWS]</title>
      <link>https://dev.to/danielthomaschapman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danielthomaschapman"/>
    <language>en</language>
    <item>
      <title>Minimising PostgreSQL RDS minor &amp; major upgrade time with Blue/Green deployments</title>
      <dc:creator>Daniel Chapman [AWS]</dc:creator>
      <pubDate>Thu, 17 Oct 2024 13:41:10 +0000</pubDate>
      <link>https://dev.to/aws-builders/minimising-postgresql-rds-minor-major-upgrade-time-with-bluegreen-deployments-1m2</link>
      <guid>https://dev.to/aws-builders/minimising-postgresql-rds-minor-major-upgrade-time-with-bluegreen-deployments-1m2</guid>
      <description>&lt;p&gt;In this blog I am going show you how you can minimise downtime when performing minor/major engine upgrades using &lt;a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html" rel="noopener noreferrer"&gt;blue/green&lt;/a&gt; deployments.&lt;/p&gt;

&lt;p&gt;This blog post assumes that you are familiar with the RDS service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Blue/Green?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blue/Green is a deployment technique where you create two separate environments. They are identical and replicate one another, you have your current application running against the "Blue" environment and the "Green" environment can be used to perform upgrades, maintenance etc. Once you are happy you simply "switch over" allow you to run your application(s) against what was the "Green" environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why would we want to use Blue/Green?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows you to perform your minor or major RDS upgrade in-hours which reduces engineering efforts out of hours&lt;/li&gt;
&lt;li&gt;Allows you to perform time consuming maintenance such as vacuum or reindex without the application being connected and thus preventing any I/O related performance bottlenecks or without having to take the system offline to perform these&lt;/li&gt;
&lt;li&gt;Application upgrades could be tested on a "proper" production environment to reduce the likelihood of issues once live&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this example, my source database is running PostgreSQL 15.8 and I intend to upgrade this to PostgreSQL 16.4 with minimal downtime&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxst23x8dia96eh009hn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxst23x8dia96eh009hn.png" alt=" " width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firstly, you need to create a new custom parameter group for the new engine version (if you are performing a major upgrade)&lt;/p&gt;

&lt;p&gt;In my example I have created a PostgreSQL 16 RDS parameter group&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7r0ye9hpyspfxry4y332.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7r0ye9hpyspfxry4y332.png" alt=" " width="779" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI can also be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; aws rds create-db-parameter-group \ 
--db-parameter-group-name rds-postgresql-v16 \
--db-parameter-group-family postgres16 \ 
--description rds-postgresql-v16 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is for you to enable &lt;strong&gt;logical_replication&lt;/strong&gt; on both the source/target parameter group. The target parameter group will be the one you have just created and the source will be what the RDS instance is currently using&lt;/p&gt;

&lt;p&gt;The CLI can be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws rds modify-db-parameter-group \
--db-parameter-group-name rds-postgresql-v16 \
--parameters ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot 

aws rds modify-db-parameter-group \
--db-parameter-group-name rds-postgresql-v15 \
--parameters ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will then have to reboot the source RDS instance if this parameter was not already set, as its a static parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws rds reboot-db-instance \
--db-instance-identifier rds-postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is for you to create a Blue/Green configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tey11pb1vsxdn4jsr4l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tey11pb1vsxdn4jsr4l.png" alt=" " width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Accept the limitations:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qc2kp1yafhv2h4owv9t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qc2kp1yafhv2h4owv9t.png" alt=" " width="670" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can opt to create the deployment using the same engine version as the source instance, or specify a new engine version. In this example I am selecting the same as the source and I'll perform the upgrade manually&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqzxsjvmffz3lwhvtoon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqzxsjvmffz3lwhvtoon.png" alt=" " width="646" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensure that you select the correct parameter group for the configuration to use and once you are happy select create&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y0zz5ap92nawimhggfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y0zz5ap92nawimhggfs.png" alt=" " width="689" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are then presented with the below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmffo1l5vh0banzcnty20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmffo1l5vh0banzcnty20.png" alt=" " width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Depending how large your dataset is, this stage could take a while to complete&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The CLI can also be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws rds create-blue-green-deployment \ 
--blue-green-deployment-name rds-postgresql-blue-green-v15-to-v16 \
--source-arn arn:aws:rds:eu-west-1:123456789:db:rds-postgresql \
--target-db-parameter-group-name rds-postgresql-v15 \
--target-db-instance-class db.m7g.large 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the deployment has created this is what you are left with:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s70nzo50f5xbgrxlm00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s70nzo50f5xbgrxlm00.png" alt=" " width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are now in a position to work on the "Green" instance, this could be maintenance such as VACUUM FULL/REINDEX or it could be an application upgrade etc.&lt;/p&gt;

&lt;p&gt;I am going to upgrade this instance to the latest version of RDS PostgreSQL &lt;/p&gt;

&lt;p&gt;From here, navigate to the modify the "Green" instance and select the new RDS engine version and the new target parameter group. Once happy, modify the instance&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdh5iwmc5nedt13xqmy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdh5iwmc5nedt13xqmy5.png" alt=" " width="750" height="806"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI can also be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws rds modify-db-instance \
--db-instance-identifier rds-postgresql-green-7fh0sf \
--engine-version 16.4 \
--db-parameter-group-name rds-postgresql-v16 \
--allow-major-version-upgrade \
--apply-immediately
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now see that the instance is now upgrading&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftid32rpn6ghk12ud65ma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftid32rpn6ghk12ud65ma.png" alt=" " width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The beauty of Blue/Green is that whilst this maintenance is occurring your application is still happily running against the Blue instance and is serving traffic as normal. &lt;br&gt;
It essentially allows you to perform the upgrade ahead of time and allows you to 'extend' any maintenance windows you may have.&lt;/p&gt;

&lt;p&gt;Once the upgrade has completed, you can see that the "Green" instance here is now running PostgreSQL 16 and my "Blue" instance is still running PostgreSQL 15. &lt;/p&gt;

&lt;p&gt;From here, you can connect to the "Green" instance and run any recommended &lt;a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.html" rel="noopener noreferrer"&gt;post steps&lt;/a&gt; such as ANALYSE, VACUUM, REINDEX, EXTENSION UPGRADES etc &lt;/p&gt;

&lt;p&gt;This instance will stay in sync with your "Blue" instance, allowing you to leave this instance here now CDC'ing until you are able to take the outage to "switch over" these instances&lt;/p&gt;

&lt;p&gt;Once you are in a position to now "switch over" the process will be &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop/pause the application(s)&lt;/li&gt;
&lt;li&gt;Switch over the RDS instances.&lt;/li&gt;
&lt;li&gt;Start/resume the application(s)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On this example I don't have any applications connected so I will not be performing these stages&lt;/p&gt;

&lt;p&gt;To switch over the RDS instances the process is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the RDS console, select the Blue/Green Deployment. Click actions, switch over&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrl9b08pf8x6pf4rjb4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrl9b08pf8x6pf4rjb4k.png" alt=" " width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfqeadd5imrsmhdzo2rc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfqeadd5imrsmhdzo2rc.png" alt=" " width="694" height="879"&gt;&lt;/a&gt;&lt;br&gt;
You specify a timeout setting, this is the amount of time the switch over has to complete in before it classes it as a fail and rolls back. I am leaving it here at the default&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88m1j7ccqjrc8tglxgjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88m1j7ccqjrc8tglxgjg.png" alt=" " width="659" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI can also be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws rds switchover-blue-green-deployment \
--blue-green-deployment-identifier rds-postgresql-blue-green-v15-to-v16 \
--switchover-timeout 300
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvezv4lkwg6nynj2ioyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvezv4lkwg6nynj2ioyz.png" alt=" " width="649" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Switchover actions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxgvn5qtg14iybyv3ock.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxgvn5qtg14iybyv3ock.png" alt=" " width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The instances will change to 'switching over' status&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rjvffk8u57nx1f2kea5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rjvffk8u57nx1f2kea5.png" alt=" " width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see now, the instance that the upgrade was performed on is now labelled as 'New Blue'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbe4h4i1s0rbx5zn57mjs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbe4h4i1s0rbx5zn57mjs.png" alt=" " width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are now in a position to connect your application(s) and test &lt;/p&gt;

&lt;p&gt;The 'Old-Blue' instance will stay there until you manually remove, so it is important to remove this instance once you are happy and will not be rolling back - As this will be costing you money to keep hold of &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rollback - if required&lt;/strong&gt;&lt;br&gt;
If you find yourself in a position where you need to rollback to the previous instance you will need to do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete the Blue/Green deployment&lt;/li&gt;
&lt;li&gt;Rename the instances so that they match the previous endpoint &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Or switch the route53 DNS address for your application to point to the 'Old Blue' instance&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once happy, you can remove the previous instance and the Blue/Green deployment to leave you with just one RDS instance running the new version of RDS PostgreSQL&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wh2ynd2romhb1c6q35o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wh2ynd2romhb1c6q35o.png" alt=" " width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations - you've managed perform a major RDS upgrade whilst minimising downtime&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3o1o6gsix0752untef38.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3o1o6gsix0752untef38.png" alt=" " width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RDS Blue/Green deployments offer a efficient way to perform RDS upgrades (minor/major), applying any hardware intense maintenance, parameter changes, application changes without impacting the current instance that is serving production. This enhances security and reliability and allows you to be fully confident in the changes you're proposing before deploying to production. &lt;/p&gt;

&lt;p&gt;I hope this blog post helped, and happy building&lt;/p&gt;

&lt;p&gt;Feel free to connect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/daniel-chapman-a753b56b/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/daniel-chapman-a753b56b/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rds</category>
      <category>postgressql</category>
      <category>database</category>
      <category>bluegreen</category>
    </item>
    <item>
      <title>Migrating from SQLServer to Aurora PostgreSQL</title>
      <dc:creator>Daniel Chapman [AWS]</dc:creator>
      <pubDate>Fri, 27 Sep 2024 11:05:12 +0000</pubDate>
      <link>https://dev.to/aws-builders/migrating-from-sqlserver-to-aurora-postgresql-1949</link>
      <guid>https://dev.to/aws-builders/migrating-from-sqlserver-to-aurora-postgresql-1949</guid>
      <description>&lt;p&gt;In this blog I am going show you how to migrate from SQLServer to Aurora PostgreSQL using the &lt;a href="https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/babelfish.html" rel="noopener noreferrer"&gt;Babelfish&lt;/a&gt; extension. &lt;/p&gt;

&lt;p&gt;This blog post assumes that you are familiar with the RDS service.&lt;/p&gt;

&lt;p&gt;The first thing you need to do is to create an Aurora PostgreSQL custom parameter group with the babelfish setting &lt;br&gt;
"rds.babelfish_status" set to on.&lt;/p&gt;

&lt;p&gt;I then created a new security group that allowed connections to my VPC range for ports 1433 &amp;amp; 5432. This will allow me and the DMS service to be able to connect to both endpoints.&lt;/p&gt;

&lt;p&gt;From here, I created an Aurora PostgreSQL cluster using this parameter group. I have opted to use Serverless V2 but this is not mandatory. Once your cluster has created, you should see that the two endpoints available (writer/reader) are listening on both TCP 5432 &amp;amp; 1433&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopv0qz9tb7odfqgaxenc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopv0qz9tb7odfqgaxenc.png" alt=" " width="800" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You then need to create two IAM roles for the DMS service to use. &lt;br&gt;
These are: dms-vpc-role and dms-cloudwatch-logs-role&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arn:aws:iam::&amp;lt;accountnumber&amp;gt;:role/dms-cloudwatch-logs-role
arn:aws:iam::&amp;lt;accountnumber&amp;gt;:role/dms-vpc-role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They need to be set up as the exact ARNs mentioned above, otherwise the DMS service will not recognise them &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://docs.aws.amazon.com/dms/latest/userguide/security-iam.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/dms/latest/userguide/security-iam.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the DMS service.&lt;br&gt;
From here, navigate to "Subnet groups" &lt;/p&gt;

&lt;p&gt;You then need to create a subnet group for the DMS replication server to run out of. This needs to be a CIDR range that can communicate to your source (SQLServer) instance and your target (APG)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://docs.aws.amazon.com/dms/latest/userguide/subnet-group.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/dms/latest/userguide/subnet-group.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI can also be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws dms create-replication-subnet-group \
--replication-subnet-group-identifier SQLServerToAPG \ 
--replication-subnet-group-description SQLServerToAPG \ 
--subnet-ids &amp;lt;SUBNETA&amp;gt; &amp;lt;SUBNETB&amp;gt; &amp;lt;SUBNETC&amp;gt; &amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are then in a position to create the DMS replication instance &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://docs.aws.amazon.com/dms/latest/userguide/CHAP_ReplicationInstance.Creating.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/dms/latest/userguide/CHAP_ReplicationInstance.Creating.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI can also be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws dms create-replication-instance \
--replication-instance-identifier SQLServerToAuroraPostgreSQL \ 
--allocated-storage 50 \ 
--replication-instance-class dms.t3.medium \ 
--vpc-security-group-ids &amp;lt;SG ID created above&amp;gt; \
--no-multi-az \
--replication-subnet-group-identifier &amp;lt;Subnet Group created above&amp;gt; \
--engine-version 3.5.3 \
--no-publicly-accessible &amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi7vsm2j52yn19jhpdo8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi7vsm2j52yn19jhpdo8.png" alt=" " width="650" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to create both source and target DMS endpoints&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Endpoints.Creating.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Endpoints.Creating.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI can also be used: &lt;/p&gt;

&lt;p&gt;Source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws dms create-endpoint \
--endpoint-identifier SQLServer-source \
--endpoint-type source \
--engine-name sqlserver \
--ssl-mode require \
--username &amp;lt;username&amp;gt; \
--server-name sqlserversourcerds.abcdef.eu-west-1.rds.amazonaws.com \
--password &amp;lt;password of the SQLServer instance&amp;gt; \
--port 1433 \
--database-name &amp;lt;Local Database you wish to migrate&amp;gt; &amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws dms create-endpoint \
--endpoint-identifier APG-Target \
--endpoint-type target \
--engine-name aurora-postgresql \
--ssl-mode require \
--username &amp;lt;username&amp;gt; \
--server-name aurorapostgresqltarget.cluster-abcdef.eu-west-1.rds.amazonaws.com \
--password &amp;lt;password of the APG cluster&amp;gt; \
--port 5432 \
--database-name babelfish_db \
--postgre-sql-settings '{"MaxFileSize": 512}','{"ExecuteTimeout": 3600}'&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuht6ui8hhriu01htrxjy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuht6ui8hhriu01htrxjy.png" alt=" " width="511" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You then need to test the endpoints to ensure that the replication instance can communicate to both the source/target endpoints&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://docs.aws.amazon.com/dms/latest/sbs/chap-mariadb2auroramysql.testendpoints.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/dms/latest/sbs/chap-mariadb2auroramysql.testendpoints.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here, connect to the source SQLServer instance. I am using SSMS in this example, but any tooling will work. &lt;/p&gt;

&lt;p&gt;The dataset was populated using this document&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://www.sqlservercentral.com/articles/generating-dummy-data" rel="noopener noreferrer"&gt;https://www.sqlservercentral.com/articles/generating-dummy-data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This creates some dummy tables and populates a dataset&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faa0ykt4b4o8q080z8ul7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faa0ykt4b4o8q080z8ul7.png" alt=" " width="761" height="725"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to gather the DDL from this instance next&lt;br&gt;
In SSMS, select the database you're wanting to export, tasks, generate scripts. &lt;/p&gt;

&lt;p&gt;Ensure 'script the entire database' is selected, also ensure 'all database objects' is ticked. &lt;/p&gt;

&lt;p&gt;On the next page, under advanced ensure that 'Script-Full-Text-Indexes' are selected and also 'Script Triggers' is set to true.&lt;/p&gt;

&lt;p&gt;Save the output to a SQL file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F695kckvsij7ubtk74hxj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F695kckvsij7ubtk74hxj.png" alt=" " width="767" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then tend to split the large DDL file into multiple separate files, for pre and post migrations steps. For example,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tables-ss.sql    -- This will include all CREATE TABLE statements
FK-ss.sql        -- This will include all FOREIGN KEY statements
functions-ss.sql -- This will include all CREATE FUNCTION statements
defaults-ss.sql  -- This will include all DEFAULT statements
procedure-ss.sql -- This will include all CREATE PROCEDURE statements
function-ss.sql  -- This will include all CREATE FUNCTIONS statements
triggers-ss.sql  -- This will include all CREATE TRIGGERS statements
views-ss.sql     -- This will include all CREATE VIEW statements
indexes-ss.sql   -- This will include all CREATE INDEXES statements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now need to enable CDC on the source SQLServer instance. This is done via the below commands, example local database here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exec msdb.dbo.rds_cdc_enable_db 'commbuilderdemo';
GO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, I connect to the APG cluster but via the 1433 port. This will be using a SQLServer native UI or the SQLCMD command line tool.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9uvb2ndm4jw7tpg5tyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9uvb2ndm4jw7tpg5tyf.png" alt=" " width="468" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once connected to the master database, I will create the target local database. &lt;/p&gt;

&lt;p&gt;In the PostgreSQL endpoint all this simply does is create a new schema.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvmldpyf95daydvpit4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvmldpyf95daydvpit4q.png" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, I then will run the script created above to create all the blank tables and any applicable primary keys&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjmnecz40x0n9psdajmfj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjmnecz40x0n9psdajmfj.png" alt=" " width="256" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can now see, we've connected to the Aurora PostgreSQL cluster using a native SQLServer UI tool and you can now see the tables visible that we have previously created&lt;/p&gt;

&lt;p&gt;To access this instance from the PostgreSQL endpoint you would run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql -h &amp;lt;hostname&amp;gt; -U &amp;lt;username&amp;gt; -d babefish_db &amp;lt;&amp;lt; EOF 
set search_path=&amp;lt;LocalDatabaseCreatedAbove_dbo;
\dt
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An example of the above with a populated variables is here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql -h &amp;lt;hostname&amp;gt; -U &amp;lt;username&amp;gt; -d babefish_db 

babelfish_db=&amp;gt; set search_path=commbuilders_dbo;
SET
babelfish_db=&amp;gt; \dt
                       List of relations
      Schema      |       Name       | Type  |      Owner
------------------+------------------+-------+------------------
 commbuilders_dbo | customer_data    | table | commbuilders_dbo
 commbuilders_dbo | first_names      | table | commbuilders_dbo
 commbuilders_dbo | last_names       | table | commbuilders_dbo
 commbuilders_dbo | numbers          | table | commbuilders_dbo
 commbuilders_dbo | street_type      | table | commbuilders_dbo
 commbuilders_dbo | transaction_data | table | commbuilders_dbo
 commbuilders_dbo | transactions     | table | commbuilders_dbo
(7 rows)

babelfish_db=&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, navigate back to the DMS service. This is where we will create a replication task to move the data over from source to target. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj3oevjsnu2iamvljm58d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj3oevjsnu2iamvljm58d.png" alt=" " width="594" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensure you set the DMS task to 'Do nothing' for 'Target table preparation mode'. This is to ensure that DMS does not drop and re-create the tables. If this was to happen, then the SQLServer endpoint cannot always see the table(s) as the data types will be the PostgreSQL types and not the SQLServer required types. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkc3xa0elur2rzzv1gp2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkc3xa0elur2rzzv1gp2.png" alt=" " width="632" height="941"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here I am selecting all tables, I'm not excluding anything&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx13ajynuuyudhteboi6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx13ajynuuyudhteboi6q.png" alt=" " width="644" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You need to rename the schema to the localdatabase_dbo. With localdatabase being the name of the "CREATE DATABASE" command above&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvkf4m5dkuk68byls69m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvkf4m5dkuk68byls69m.png" alt=" " width="661" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a summary of the transformation rules that I created:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9m7uf97eyacsihsgxd54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9m7uf97eyacsihsgxd54.png" alt=" " width="642" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the data has loaded, it will stay in CDC mode until you are ready to switch over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxs7d7fb5vhsovntpb8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxs7d7fb5vhsovntpb8z.png" alt=" " width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check the status of the task by checking CloudWatch logs or inside the task itself, it shows how many rows it has migrated over:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foof3fkiaryruc7rh6bfi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foof3fkiaryruc7rh6bfi.png" alt=" " width="623" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you are ready to switch over, this is where you'd stop the source application and then once all connections have dropped you are in a position to stop the replication&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgh57j5mi3m1nvhgfyil0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgh57j5mi3m1nvhgfyil0.png" alt=" " width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now run the post scripts that you created before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FK-ss.sql        
functions-ss.sql 
defaults-ss.sql 
procedure-ss.sql 
function-ss.sql  
triggers-ss.sql  
views-ss.sql     
indexes-ss.sql   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have created all the database resources, you now need to run data validation steps.&lt;/p&gt;

&lt;p&gt;This will include, row counts validation, object count validation (FK, indexes, constraints etc), column count validation (to ensure all columns on the tables have replicated).&lt;/p&gt;

&lt;p&gt;For row counts, I simply ran a row count on all tables and compared.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT COUNT(*) FROM X;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;For object counts, I compared sys.objects in both instances, connecting to the 1433 endpoints so I could run the exact same SQL on both.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT type_desc,count(*) from sys.objects 
where schema_id=(SELECT SCHEMA_ID('dbo'))
group by type_desc
order by type_desc;
GO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That way you can easily compare objects and drill down into any differences, if applicable&lt;/p&gt;

&lt;p&gt;Once all of those steps have passed and you are happy, you will need to instruct your application team(s) to change their endpoint to the Aurora PostgreSQL endpoint and restart their application(s)&lt;/p&gt;

&lt;p&gt;Congratulations - you've managed to migrate from SQLServer to Aurora PostgreSQL.&lt;/p&gt;

&lt;p&gt;You can see a walkthrough of this process here on the AWS twitch site, that I presented earlier this year.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://www.twitch.tv/videos/2043017167?collection=BEUpZw5lUxeLJA" rel="noopener noreferrer"&gt;https://www.twitch.tv/videos/2043017167?collection=BEUpZw5lUxeLJA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this blog post helped, and happy building&lt;/p&gt;

&lt;p&gt;Feel free to connect &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;a href="https://www.linkedin.com/in/daniel-chapman-a753b56b/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/daniel-chapman-a753b56b/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>databasefreedom</category>
      <category>aurora</category>
      <category>sqlserver</category>
      <category>babelfish</category>
    </item>
  </channel>
</rss>
