Cloud Construction

Finally the part we’ve all been waiting for. Let’s deploy our target AWS infrastructure.

In Cloud9, change back to the home directory of your workspace, and then let’s clone the firebase-migrator CDK application:

cd ~/environment

git clone https://github.com/shankben/firebase-migrator.git

Now let’s install the CDK application’s dependencies:

cd firebase-migrator

npm install

Great. Now we’ll need to copy our two sets of Firebase credentials to the secrets/ directory. Just like we did for configuring the web application, we first need to download our Firebase SDK configuration:

firebase apps:sdkconfig --project ionic-conference-demo

Copy the guts of the output and paste into a JSON file at secrets/FirebaseAppConfig.json, so that the contents resemble:

{
  "projectId": "ionic-conference-demo",
  "appId": "1:123456789123:web:a1b2c3d4e5f6a7b8c9d1e2",
  "databaseURL": "https://ionic-conference-demo.firebaseio.com",
  "storageBucket": "ionic-conference-demo.appspot.com",
  "locationId": "us-central",
  "apiKey": "AIa1b2c3d4e5f6a7b8c9d1e2f3a1b2c3d4e5f6a",
  "authDomain": "ionic-conference-demo.firebaseapp.com",
  "messagingSenderId": "123456789123"
}

Lastly, we need the Firebase Service Account credentials so that the migrator tools can utilize the Firebase Admin SDK within AWS. Download these credentials using the password given at the beginning of the workshop

Firebase Service Account Credentials

and save the JSON file to secrets/FirebaseServiceAccount.json.

Build

Let’s build the CDK application. This should take a few seconds:

npm run build

Let’s now list the stacks our CDK application defines:

cdk ls

You can see there are the following stacks:

ionic-conference-demo-BaseStack
ionic-conference-demo-ApiStack
ionic-conference-demo-SyncStack
ionic-conference-demo-ListenerStack

BaseStack deploys resources that are shared amongst the entire infrastructure, namely, the DynamoDB table, the S3 bucket, the Cognito User Pool with user migration trigger. The SyncStack sets up a Step Functions state machine that synchronizes Firestore data with DynamoDB.

ApiStack defines our AppSync GraphQL API and ListenerStack sets up the Fargate services that propagate real time changes from Firestore and Google Cloud Storage to DynamoDB and S3, respectively. We deploy these as separate stacks for two reasons:

  1. Before ApiStack deploys, the CDK application generates our AppSync GraphQL schema by introspecting the migrated Firestore data in DynamoDB.

  2. Should we ever wish to evolve our architecture and deploy an additional or completely different type of API service, we can do so without disrupting our existing AppSync API.

This practice derives from software engineering principles collectively refined for decades that allow complex systems to change over time with minimal disruption.

Do It Live

Ready to rock? Let’s do this:

cdk deploy ionic-conference-demo-SyncStack

We start by deploying SyncStack because it is dependent upon the BaseStack. You’ll notice the console output reflects this:

Including dependency stacks: ionic-conference-demo-BaseStack

After a few minutes, our base infrastructure is up and running and our Firebase application’s Firestore data is now synchronized in DynamoDB.

Now let’s deploy ListenerStack:

cdk deploy ionic-conference-demo-ListenerStack

Similar to before, ListenerStack is dependent upon ApiStack, so we can expect the API resources to deploy before all the Fargate services. After a few more minutes, our AWS infrastructure is up and running. At this moment, we have effectively created a parallel AWS environment to our Firebase environment.

Wait, that’s it?!

Not quite. We still need to wire up our frontend application using Amplify to our freshly baked AWS infrastructure.