[2020] Build Your MongoDB Atlas Cluster With Terraform in 5 Simple Steps
By: Nandhagopal Ezhilmaran
Tags: Mongo, Terraform Modules, Mongodb Atlas, Terraform, Mongodb

So, I had this requirement at work where I had to automate the creation of MongoDB cluster with Terraform. I had to spend a lot of time figuring out how to get it up and running because of lack of detailed documentation. We can’t really blame Mongo for it since their terraform provider is still new in town and evolving. As you would have guessed already, I felt like writing this blog right away, so that folks like me out there should not be struggling to get this simple task done. Following are the 5 simple steps to terraform this bad boy.!

Disclaimer: I’ll not be getting into the details of terraform syntaxes and concepts since this is not a terraform course.

Prerequisites:

Basic understanding of Terraform concepts and Terraform CLI installed. Create a MongoDB Atlas account. Create an Organisation and a Project under your account.

STEP 1: Create a MongoDB Atlas API key for terraform:

You need an API key (Public and Private keys) from your project to be used in terraform. Here’s how to create one. Make sure to create one at project level and not at Organisation level (It will have ‘Organisation Member’ access by default at the Org level when it’s created for the project) and give ‘Project Owner’ as the permission level to the API key. For some reason the cluster creation needs owner access and does not work with cluster manager permission.

You will get a private and public key pair. The private key will be visible to you only once when you create it. Make sure to store it in safe place (Preferably a password manager).

STEP 2: Create a mongodbatlas terraform provider

Now let’s get to business and create a main.tf file and add a provider block for mongodbatlas like below.

provider "mongodbatlas" {

public_key = "<YOUR PUBLIC KEY HERE>"

private_key = "<YOUR PRIVATE KEY HERE>"

}

When you are done adding a main.tf with the above content, run terraform init from the terminal in the same directory to initiate connection with the provider and local backend for state. (Since we have not given a backend block for a cloud backend, it will be initiated locally. Also, no need to worry if you get a versions.tf generated, it is a new way of managing third party providers in terraform 0.13 or higher)

STEP 3: Write a cluster resource as a module

I usually keep terraform entities as separate modules for clean directory structure and code reusability. I follow the below directory structure.

.

├── main.tf

├── modules

│ ├── module_one

│ │ └── module_one.tf

│ ├── module_two

│ │ └── module_two.tf

└── variables.tf

That being said, we can have the following cluster resource created in cluster.tf file under a cluster module like below:

variable "project_id" {}

variable "cluster_name" {}

variable "cluster_size" {}

variable "region" {

default = "EU_CENTRAL_1"

}



resource "mongodbatlas_cluster" "cluster" {

project_id = var.project_id // Your mongodb atlas project id

name = var.cluster_name // Desired cluster name

disk_size_gb = 10 // Disk size: Choose based on the instance size flavour you want. For ex, for M10, it's 10GB

num_shards = 1



replication_factor = 3

provider_backup_enabled = false

auto_scaling_disk_gb_enabled = false

mongo_db_major_version = "4.2"



//Provider Settings "block"

provider_name = "AWS" // Could be GCP | AWS | AZURE

provider_disk_iops = 100

provider_volume_type = "STANDARD"

provider_encrypt_ebs_volume = true

provider_instance_size_name = var.cluster_size // Could be anything above M2. M0 is not supported via this provider

provider_region_name = var.region // Desired region

}

Now we have to instantiate this module in our main.tf file as shown below

... // Provider code from Step 2 module "cluster" {

source = "./modules/cluster"

region = var.region

cluster_name = var.cluster_name

cluster_size = var.cluster_size

project_id = var.project_id

}

I prefer to use a variables.tf for managing variables. (Refer the above directory structure). variable.tf for above implemention can be added as shown below.

variable "project_id" {

type = string

description = "project ID"

default = "5fb250f25609bfbc82074f2f" // Your project ID

}



variable "cluster_name" {

type = string

description = "Cluster name"

default = "my-cluster"

}





variable "cluster_size" {

type = string

description = "Cluster size name"

default = "M10" // Could be M2/M5/M10...etc

}



variable "region" {

type = string

description = "Region name"

default = "EU_CENTRAL_1" // Your desired region

}

Step 4: Plan and Apply your terraform code

Now all you need to do is to plan your terraform code using terraform plan and verify the changes in the printed plan. Your should be seeing one module to be added which will be the atlas cluster with the provided configuration.

After verifying the plan printed in the above step, run terraform apply to apply your changes. You will see the cluster getting created message on the terminal and your changes will start appearing in your mongoDB console as well. It usually takes about 7 to 10 mins for the cluster to be created, so don’t worry about the time delay.

Step 5: Get a beer and celebrate

As soon as you see the message ‘Apply complete! Resources: 1 added, 0 changed, 0 destroyed.’, you can verify the cluster created in MongoDB atlas console and have a beer to reward yourself and celebrate.

Please do let me know if there are any questions/suggestions in the comments. Also let me know if writing more blogs around custom roles, users, AWS private link with mongoDB would be useful in the comments below :)

Hope this helps someone out there! Cheers…!

Working demo: https://github.com/nandhae/mongodb_atlas_terraform_cluster_creation_demo