santosh.a
santosh.a

Reputation: 535

how to create generic cosmos db terraform module to add multiple geo_locations

I'm trying to create a module for azure cosmos db using terraform. In my example I wanted geo_location should be more flexible/customized. Which means my failover locations are not standard for all my applications. In one of the application my primary location is WEU but failover is EUS. In other application Primary is EUS but failover location is WEU, WUS2. and so on... So I wanted to use 1 cosmosdb module and the geo_location property should be more self service oriented where infra developers can specify any number of regions they require.

I see that in terraform we have to specify "geo_location" block for every region. This approach will defeat the purpose of having 1 module. Is there anyway can I make it more generic like I explained above?

Any suggestions are helpful.

thanks, Santosh

Upvotes: 0

Views: 1277

Answers (1)

Ansuman Bal
Ansuman Bal

Reputation: 11421

If I understand your requirement correctly , You want to build a module for Cosmos DB where the operator will be asked to provide any number of values for geo location and the resource block will create the geo_location blocks accordingly.

In the above case you can create a variable of list type , which will ask the user to provide the values for the same and then use dynamic geo_location block so that it gets configured accordingly. I have tested with the below code :

provider "azurerm" {
  features {}
}
resource "azurerm_resource_group" "rg" {
  name     = "cosmos-dbtest"
  location = "East US"
}

variable "geo_location" {
    type = list
    description = "value for Geo Locations"
}

resource "random_integer" "ri" {
  min = 10000
  max = 99999
}

resource "azurerm_cosmosdb_account" "db" {
  name                = "tfex-cosmos-db-${random_integer.ri.result}"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  offer_type          = "Standard"
  kind                = "MongoDB"

  enable_automatic_failover = true

  capabilities {
    name = "EnableAggregationPipeline"
  }

  capabilities {
    name = "mongoEnableDocLevelTTL"
  }

  capabilities {
    name = "MongoDBv3.4"
  }

  capabilities {
    name = "EnableMongo"
  }

  consistency_policy {
    consistency_level       = "BoundedStaleness"
    max_interval_in_seconds = 300
    max_staleness_prefix    = 100000
  }

  dynamic "geo_location" {
      for_each = var.geo_location
    content{
    location          = geo_location.value
    failover_priority = geo_location.key
  }
}
}

Output:

enter image description here

enter image description here

OR

If you want to keep the first geo_location same as the location for cosmos DB and then other failover locations , then you can use one static and one dynamic geo_location block like below:

resource "azurerm_cosmosdb_account" "db" {
  name                = "tfex-cosmos-db-${random_integer.ri.result}"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  offer_type          = "Standard"
  kind                = "MongoDB"

  enable_automatic_failover = true

  capabilities {
    name = "EnableAggregationPipeline"
  }

  capabilities {
    name = "mongoEnableDocLevelTTL"
  }

  capabilities {
    name = "MongoDBv3.4"
  }

  capabilities {
    name = "EnableMongo"
  }

  consistency_policy {
    consistency_level       = "BoundedStaleness"
    max_interval_in_seconds = 300
    max_staleness_prefix    = 100000
  }
  geo_location {
    location          = azurerm_resource_group.rg.location
    failover_priority = 0
  }
  dynamic "geo_location" {
      for_each = var.geo_location
    content{
    location          = geo_location.value
    failover_priority = "${geo_location.key + 1}"
  }
}
}

Output:

enter image description here

enter image description here

Upvotes: 2

Related Questions