How to Deploy MongoDB Atlas with Terraform on AWS
Rate this tutorial
MongoDB Atlas is the multi-cloud developer data platform that provides an integrated suite of cloud database and data services. We help to accelerate and simplify how you build resilient and performant global applications on the cloud provider of your choice.
HashiCorp Terraform is an Infrastructure-as-Code (IaC) tool that lets you define cloud resources in human-readable configuration files that you can version, reuse, and share. Hence, we built the Terraform MongoDB Atlas Provider that automates infrastructure deployments by making it easy to provision, manage, and control Atlas configurations as code on any of the three major cloud providers.
In addition, teams can also choose to deploy MongoDB Atlas through the MongoDB Atlas CLI (Command-Line Interface), Atlas Administration API, AWS CloudFormation, and as always, with the Atlas UI (User Interface).
In this blog post, we will learn how to deploy MongoDB Atlas hosted on AWS using Terraform. In addition, we will explore how to use Private Endpoints with AWS Private Link to provide increased security with private connectivity for your MongoDB Atlas cluster without exposing traffic to the public internet.
Let’s get started:
Go to the top of the Atlas UI, click the Gear Icon to the right of the organization name you created, click Access Manager in the lefthand menu bar, click the API Keys tab, and then click the green Create API Key box.
Enter a description for the API key that will help you remember what it’s being used for — for example “Terraform API Key.” Next, you’ll select the appropriate permission for what you want to accomplish with Terraform. Both the Organization Owner and Organization Project Creator roles (see role descriptions below) will provide access to complete this task, but by using the principle of least privilege, let’s select the Organization Project Creator role in the dropdown menu and click Next.
Make sure to copy your private key and store it in a secure location. After you leave this page, your full private key will notbe accessible.
On the same page, scroll down and click Add Access List Entry. If you are unsure of the IP address that you are running Terraform on (and you are performing this step from that machine), simply click Use Current IP Address and Save. Another option is to open up your IP Access List to all, but this comes with significant potential risk. To do this, you can add the following two CIDRs: 0.0.0.0/1 and 18.104.22.168/1. These entries will open your IP Access List to at most 4,294,967,296 (or 2^32) IPv4 addresses and should be used with caution.
Go to the lefthand menu bar and click Billing and then Add Payment Method. Follow the steps to ensure there is a valid payment method for your organization. Note when creating a free (forever) or M0 cluster tier, you can skip this step.
First, go to the terminal window and create Environment Variables with the below commands. This prevents you from having to hard-code secrets directly into Terraform config files (which is not recommended):
We will now create a variables.tf file to declare all the Terraform variables used as part of this exercise and all of which are of type string. Next, we’ll define values (i.e. our secrets) for each of these variables in the terraform.tfvars file. Note as with most secrets, best practice is not to upload them (or the terraform.tfvars file itself) to public repos.
The example below specifies to use the most current MongoDB version (as of this writing), which is 6.0, a M10 cluster tier which is great for a robust development environment and will be deployed on AWS in the US_WEST_2 Atlas region. For specific details about all the available options besides M10 and US_WEST_2, please see the .
Next, create a main.tf file, which we will populate together to create the minimum required resources to create and access your cluster: a MongoDB Atlas Project (Step 8), Database User/Password (Step 9), IP Access List (Step 10), and of course, the MongoDB Atlas Cluster itself (Step 11). We will then walk through how to create Terraform Outputs (Step 12) so you can access your Atlas cluster and then create a Private Endpoint with AWS PrivateLink (Step 13). If you are already familiar with any of these steps, feel free to skip ahead.
Note: As infrastructure resources get created, modified, or destroyed, several more files will be generated in your directory by Terraform (for example the terraform.tfstate file). It is best practice not to modify these additional files directly unless you know what you are doing.
MongoDB Atlas Projects helps to organize and provide granular access controls to our resources inside our MongoDB Atlas Organization. Note MongoDB Atlas “Groups” and “Projects” are synonymous terms.
To create a Project using Terraform, we will need the MongoDB Atlas Organization ID with at least the Organization Project Creator role (defined when we created the MongoDB Atlas Provider API Keys in Step 2).
To get this information, simply click on Settings on the lefthand menu bar in the Atlas UI and click the copy icon next to Organization ID. You can now paste this information as the atlas_org_id in your terraform.tfvars file.
To authenticate a client to MongoDB, like the MongoDB Shell or your application code using a (officially supported in Python, Node.js, Go, Java, C#, C++, Rust, and several others), you must add a corresponding Database User to your MongoDB Atlas Project. See the for more information on available user roles so you can customize the user’s RBAC (Role Based Access Control) as per your team’s needs.
For now, simply input the following code as part of the next few lines in the main.tf file to create a Database User with a random 16-character password. This will use the resource from the Terraform MongoDB Atlas Provider. The database user_password is a sensitive secret, so to access it, you will need to input the “terraform output -json user_password” command in your terminal window after our deployment is complete to reveal.
Next, we will create the IP Access List by inputting the following into your main.tf file. Be sure to lookup the IP address (or CIDR range) of the machine where you’ll be connecting to your MongoDB Atlas cluster from and paste it into the terraform.tfvars file (as shown in code block in Step 7). This will use the resource from the Terraform MongoDB Atlas Provider.
In this example, we group three database servers together to create a with a primary server and two secondary replicas duplicating the primary's data. This architecture is primarily designed with high availability in mind and can automatically handle failover if one of the servers goes down — and recover automatically when it comes back online. We call all these nodes electable because an election is held between them to work out which one is primary.
Lastly, we create one analytics node. Analytics nodes are read-only nodes that can exclusively be used to execute database queries on. That means that this analytics workload is isolated to this node only so operational performance isn't impacted. This makes analytic nodes ideal to run longer and more computationally intensive analytics queries on without impacting your replica set performance (see ).
You can output information from your Terraform configuration to the terminal window of the machine executing Terraform commands. This can be especially useful for values you won’t know until the resources are created, like the random password for the database user or the connection string to your Atlas cluster deployment. The code below in the main.tf file will output these values to the terminal display for you to use after Terraform completes.
Increasingly, we see our customers want their data to traverse only private networks. One of the best ways to connect to Atlas over a private network from AWS is to use , which establishes a one-way connection that preserves your perceived network trust boundary while eliminating additional security controls associated with other options like VPC peering (Azure Private Link and GCP Private Service Connect are supported, as well). .
Next, let’s go to the terminal and create AWS Environment Variables with the below commands (similar as we did in Step 6 with our MongoDB Atlas credentials). Use the same region as above, except we will use the AWS naming convention instead, i.e., “us-west-2”.
We now add a new entry in our variables.tf and terraform.tfvars files for the desired AWS region. As mentioned earlier, we will be using “us-west-2” which is the AWS region in Oregon, USA.
Next we create two more files for each of the new types of resources to be deployed: aws-vpc.tf to create a full network configuration on the AWS side and atlas-pl.tf to create both the and the of the PrivateLink. In your environment, you may already have an AWS network created. If so, then you’ll want to include the correct values in the atlas-pl.tf file and won’t need aws-vpc.tf file. To get started quickly, we will simply them from .
We are now all set to start creating our first MongoDB Atlas deployment!
Open the terminal console and type the following command: terraform init to initialize Terraform. This will download and install both the Terraform AWS and MongoDB Atlas Providers (if you have not done so already).
Next, we will run the terraform plan command. This will output what Terraform plans to do, such as creation, changes, or destruction of resources. If the output is not what you expect, then it’s likely an issue in your Terraform configuration files.
Next, use the terraform apply command to deploy the infrastructure. If all looks good, input yes to approve terraform build.
Note new AWS and MongoDB Atlas resources can take ~15 minutes to provision and the provider will continue to give you a status update until it is complete. You can also check on progress through the Atlas UI and AWS Management Console.
The connection string shown in the output can be used to access (including performing CRUD operations) on your MongoDB database via the , , and in the UI (as shown below). Learn more about with the MongoDB Query Language (MQL). As a pro tip, I regularly leverage the to quickly reference key commands.
Lastly, as a reminder, the database user_password is a sensitive secret, so to access it, you will need to input the “terraform output -json user_password” command in your terminal window to reveal.
Here the resources we created earlier will all now be terminated. If all looks good, input yes:
After a few minutes, we are back to an empty slate on both our MongoDB Atlas and AWS environments. It goes without saying, but please be mindful when using the terraform destroy command in any kind of production environment.
Happy Terraforming with MongoDB Atlas on AWS!
Conference Transcription and Replay - Build a Serverless GraphQL API with MongoDB Realm
Feb 1, 2022 | 5:15 PM UTC