Terraform with azure cosmosdb example
Tags: terraform, cosmosdb, azure
Published: 2021-03-31 13:00:28

Azure Cosmos DB is a globally distributed, multi-model database services that allows you to elastically scale in both throughput and storage. You can use document, key-value, columnar and graph databases in Azure Cosmos DB thanks to their multiple API offerings

### Creating an Account

Before even creating our account, we’ll need to tell Terraform that we’re deploying our resources to Azure. We can do this by using the Azure Provider. This is used to configure infrastructure in Azure. We’ll also use this provider to tell Terraform which subscription we are using. For that, we’ll need to provide our Subscription Id.

We’ll stick the Subscription Id in a file called variables.tf like so and also add the other related resource name like below
```
variable "subscription_id" {
  default = "******-*****-*****" // Add your azure subcription_id here
}

variable "resource_group_name" {
  default = "multi-cloud-tooling"
}

variable "resource_group_location" {
  default = "centralindia"
}

variable "cosmos_db_account_name" {
  default = "mrnewcosmosmongodb"
}

variable "failover_location" {
  default = "westindia"
}
```

Then create a file called main.tf and write the following code:

```
terraform {
  required_version = ">= 0.12.6"
  required_providers {
    azurerm = {
      version = "~> 2.53.0"
    }
  }
}

provider "azurerm" {
  features {}
  subscription_id            = var.subscription_id
  skip_provider_registration = true
}

resource "azurerm_cosmosdb_account" "acc" {

  name                      = var.cosmos_db_account_name
  location                  = var.resource_group_location
  resource_group_name       = var.resource_group_name
  offer_type                = "Standard"
  kind                      = "GlobalDocumentDB"
  enable_automatic_failover = true

  consistency_policy {
    consistency_level = "Session"
  }

  geo_location {
    location          = var.failover_location
    failover_priority = 1
  }

  geo_location {
    location          = var.resource_group_location
    failover_priority = 0
  }
}

resource "azurerm_cosmosdb_sql_database" "db" {
  name                = "firstcosmosdb"
  resource_group_name = azurerm_cosmosdb_account.acc.resource_group_name
  account_name        = azurerm_cosmosdb_account.acc.name
}

resource "azurerm_cosmosdb_sql_container" "coll" {
  name                = "firstcosmosdbcollection"
  resource_group_name = azurerm_cosmosdb_account.acc.resource_group_name
  account_name        = azurerm_cosmosdb_account.acc.name
  database_name       = azurerm_cosmosdb_sql_database.db.name
  partition_key_path  = "/CollId"
}
```
Let’s go through this block by block.

First up, we are setting up the terraform version and provider information

In the second block we are setting up the subscription_id, features{} to tell Terraform which Azure subscription I want to deploy my cosmos DB resources.

Then i am creating the azurerm_cosmosdb_account block to set up our Cosmos DB account. I'm giving it a name, assigning it to my resource group, giving it a location, defining the offer type, the kind of Cosmos DB account to create, defining the Consistency level of my Cosmos DB account, enabling geo_location for geo-replication and failover location priorities

### Creating Databases

Now that we have our account, I’m going to create a SQL API database within that account. Add the following resource definition to your main.tf file:

```
resource "azurerm_cosmosdb_sql_database" "db" {
  name                = "firstcosmosdb"
  resource_group_name = azurerm_cosmosdb_account.acc.resource_group_name
  account_name        = azurerm_cosmosdb_account.acc.name
} 
```


Here, I’m giving my database a name called “firstcosmosdb”. I’m then telling Terraform to deploy my database in the same resource group as my Cosmos DB account as well as assigning the database to my account name.

### Creating Collections:

Let’s create a collection under our database. We can do this with the azurerm_cosmosdb_sql_container resource definition. Add the following Terraform code to your main.tf file:

```
resource "azurerm_cosmosdb_sql_container" "coll" {
  name                = "firstcosmosdbcollection"
  resource_group_name = azurerm_cosmosdb_account.acc.resource_group_name
  account_name        = azurerm_cosmosdb_account.acc.name
  database_name       = azurerm_cosmosdb_sql_database.db.name
  partition_key_path  = "/CollId"
}
```

In this resource, I’ve given my container a name ('firstcosmosdbcollection'), assigned it to my resource group, account and database and then given my container a Partition Key of '/CollId'.

Everything has now been set up, so let’s deploy it to Azure!

### Deploying to Azure

First, we’ll need to login to Azure via the command line.
If you’ve got it already, run the following command:

```az login```

When we build infrastructure in Terraform, we need to perform the following three steps:

1. Terraform Init
2. Terraform Plan
3. Terraform Apply

Then create a file called Makefile and write the following code:

```
.PHONY: init
init:
	terraform init

.PHONY: plan
plan:
	terraform plan

.PHONY: apply
apply: validate
	terraform apply --auto-approve

.PHONY: format
format:
	terraform fmt

.PHONY: validate
validate:
	terraform validate

.PHONY: destroy
destroy:
	terraform destroy --auto-approve

.PHONY: refresh
refresh:
	terraform refresh
```

Run the following commands to create the azure infrastruture.

***make init*** will create a new configuration for our Terraform environment.It will create a directory called .terraform and download any plugins needed for the configuration. It will also configure the back-end for the Terraform state. Each Terraform provider will have it’s own binaries that are separate from Terraform itself, so the init command will download and install these based on what provider we are using

***make plan*** terraform plan also checks our syntax and attempts to connect to our Azure account to check if there are any differences between our Terraform code and our current state. 

***make apply*** This command is used to apply our changes. We should run this command in the same directory as the main.tf file.

It will create the resources in azure which we mentioned in the main.tf file.