Hero Image

Azure DevOps CI/CD with MongoDB Atlas App Services

 

06 Feb 2023 | Julian Echeverri

In this article we will explore a workaround that will allow us to implement CI/CD within MongoDB Atlas Application Services in an Azure DevOps environment.

MongoDB Atlas provides integration with GitHub (deployments, workflows and commits) however currently there is no out-of-the-box integration with Azure DevOps. MongoDB Atlas has a CLI and SDK that proved useful when solving this challenge.

You can review the MongoDB Documents covering GitHub deployments here:

Deploy Automatically with GitHub

App Services / Application Deployment

Set Up a CI/CD Pipeline

Our Process

There are two main components in our process: the Realm App in Atlas Cloud and our code repository in Azure DevOps. The Realm App in Atlas Cloud is our application, and here we can see logs, code, current state, environment variables, deployments, and other similar information. We use Azure DevOps for code versioning of our application and a CI/CD approach, which are both not supported in Atlas Cloud directly.

By utilizing Azure DevOps, we can bring a full application lifecycle approach to the management of our Realm App. Our process will be to first push any code changes to Azure DevOps for development purposes, and then to publish code from Azure DevOps into Atlas Cloud for deploying and testing our application.

As a first step to setting this up, start in the MongoDB Atlas portal and follow the instructions shown in order to export the Realm App and push it to Azure. We must create a programmatic API key for pulling – and no ZIP file is exported.

For this example, we are using one branch called “main” for all the CI/CD process’. A pipeline will be triggered every time that we push a change (or changes) to it.

You can read more about what Azure pipelines are at this address and access additional information by clicking here.

Our process can be observed in the code below:

In this CI/CD flow approach we are creating a temporary Realm App and Database – to be able to run tests against both – however we first need to validate the current deployment of our App.

This validation is important as it allows us to avoid versioning issues. This is because App services will not be aware of any changes, and so whatever we push will be replaced. We use the task shown in the code below to achieve this.

Within this task we are retrieving the deployments by sending a request to the Atlas App Services Admin API. We then compare the latest successful deployment against the one stored in our database history.

In the next image we see the version data in our database that our deployment is to be validated against. It tells us if we need a new version, or if we can proceed.

A PowerShell script using the following parameters is created to handle versioning of the deployment for the Realm App and the repository in Azure:

The functions of each string are as follows:

• String Api Key and PrivateApi Key are needed to authenticate with Atlas App Services.

• String ProjectId is needed to identify the project we’re working with.

• String ConnectionString is used for retrieving deployment history.

• String DatabaseName returns the name of the database.

Continuing with the deployment history pipeline, the following functions are set up:

• Function AuthMongoCloud sends an authentication request to get an access token, which is needed for further requests.

• Function GetAppInfo sends a request to retrieve the app info. We need the appID for subsequent requests.

• Function GetDeployments gets the deployments based on appId.

We began a validation process by getting the access token based on the API keys. Next, we will retrieve the app info and the deployments.

The date from the deployments is returned in seconds, we use a function to convert it to a regular date (see below). This is needed to get the most recently created successful deployment.

Now that we have the deployment, we can query our database to retrieve the latest version on it too.

If there is no match, the process fails as we don’t want to push changes that could not function as intended (or even break something). The user will instead then be alerted that the latest version isn’t present, and they can address this directly.

Once we have a successful match, we can continue.

Proceeding from our successful match, we can name the testing app, setting this up with the Build.SourceVersion (commit number).

It is at this point that we install RealmCLI:

We can now create the Realm App and Database via a PowerShell script.

We are sending the following parameters:

• String Api Key and PrivateApi Key are needed to authenticate in Realm CLI.

• String ProjectId is needed to push the changes to our testing project in Atlas.

• String ClusterName and ClusterServiceName are necessary for pointing to our cluster.

• String ConnectionString is used for creating the connection between database and application.

• String AppName is used for naming our app.

• Strings ApiKeyProd,privateApiKeyProd, appIdProd and projectIdProd are all data from our app.

Next, we will create our testing database using the MongoDB PowerShell Cmdlets module, shown as follows:

We’ll then create the testing Realm App in a lower-level directory from our current one.

Then, we set up functions and triggers depending on how many are present in our app. We made a loop for each one.

Once the testing Realm App is created, we pull the changes and continue with copying files.

We then need to replace the data source with the temporary data source that we are creating for testing, setting the database name and cluster properly.

We can then begin to copy the files to the testing folder app:

Next, we replace the “environment”, “log_forwarders” and “triggers” values in each file (covering database names, service names etc.):

To correctly run the tests we require, we’ve created a file that will be used for script testing. It contains a range of information using Realm SDK including “appID” and “database name”.

We need to retrieve this information and set it in order to correctly test. We also need to set up the environment variables.

Once this is done, we can push the changes and are now ready to run our test scripts against the testing app:

Following the pipeline steps above, we’re ready to run our test scripts. We install Node and NPM then run our tests using Jest.

This is a sample integration test. It tests a trigger and a function when we insert data into Collection ‘orders’ in MongoDB.

Assuming successful completion of the tests, we perform a little clean-up operation by removing the database and Realm app as shown below.


If the tests are not successful, the user will receive an error message and opportunity to correct any issues before proceeding.

Then, we push the changes. The implementation process is complete!

 

Process Review

We validate our deployment code versions in Azure DevOps to avoid conflicts or issues that could arise when a developer moves to push their code. The complete deployment history is stored in a MongoDB collection.

We also thoroughly test and validate the code (functions, triggers etc.) in the pipeline build, an automated process to ensure properly functioning code.

We hope you’ve found this overview useful in implementing CI/CD in MongoDB Atlas in an Azure DevOps environment.