Getting started with TerraForm
These notes document my first steps in using TerraForm to manage Azure infrastructure. This first post is how I brought some existing resources under TerraForm’s management.
My initial project is to bring an existing CosmosDB into TerraForm (prior to provisioning a new VM alongside it).
I initially created a new directory and then a .tf
file within it - having discovered that terraform init
in an empty directory complains that there are no TerraForm configuration files.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=2.77.0" # 2.77.0 added 'EnableServerless' cosmosdb capability, which we use
}
}
}
# Using the Azure plugin
provider "azurerm" {
features {}
}
variable "base_tags" {
type = map(String)
description = "Base set of tags for all resources"
default = {
"Application Name" = "My Application"
"Application Owner" = "Support Team"
"Business Sector" = "R&D"
"Country" = "UK"
"Data Classification" = "Confidential"
"Environment" = "PROD/DEV" # Mandatory tag per company policy - set to correct value by more specific variables
"Region" = "EMEA"
# ... etc.
}
}
variable "tags_dev" {
type = map(String)
description = "Development resources tags"
default = {Environment = "DEV"}
}
variable "tags_live" {
type = map(String)
description = "Live resources tags"
default = {Environment = "LIVE"}
}
resource "azurerm_resource_group" "rg" {
name = "RG-MY_RG-001"
location = "West Europe"
tags = merge(var.base_tags, var.tags_dev)
}
resource "azurerm_cosmosdb_account" "db" {
name = "cdb-my_cosmosdb"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
offer_type = "Standard"
kind = "MongoDB"
public_network_access_enabled = false
consistency_policy {
consistency_level = "Session"
max_interval_in_seconds = 5
max_staleness_prefix = 100
}
capabilities {
name = "DisableRateLimitingResponses"
}
capabilities {
name = "EnableMongo"
}
capabilities {
name = "EnableServerless"
}
geo_location {
location = azurerm_resource_group.rg.location
failover_priority = 0
}
backup {
type = "Periodic"
interval_in_minutes = 240
retention_in_hours = 8
}
tags = merge(
var.base_tags,
var.tags_dev,
{
defaultExperience = "Azure Cosmos DB for MongoDB API
}
)
}
resource "azurerm_cosmosdb_mongo_database" "mongo_db" {
name = "my_mongo_db"
resource_group_name = azurerm_resource_group.rg.name
account_name = azurerm_cosmosdb_account.db.name
}
resource "azurerm_cosmosdb_mongo_collection" "mongo_collection" {
name = "my_collection"
resource_group_name = azurerm_resource_group.rg.name
account_name = azurerm_cosmosdb_account.db.name
database_name = azurerm_cosmosdb_mongo_database.mongo_db.name
default_ttl_seconds = 0
index {
keys = [
"$**",
]
unique = false
}
index {
keys = [
"_id",
]
unique = true
}
}
resource "azurerm_private_endpoint" "cosmos_endpoint" {
name = "EP-MY_EP-001"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = "...."
private_service_connection {
is_manual_connection = false
name = "${azurerm_cosmosdb_account.db.name}-connection"
private_connection_resource_id = azurerm_cosmosdb_account.db.id
subresource_names = [azurerm_cosmosdb_account.db.kind]
}
tags = merge(var.base_tags, var.tags_live)
}
(Once the rest of the networking is brought under TerraForm, the hardcoded subnet_id will be replaced with a reference to the subnet’s id property.)
To update the installed azurerm
provider, I had to pass -upgrade
to terraform init
:
terraform init -upgrade
In order to let TerraForm know it does not need to create everything, I have to tell it about the already deployed infrastructure using terraform import
, so for the existing resource group, Cosmos database and private endpoint:
terraform import azurerm_resource_group.rg /subscriptions/$sub_id/resourceGroups/RG-MY_RG-001
terraform import azurerm_cosmosdb_account.db /subscriptions/$sub_id/resourceGroups/RG-MY_RG-001/providers/Microsoft.DocumentDB/databaseAccounts/cdb-my_cosmosdb
terraform import azurerm_cosmosdb_mongo_database.mongo_db /subscriptions/$sub_id/resourceGroups/RG-MY_RG-001/providers/Microsoft.DocumentDB/databaseAccounts/cdb-my_cosmosdb/mongodbDatabases/my_mongo_db
terraform import azurerm_cosmosdb_mongo_collection.mongo_collection /subscriptions/$sub_id/resourceGroups/RG-MY_RG-001/providers/Microsoft.DocumentDB/databaseAccounts/cdb-my_cosmosdb/mongodbDatabases/my_mongo_db/collections/my_collection
terraform import azurerm_private_endpoint.cosmos_endpoint /subscriptions/$sub_id/resourceGroups/RG-MY_RG-001/providers/Microsoft.Network/privateEndpoints/EP-My_EP-001
To preview what TerraForm will do, use the command:
terraform plan
Once happy with the plan, make the changes with:
terraform apply