This commit is contained in:
John Spinella 2023-01-23 11:50:59 -05:00
Родитель af38ea99d6
Коммит 8a51e67fca
33 изменённых файлов: 1217 добавлений и 119 удалений

Просмотреть файл

@ -1,50 +0,0 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
/*
SUMMARY: Module to deploy a CosmosDB with private endpoints to an Virtual Network
DESCRIPTION: The following components will be options in this deployment
* CosmosDB with MongoDB API
* Private Endpoints
* Private DNS Zones
AUTHOR/S: jspinella
*/
# If the resource group name is not provided, create a new one
data "azurerm_resource_group" "cosmos_rg" {
count = length(var.resource_group_name) > 0 ? 1 : 0
name = var.resource_group_name
}
# Create the CosmosDB
module "mod_cosmos_db" {
source = "../../../modules/Microsoft.DocumentDB/databases"
name = var.cosmosdb_name
location = var.location
resource_group_name = length(var.resource_group_name) > 0 ? data.azurerm_resource_group.cosmos_rg.name : var.resource_group_name
account_kind = var.cosmosdb_account_kind
}
# Create the private DNS zone for the ACR
module "mod_cosmos_db_private_dns_zone" {
source = "../../../modules/Microsoft.Network/privateDnsZone"
name = "privatelink.vaultcore.azure.net"
resource_group_name = length(var.resource_group_name) > 0 ? data.azurerm_resource_group.cosmos_rg.name : var.resource_group_name
virtual_networks_to_link = var.virtual_networks_to_link
}
# Create the private endpoint for the ACR
module "mod_cosmos_db_private_endpoint" {
source = "../../../modules/Microsoft.Network/privateEndpoints"
name = "${module.mod_cosmos_db.name}PrivateEndpoint"
location = var.location
resource_group_name = length(var.resource_group_name) > 0 ? data.azurerm_resource_group.cosmos_rg.name : var.resource_group_name
subnet_id = var.vnet_subnet_id
tags = var.tags
private_connection_resource_id = module.mod_cosmos_db.id
is_manual_connection = false
subresource_name = "vault"
private_dns_zone_group_name = "CosmosDbPrivateDnsZoneGroup"
private_dns_zone_group_ids = [module.mod_cosmos_db_private_dns_zone.id]
}

Просмотреть файл

@ -1,9 +0,0 @@
# Acessing AzureRM provider configuration
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "this" {
name = var.resource_group_name
location = var.location
}

Просмотреть файл

@ -1,44 +0,0 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
/*
SUMMARY: Module to deploy a Cosmos DB Account with a SQL API Database
DESCRIPTION: The following components will be options in this deployment
Cosmos DB Account
SQL API Database
AUTHOR/S: jspinella
*/
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
}
}
# Private DNS Zone for SQL API
# Cosmos DB Account
module "azure_cosmos_db" {
source = "../../modules/Microsoft.DocumentDB/databaseAccounts"
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
cosmos_account_name = var.cosmos_account_name
cosmos_api = var.cosmos_api
}
module "azure_cosmos_sql_db" {
source = "../../modules/Microsoft.DocumentDB/databaseAccounts/sqlDatabases"
resource_group_name = data.azurerm_resource_group.this.name
location = data.azurerm_resource_group.this.location
cosmos_account_name = module.azure_cosmos_db.cosmos_account_name
sql_dbs = var.sql_dbs
sql_db_containers = var.sql_db_containers
depends_on = [
module.azure_cosmos_db
]
}

Просмотреть файл

@ -1,16 +0,0 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# -
# - Azure CosmosDB Account
# -
variable "database_name" {
type = string
description = "Specifies the name of the CosmosDB Account."
}
variable "offer_type" {
type = string
description = "Specifies the Offer Type to use for this CosmosDB Account - currently this can only be set to Standard."
}

Просмотреть файл

@ -0,0 +1,8 @@
locals {
# Naming locals/constants
name_prefix = lower(var.name_prefix)
name_suffix = lower(var.name_suffix)
name = coalesce(var.custom_name, data.azurecaf_name.redis.result)
storage_name = coalesce(var.data_persistence_storage_custom_name, data.azurecaf_name.data_storage.result)
}

Просмотреть файл

@ -0,0 +1,6 @@
locals {
default_tags = var.default_tags_enabled ? {
env = var.environment
core = var.workload_name
} : {}
}

Просмотреть файл

@ -0,0 +1,25 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#------------------------------------------------------------
# Local configuration - Default (required).
#------------------------------------------------------------
locals {
redis_family_map = {
Basic = "C",
Standard = "C",
Premium = "P"
}
data_persistence_enabled = var.sku_name == "Premium" ? var.data_persistence_enabled : false
default_redis_config = {
rdb_backup_enabled = local.data_persistence_enabled
rdb_storage_connection_string = one(azurerm_storage_account.redis_storage[*].primary_blob_connection_string)
rdb_backup_frequency = local.data_persistence_enabled ? var.data_persistence_frequency_in_minutes : null
rdb_backup_max_snapshot_count = local.data_persistence_enabled ? var.data_persistence_max_snapshot_count : null
}
redis_config = merge(local.default_redis_config, var.redis_additional_configuration)
}

Просмотреть файл

@ -0,0 +1,106 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# By default, this module will not create a resource group
# provide a name to use an existing resource group, specify the existing resource group name,
# and set the argument to `create_storage_account_resource_group = false`. Location will be same as existing RG.
resource "azurerm_resource_group" "rg" {
count = var.create_resource_group ? 1 : 0
name = var.resource_group_name
location = var.location
tags = merge({ "Name" = format("%s", var.resource_group_name) }, var.tags, )
}
data "azurerm_log_analytics_workspace" "logws" {
count = var.log_analytics_workspace_name != null ? 1 : 0
name = var.log_analytics_workspace_name
resource_group_name = local.resource_group_name
}
#---------------------------------------------------------------
# Storage Account to keep logs and backups - Default is "false"
#----------------------------------------------------------------
resource "random_string" "str" {
count = var.enable_data_persistence ? 1 : 0
length = 6
special = false
upper = false
keepers = {
name = var.storage_account_name
}
}
resource "azurerm_storage_account" "redis_storage" {
count = local.data_persistence_enabled ? 1 : 0
name = local.storage_name
resource_group_name = var.resource_group_name
location = var.location
account_tier = var.data_persistence_storage_account_tier
account_replication_type = var.data_persistence_storage_account_replication
account_kind = "StorageV2"
min_tls_version = "TLS1_2"
tags = merge(local.default_tags, var.extra_tags)
}
#------------------------------------------------------------
# Redis Cache Instance configuration - Default (required).
#------------------------------------------------------------
resource "azurerm_redis_cache" "redis" {
name = local.name
location = var.location
resource_group_name = var.resource_group_name
family = lookup(local.redis_family_map, var.sku_name)
sku_name = var.sku_name
enable_non_ssl_port = var.allow_non_ssl_connections
minimum_tls_version = var.minimum_tls_version
shard_count = var.sku_name == "Premium" ? var.cluster_shard_count : 0
capacity = var.capacity
private_static_ip_address = var.private_static_ip_address
subnet_id = var.subnet_id
redis_version = var.redis_version
zones = var.zones
tags = merge(local.default_tags, var.extra_tags)
dynamic "redis_configuration" {
for_each = local.redis_config[*]
content {
aof_backup_enabled = redis_configuration.value.aof_backup_enabled
aof_storage_connection_string_0 = redis_configuration.value.aof_storage_connection_string_0
aof_storage_connection_string_1 = redis_configuration.value.aof_storage_connection_string_1
enable_authentication = redis_configuration.value.enable_authentication
maxmemory_reserved = redis_configuration.value.maxmemory_reserved
maxmemory_delta = redis_configuration.value.maxmemory_delta
maxmemory_policy = redis_configuration.value.maxmemory_policy
maxfragmentationmemory_reserved = redis_configuration.value.maxfragmentationmemory_reserved
rdb_backup_enabled = redis_configuration.value.rdb_backup_enabled
rdb_backup_frequency = redis_configuration.value.rdb_backup_frequency
rdb_backup_max_snapshot_count = redis_configuration.value.rdb_backup_max_snapshot_count
rdb_storage_connection_string = redis_configuration.value.rdb_storage_connection_string
notify_keyspace_events = redis_configuration.value.notify_keyspace_events
}
}
lifecycle {
ignore_changes = [redis_configuration[0].rdb_storage_connection_string]
}
dynamic "patch_schedule" {
for_each = var.patch_schedules
content {
day_of_week = patch_schedule.value.day_of_week
start_hour_utc = patch_schedule.value.start_hour_utc
maintenance_window = patch_schedule.value.maintenance_window
}
}
}

Просмотреть файл

@ -0,0 +1,31 @@
data "azurecaf_name" "redis" {
name = var.workload_name
resource_type = "azurerm_redis_cache"
prefixes = var.name_prefix == "" ? null : [local.name_prefix]
suffixes = compact([var.org_name, var.location_short, var.environment, local.name_suffix, var.use_caf_naming ? "" : "redis"])
use_slug = var.use_caf_naming
clean_input = true
separator = "-"
}
data "azurecaf_name" "data_storage" {
name = var.workload_name
resource_type = "azurerm_storage_account"
prefixes = compact([local.name_prefix, "redis"])
suffixes = compact([var.org_name, var.location_short, var.environment, local.name_suffix, var.use_caf_naming ? "" : "st"])
use_slug = var.use_caf_naming
clean_input = true
separator = "-"
}
data "azurecaf_name" "redis_fw_rule" {
for_each = var.authorized_cidrs
name = var.workload_name
resource_type = "azurerm_redis_firewall_rule"
prefixes = var.name_prefix == "" ? null : [local.name_prefix]
suffixes = compact([var.org_name, var.location_short, var.environment, local.name_suffix, each.key])
use_slug = var.use_caf_naming
clean_input = true
separator = "-"
}

Просмотреть файл

@ -0,0 +1,9 @@
output "terraform_module" {
description = "Information about this Terraform module"
value = {
name = "redis"
version = file("${path.module}/VERSION")
provider = "azurerm"
maintainer = "microsoft"
}
}

Просмотреть файл

@ -0,0 +1,65 @@
output "redis_id" {
value = azurerm_redis_cache.redis.id
description = "Redis instance id"
}
output "redis_name" {
value = azurerm_redis_cache.redis.name
description = "Redis instance name"
}
output "redis_hostname" {
value = azurerm_redis_cache.redis.hostname
description = "Redis instance hostname"
}
output "redis_ssl_port" {
value = azurerm_redis_cache.redis.ssl_port
description = "Redis instance SSL port"
}
output "redis_port" {
value = azurerm_redis_cache.redis.port
description = "Redis instance port"
}
output "redis_primary_access_key" {
sensitive = true
value = azurerm_redis_cache.redis.primary_access_key
description = "Redis primary access key"
}
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
output "redis_secondary_access_key" {
sensitive = true
value = azurerm_redis_cache.redis.secondary_access_key
description = "Redis secondary access key"
}
output "redis_private_static_ip_address" {
value = azurerm_redis_cache.redis.private_static_ip_address
description = "Redis private static IP address"
}
output "redis_sku_name" {
value = azurerm_redis_cache.redis.sku_name
description = "Redis SKU name"
}
output "redis_family" {
value = azurerm_redis_cache.redis.family
description = "Redis family"
}
output "redis_capacity" {
value = azurerm_redis_cache.redis.capacity
description = "Redis capacity"
}
output "redis_configuration" {
sensitive = true
value = azurerm_redis_cache.redis.redis_configuration
description = "Redis configuration"
}

Просмотреть файл

@ -0,0 +1,59 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#---------------------------------------------------------
# Private Link for Redis Server - Default is "false"
#---------------------------------------------------------
data "azurerm_virtual_network" "vnet01" {
count = var.enable_private_endpoint ? 1 : 0
name = var.virtual_network_name
resource_group_name = var.resource_group_name
}
resource "azurerm_private_endpoint" "pep1" {
count = var.enable_private_endpoint ? 1 : 0
name = format("%s-private-endpoint", element([for n in azurerm_redis_cache.main : n.name], 0))
location = var.location
resource_group_name = var.resource_group_name
subnet_id = var.existing_subnet_id
tags = merge({ "Name" = format("%s-private-endpoint", element([for n in azurerm_redis_cache.main : n.name], 0)) }, var.tags, )
private_service_connection {
name = "rediscache-privatelink"
is_manual_connection = false
private_connection_resource_id = element([for i in azurerm_redis_cache.main : i.id], 0)
subresource_names = ["redisCache"]
}
}
data "azurerm_private_endpoint_connection" "private-ip1" {
count = var.enable_private_endpoint ? 1 : 0
name = azurerm_private_endpoint.pep1.0.name
resource_group_name = var.resource_group_name
depends_on = [azurerm_redis_cache.main]
}
resource "azurerm_private_dns_zone" "dnszone1" {
count = var.existing_private_dns_zone == null && var.enable_private_endpoint ? 1 : 0
name = "privatelink.redis.cache.windows.net"
resource_group_name = var.resource_group_name
tags = merge({ "Name" = format("%s", "RedisCache-Private-DNS-Zone") }, var.tags, )
}
resource "azurerm_private_dns_zone_virtual_network_link" "vent-link1" {
count = var.existing_private_dns_zone == null && var.enable_private_endpoint ? 1 : 0
name = "vnet-private-zone-link"
resource_group_name = var.resource_group_name
private_dns_zone_name = azurerm_private_dns_zone.dnszone1.0.name
virtual_network_id = data.azurerm_virtual_network.vnet01.0.id
tags = merge({ "Name" = format("%s", "vnet-private-zone-link") }, var.tags, )
}
resource "azurerm_private_dns_a_record" "arecord1" {
count = var.enable_private_endpoint ? 1 : 0
name = element([for n in azurerm_redis_cache.main : n.name], 0)
zone_name = var.existing_private_dns_zone == null ? azurerm_private_dns_zone.dnszone1.0.name : var.existing_private_dns_zone
resource_group_name = var.resource_group_name
ttl = 300
records = [data.azurerm_private_endpoint_connection.private-ip1.0.private_service_connection.0.private_ip_address]
}

Просмотреть файл

@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Generic naming variables
variable "name_prefix" {
description = "Optional prefix for the generated name"
type = string
default = ""
}
variable "name_suffix" {
description = "Optional suffix for the generated name"
type = string
default = ""
}
variable "use_caf_naming" {
description = "Use the Azure CAF naming provider to generate default resource name. `custom_name` override this if set. Legacy default name is used if this is set to `false`."
type = bool
default = true
}
# Custom naming override
variable "custom_name" {
description = "Custom name of Redis Server"
type = string
default = ""
}
variable "data_persistence_storage_custom_name" {
description = "Custom name for the Storage Account used for Redis data persistence."
type = string
default = ""
}

Просмотреть файл

@ -0,0 +1,12 @@
variable "default_tags_enabled" {
description = "Option to enable or disable default tags."
type = bool
default = true
}
variable "extra_tags" {
description = "Map of custom tags."
type = map(string)
default = {}
}

Просмотреть файл

@ -0,0 +1,173 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
variable "location" {
description = "Azure region in which instance will be hosted"
type = string
}
variable "location_short" {
description = "Azure region short name"
type = string
}
variable "environment" {
description = "Name of the workload's environnement"
type = string
}
variable "workload_name" {
description = "Name of the workload_name"
type = string
}
variable "org_name" {
description = "Name of the organization"
type = string
}
variable "virtual_network_name" {
description = "The name of the virtual network"
default = ""
}
variable "resource_group_name" {
description = "Name of the workload ressource group"
type = string
}
variable "enable_private_endpoint" {
description = "Manages a Private Endpoint to Azure database for Redis"
default = false
}
variable "existing_private_dns_zone" {
description = "Name of the existing private DNS zone"
default = null
}
variable "existing_subnet_id" {
description = "ID of the existing subnet"
default = null
}
variable "capacity" {
description = "Redis size: (Basic/Standard: 1,2,3,4,5,6) (Premium: 1,2,3,4) https://docs.microsoft.com/fr-fr/azure/redis-cache/cache-how-to-premium-clustering"
type = number
default = 2
}
variable "sku_name" {
description = "Redis Cache Sku name. Can be Basic, Standard or Premium"
type = string
default = "Premium"
}
variable "cluster_shard_count" {
description = "Number of cluster shards desired"
type = number
default = 3
}
variable "redis_configuration" {
description = "Additional configuration for the Redis instance. Some of the keys are set automatically. See https://www.terraform.io/docs/providers/azurerm/r/redis_cache.html#redis_configuration for full reference."
type = object({
aof_backup_enabled = optional(bool)
aof_storage_connection_string_0 = optional(string)
aof_storage_connection_string_1 = optional(string)
enable_authentication = optional(bool)
maxmemory_reserved = optional(number)
maxmemory_delta = optional(number)
maxmemory_policy = optional(string)
maxfragmentationmemory_reserved = optional(number)
rdb_backup_enabled = optional(bool)
rdb_backup_frequency = optional(number)
rdb_backup_max_snapshot_count = optional(number)
rdb_storage_connection_string = optional(string)
notify_keyspace_events = optional(string)
})
default = {}
}
variable "authorized_cidrs" {
description = "Map of authorized cidrs"
type = map(string)
}
variable "allow_non_ssl_connections" {
description = "Activate non SSL port (6779) for Redis connection"
type = bool
default = false
}
variable "minimum_tls_version" {
description = "The minimum TLS version"
type = string
default = "1.2"
}
variable "private_static_ip_address" {
description = "The Static IP Address to assign to the Redis Cache when hosted inside the Virtual Network. Changing this forces a new resource to be created."
type = string
default = null
}
variable "subnet_id" {
description = "The ID of the Subnet within which the Redis Cache should be deployed. Changing this forces a new resource to be created."
type = string
default = null
}
variable "data_persistence_enabled" {
description = "\"true\" to enable data persistence."
type = bool
default = true
}
variable "data_persistence_frequency_in_minutes" {
description = "Data persistence snapshot frequency in minutes."
type = number
default = 60
}
variable "data_persistence_max_snapshot_count" {
description = "Max number of data persistence snapshots."
type = number
default = null
}
variable "data_persistence_storage_account_tier" {
description = "Replication type for the Storage Account used for data persistence."
type = string
default = "Premium"
}
variable "data_persistence_storage_account_replication" {
description = "Replication type for the Storage Account used for data persistence."
type = string
default = "LRS"
}
variable "redis_version" {
description = "Redis version to deploy. Allowed values are 4 or 6"
type = number
default = 4
}
variable "zones" {
description = "A list of a one or more Availability Zones, where the Redis Cache should be allocated."
default = null
type = list(number)
}
variable "patch_schedules" {
description = "A list of Patch Schedule, Azure Cache for Redis patch schedule is used to install important software updates in specified time window."
default = []
nullable = false
type = list(object({
day_of_week = string
start_hour_utc = optional(string)
maintenance_window = optional(string)
}))
}

Просмотреть файл

@ -0,0 +1,13 @@
terraform {
required_version = ">= 1.3"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.22"
}
azurecaf = {
source = "aztfmod/azurecaf"
version = "~> 1.2, >= 1.2.22"
}
}
}

Просмотреть файл

@ -0,0 +1,79 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#---------------------------------------------------------
# CosmosDB SQL Container API - Default is "false"
#---------------------------------------------------------
resource "azurerm_cosmosdb_sql_container" "main" {
count = var.create_cosmosdb_sql_container ? 1 : 0
name = var.cosmosdb_sql_container_name == null ? format("%s-sql-container", element([for n in azurerm_cosmosdb_account.main : n.name], 0)) : var.cosmosdb_sql_container_name
resource_group_name = local.resource_group_name
account_name = element([for n in azurerm_cosmosdb_account.main : n.name], 0)
database_name = azurerm_cosmosdb_sql_database.main.0.name
partition_key_path = var.partition_key_path
partition_key_version = var.partition_key_version
throughput = var.sql_container_autoscale_settings == null ? var.sql_container_throughput : null
default_ttl = var.default_ttl
analytical_storage_ttl = var.analytical_storage_ttl
dynamic "unique_key" {
for_each = var.unique_key != null ? [var.unique_key] : []
content {
paths = var.unique_key.paths
}
}
dynamic "autoscale_settings" {
for_each = var.sql_container_autoscale_settings != null ? [var.sql_container_autoscale_settings] : []
content {
max_throughput = var.sql_container_throughput == null ? var.sql_container_autoscale_settings.max_throughput : null
}
}
dynamic "indexing_policy" {
for_each = var.indexing_policy != null ? [var.indexing_policy] : []
content {
indexing_mode = var.indexing_policy.indexing_mode
dynamic "included_path" {
for_each = lookup(var.indexing_policy, "included_path") != null ? [lookup(var.indexing_policy, "included_path")] : []
content {
path = var.indexing_policy.included_path.path
}
}
dynamic "excluded_path" {
for_each = lookup(var.indexing_policy, "excluded_path") != null ? [lookup(var.indexing_policy, "excluded_path")] : []
content {
path = var.indexing_policy.excluded_path.path
}
}
dynamic "composite_index" {
for_each = lookup(var.indexing_policy, "composite_index") != null ? [lookup(var.indexing_policy, "composite_index")] : []
content {
index {
path = var.indexing_policy.composite_index.index.path
order = var.indexing_policy.composite_index.index.order
}
}
}
dynamic "spatial_index" {
for_each = lookup(var.indexing_policy, "spatial_index") != null ? [lookup(var.indexing_policy, "spatial_index")] : []
content {
path = var.indexing_policy.spatial_index.path
}
}
}
}
dynamic "conflict_resolution_policy" {
for_each = var.conflict_resolution_policy != null ? [var.conflict_resolution_policy] : []
content {
mode = var.conflict_resolution_policy.mode
conflict_resolution_path = var.conflict_resolution_policy.conflict_resolution_path
conflict_resolution_procedure = var.conflict_resolution_policy.conflict_resolution_procedure
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#---------------------------------------------------------
# CosmosDB SQL Database API - Default is "false"
#---------------------------------------------------------
resource "azurerm_cosmosdb_sql_database" "main" {
count = var.create_cosmosdb_sql_database || var.create_cosmosdb_sql_container ? 1 : 0
name = var.cosmosdb_sql_database_name == null ? format("%s-sql-database", element([for n in azurerm_cosmosdb_account.main : n.name], 0)) : var.cosmosdb_sql_database_name
resource_group_name = local.resource_group_name
account_name = element([for n in azurerm_cosmosdb_account.main : n.name], 0)
throughput = var.cosmosdb_sqldb_autoscale_settings == null ? var.cosmosdb_sqldb_throughput : null
dynamic "autoscale_settings" {
for_each = var.cosmosdb_table_autoscale_settings != null ? [var.cosmosdb_table_autoscale_settings] : []
content {
max_throughput = var.cosmosdb_sqldb_throughput == null ? var.cosmosdb_table_autoscale_settings.max_throughput : null
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#------------------------------------------------------------
# Local Naming configuration - Default (required).
#------------------------------------------------------------
locals {
# Naming locals/constants
name_prefix = lower(var.name_prefix)
name_suffix = lower(var.name_suffix)
cosmosdb_name = coalesce(var.custom_server_name, data.azurecaf_name.cosmosdb.result)
}

Просмотреть файл

@ -0,0 +1,13 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#------------------------------------------------------------
# Local Tags configuration - Default (required).
#------------------------------------------------------------
locals {
default_tags = var.default_tags_enabled ? {
env = var.environment
core = var.workload_name
} : {}
}

Просмотреть файл

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#------------------------------------------------------------
# Local configuration - Default (required).
#------------------------------------------------------------
locals {
default_failover_locations = {
default = {
location = var.location
zone_redundant = var.zone_redundancy_enabled
}
}
}

Просмотреть файл

@ -0,0 +1,101 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# By default, this module will not create a resource group
# provide a name to use an existing resource group, specify the existing resource group name,
# and set the argument to `create_storage_account_resource_group = false`. Location will be same as existing RG.
resource "azurerm_resource_group" "rg" {
count = var.create_resource_group ? 1 : 0
name = var.resource_group_name
location = var.location
tags = merge({ "Name" = format("%s", var.resource_group_name) }, var.tags, )
}
#-------------------------------------------------------------
# CosmosDB azure defender configuration - Default is "false"
#-------------------------------------------------------------
resource "azurerm_advanced_threat_protection" "example" {
count = var.enable_advanced_threat_protection ? 1 : 0
target_resource_id = element([for n in azurerm_cosmosdb_account.main : n.id], 0)
enabled = var.enable_advanced_threat_protection
}
#------------------------------------------------------------
# Cosmos Db Sql Instance configuration - Default (required).
#------------------------------------------------------------
resource "azurerm_cosmosdb_account" "db" {
name = local.cosmosdb_name
location = var.location
resource_group_name = var.resource_group_name
offer_type = var.offer_type
kind = var.kind
mongo_server_version = var.kind == "MongoDB" ? var.mongo_server_version : null
enable_automatic_failover = true
analytical_storage_enabled = var.analytical_storage_enabled
dynamic "analytical_storage" {
for_each = var.analytical_storage_type != null ? ["enabled"] : []
content {
schema_type = var.analytical_storage_type
}
}
dynamic "geo_location" {
for_each = var.failover_locations != null ? var.failover_locations : local.default_failover_locations
content {
location = geo_location.value.location
failover_priority = lookup(geo_location.value, "priority", 0)
zone_redundant = lookup(geo_location.value, "zone_redundant", false)
}
}
consistency_policy {
consistency_level = var.consistency_policy_level
max_interval_in_seconds = var.consistency_policy_max_interval_in_seconds
max_staleness_prefix = var.consistency_policy_max_staleness_prefix
}
dynamic "capabilities" {
for_each = toset(var.capabilities)
content {
name = capabilities.key
}
}
ip_range_filter = join(",", var.allowed_cidrs)
public_network_access_enabled = var.public_network_access_enabled
is_virtual_network_filter_enabled = var.is_virtual_network_filter_enabled
network_acl_bypass_for_azure_services = var.network_acl_bypass_for_azure_services
network_acl_bypass_ids = var.network_acl_bypass_ids
dynamic "virtual_network_rule" {
for_each = var.virtual_network_rule != null ? toset(var.virtual_network_rule) : []
content {
id = virtual_network_rule.value.id
ignore_missing_vnet_service_endpoint = virtual_network_rule.value.ignore_missing_vnet_service_endpoint
}
}
dynamic "backup" {
for_each = var.backup != null ? ["enabled"] : []
content {
type = lookup(var.backup, "type", null)
interval_in_minutes = lookup(var.backup, "interval_in_minutes", null)
retention_in_hours = lookup(var.backup, "retention_in_hours", null)
}
}
dynamic "identity" {
for_each = var.identity_type != null ? ["enabled"] : []
content {
type = var.identity_type
}
}
tags = merge(local.default_tags, var.extra_tags)
}

Просмотреть файл

@ -0,0 +1,31 @@
data "azurecaf_name" "redis" {
name = var.workload_name
resource_type = "azurerm_redis_cache"
prefixes = var.name_prefix == "" ? null : [local.name_prefix]
suffixes = compact([var.org_name, var.location_short, var.environment, local.name_suffix, var.use_caf_naming ? "" : "redis"])
use_slug = var.use_caf_naming
clean_input = true
separator = "-"
}
data "azurecaf_name" "data_storage" {
name = var.workload_name
resource_type = "azurerm_storage_account"
prefixes = compact([local.name_prefix, "redis"])
suffixes = compact([var.org_name, var.location_short, var.environment, local.name_suffix, var.use_caf_naming ? "" : "st"])
use_slug = var.use_caf_naming
clean_input = true
separator = "-"
}
data "azurecaf_name" "redis_fw_rule" {
for_each = var.authorized_cidrs
name = var.workload_name
resource_type = "azurerm_redis_firewall_rule"
prefixes = var.name_prefix == "" ? null : [local.name_prefix]
suffixes = compact([var.org_name, var.location_short, var.environment, local.name_suffix, each.key])
use_slug = var.use_caf_naming
clean_input = true
separator = "-"
}

Просмотреть файл

@ -0,0 +1,12 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
output "terraform_module" {
description = "Information about this Terraform module"
value = {
name = "redis"
version = file("${path.module}/VERSION")
provider = "azurerm"
maintainer = "microsoft"
}
}

Просмотреть файл

@ -0,0 +1,62 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
output "cosmosdb_id" {
description = "The CosmosDB Account ID."
value = azurerm_cosmosdb_account.db.id
}
output "cosmosdb_name" {
description = "The CosmosDB Account Name."
value = azurerm_cosmosdb_account.db.name
}
output "cosmosdb_endpoint" {
description = "The endpoint used to connect to the CosmosDB account."
value = azurerm_cosmosdb_account.db.endpoint
}
output "cosmosdb_read_endpoints" {
description = "A list of read endpoints available for this CosmosDB account."
value = azurerm_cosmosdb_account.db.read_endpoints
}
output "cosmosdb_write_endpoints" {
description = "A list of write endpoints available for this CosmosDB account."
value = azurerm_cosmosdb_account.db.write_endpoints
}
output "cosmosdb_primary_master_key" {
description = "The Primary master key for the CosmosDB Account."
value = azurerm_cosmosdb_account.db.primary_key
sensitive = true
}
output "cosmosdb_secondary_master_key" {
description = " The Secondary master key for the CosmosDB Account."
value = azurerm_cosmosdb_account.db.secondary_key
sensitive = true
}
output "cosmosdb_primary_readonly_master_key" {
description = "The Primary read-only master Key for the CosmosDB Account."
value = azurerm_cosmosdb_account.db.primary_readonly_key
sensitive = true
}
output "cosmosdb_secondary_readonly_master_key" {
description = "The Secondary read-only master key for the CosmosDB Account."
value = azurerm_cosmosdb_account.db.secondary_readonly_key
sensitive = true
}
output "cosmosdb_connection_strings" {
description = "A list of connection strings available for this CosmosDB account."
value = azurerm_cosmosdb_account.db.connection_strings
sensitive = true
}
output "identity" {
description = "Identity block with principal ID"
value = azurerm_cosmosdb_account.db.identity
}

Просмотреть файл

@ -0,0 +1,59 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#---------------------------------------------------------
# Private Link for CosmosDB Server - Default is "false"
#---------------------------------------------------------
data "azurerm_virtual_network" "vnet01" {
count = var.enable_private_endpoint ? 1 : 0
name = var.virtual_network_name
resource_group_name = local.resource_group_name
}
resource "azurerm_private_endpoint" "pep1" {
count = var.enable_private_endpoint ? 1 : 0
name = format("%s-private-endpoint", element([for n in azurerm_cosmosdb_account.main : n.name], 0))
location = local.location
resource_group_name = local.resource_group_name
subnet_id = azurerm_subnet.snet-ep.0.id
tags = merge({ "Name" = format("%s-private-endpoint", element([for n in azurerm_cosmosdb_account.main : n.name], 0)) }, var.tags, )
private_service_connection {
name = "rediscache-privatelink"
is_manual_connection = false
private_connection_resource_id = element([for n in azurerm_cosmosdb_account.main : n.id], 0)
subresource_names = ["Sql"]
}
}
data "azurerm_private_endpoint_connection" "private-ip1" {
count = var.enable_private_endpoint ? 1 : 0
name = azurerm_private_endpoint.pep1.0.name
resource_group_name = local.resource_group_name
depends_on = [azurerm_cosmosdb_account.main]
}
resource "azurerm_private_dns_zone" "dnszone1" {
count = var.existing_private_dns_zone == null && var.enable_private_endpoint ? 1 : 0
name = "privatelink.documents.azure.com"
resource_group_name = local.resource_group_name
tags = merge({ "Name" = format("%s", "CosmosDB-Private-DNS-Zone") }, var.tags, )
}
resource "azurerm_private_dns_zone_virtual_network_link" "vent-link1" {
count = var.existing_private_dns_zone == null && var.enable_private_endpoint ? 1 : 0
name = "vnet-private-zone-link"
resource_group_name = local.resource_group_name
private_dns_zone_name = azurerm_private_dns_zone.dnszone1.0.name
virtual_network_id = data.azurerm_virtual_network.vnet01.0.id
tags = merge({ "Name" = format("%s", "vnet-private-zone-link") }, var.tags, )
}
resource "azurerm_private_dns_a_record" "arecord1" {
count = var.enable_private_endpoint ? 1 : 0
name = element([for n in azurerm_cosmosdb_account.main : n.name], 0)
zone_name = var.existing_private_dns_zone == null ? azurerm_private_dns_zone.dnszone1.0.name : var.existing_private_dns_zone
resource_group_name = local.resource_group_name
ttl = 300
records = [data.azurerm_private_endpoint_connection.private-ip1.0.private_service_connection.0.private_ip_address]
}

Просмотреть файл

Просмотреть файл

@ -0,0 +1,20 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT Lice
#---------------------------------------------------------
# CosmosDB Table - Default is "false"
#---------------------------------------------------------
resource "azurerm_cosmosdb_table" "main" {
count = var.create_cosmosdb_table ? 1 : 0
name = var.cosmosdb_table_name == null ? format("%s-table", element([for n in azurerm_cosmosdb_account.main : n.name], 0)) : var.cosmosdb_table_name
resource_group_name = local.resource_group_name
account_name = element([for n in azurerm_cosmosdb_account.main : n.name], 0)
throughput = var.cosmosdb_table_autoscale_settings == null ? var.cosmosdb_table_throughput : null
dynamic "autoscale_settings" {
for_each = var.cosmosdb_table_autoscale_settings != null ? [var.cosmosdb_table_autoscale_settings] : []
content {
max_throughput = var.cosmosdb_table_throughput == null ? var.cosmosdb_table_autoscale_settings.max_throughput : null
}
}
}

Просмотреть файл

@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Generic naming variables
variable "name_prefix" {
description = "Optional prefix for the generated name"
type = string
default = ""
}
variable "name_suffix" {
description = "Optional suffix for the generated name"
type = string
default = ""
}
variable "use_caf_naming" {
description = "Use the Azure CAF naming provider to generate default resource name. `custom_name` override this if set. Legacy default name is used if this is set to `false`."
type = bool
default = true
}
# Custom naming override
variable "custom_name" {
description = "Custom name of Redis Server"
type = string
default = ""
}
variable "data_persistence_storage_custom_name" {
description = "Custom name for the Storage Account used for Redis data persistence."
type = string
default = ""
}

Просмотреть файл

@ -0,0 +1,12 @@
variable "default_tags_enabled" {
description = "Option to enable or disable default tags."
type = bool
default = true
}
variable "extra_tags" {
description = "Map of custom tags."
type = map(string)
default = {}
}

Просмотреть файл

@ -0,0 +1,192 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
variable "location" {
description = "Azure region in which instance will be hosted"
type = string
}
variable "location_short" {
description = "Azure region short name"
type = string
}
variable "environment" {
description = "Name of the workload's environnement"
type = string
}
variable "workload_name" {
description = "Name of the workload_name"
type = string
}
variable "org_name" {
description = "Name of the organization"
type = string
}
variable "virtual_network_name" {
description = "The name of the virtual network"
default = ""
}
variable "resource_group_name" {
description = "Name of the workload ressource group"
type = string
}
## Specific Private Endpoint parameters
variable "enable_private_endpoint" {
description = "Manages a Private Endpoint to Azure database for Redis"
default = false
}
variable "existing_private_dns_zone" {
description = "Name of the existing private DNS zone"
default = null
}
variable "existing_subnet_id" {
description = "ID of the existing subnet"
default = null
}
## Specific CosmosDB parameters
variable "offer_type" {
type = string
description = "Specifies the Offer Type to use for this CosmosDB Account - currently this can only be set to Standard."
default = "Standard"
}
variable "kind" {
type = string
description = "Specifies the Kind of CosmosDB to create - possible values are `GlobalDocumentDB` and `MongoDB`."
default = "GlobalDocumentDB"
}
variable "mongo_server_version" {
description = "The Server Version of a MongoDB account. See possible values https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_account#mongo_server_version"
type = string
default = "4.2"
}
variable "zone_redundancy_enabled" {
description = "True to enabled zone redundancy on default primary location"
type = bool
default = true
}
variable "failover_locations" {
description = "The name of the Azure region to host replicated data and their priority."
type = map(map(string))
default = null
}
variable "capabilities" {
type = list(string)
description = <<EOD
Configures the capabilities to enable for this Cosmos DB account:
Possible values are
AllowSelfServeUpgradeToMongo36, DisableRateLimitingResponses,
EnableAggregationPipeline, EnableCassandra, EnableGremlin,EnableMongo, EnableTable, EnableServerless,
MongoDBv3.4 and mongoEnableDocLevelTTL.
EOD
default = []
}
variable "allowed_cidrs" {
type = list(string)
description = "CosmosDB Firewall Support: This value specifies the set of IP addresses or IP address ranges in CIDR form to be included as the allowed list of client IP's for a given database account."
default = []
}
variable "public_network_access_enabled" {
description = "Whether or not public network access is allowed for this CosmosDB account."
type = bool
default = true
}
variable "is_virtual_network_filter_enabled" {
description = "Enables virtual network filtering for this Cosmos DB account"
type = bool
default = false
}
variable "network_acl_bypass_for_azure_services" {
description = "If azure services can bypass ACLs."
type = bool
default = false
}
variable "network_acl_bypass_ids" {
description = "The list of resource Ids for Network Acl Bypass for this Cosmos DB account."
type = list(string)
default = null
}
variable "virtual_network_rule" {
description = "Specifies a virtual_network_rules resource used to define which subnets are allowed to access this CosmosDB account"
type = list(object({
id = string,
ignore_missing_vnet_service_endpoint = bool
}))
default = null
}
variable "consistency_policy_level" {
description = "Consistency policy level. Allowed values are `BoundedStaleness`, `Eventual`, `Session`, `Strong` or `ConsistentPrefix`"
type = string
default = "BoundedStaleness"
}
variable "consistency_policy_max_interval_in_seconds" {
description = "When used with the Bounded Staleness consistency level, this value represents the time amount of staleness (in seconds) tolerated. Accepted range for this value is 5 - 86400 (1 day). Defaults to 5. Required when consistency_level is set to BoundedStaleness."
type = number
default = 10
}
variable "consistency_policy_max_staleness_prefix" {
description = "When used with the Bounded Staleness consistency level, this value represents the number of stale requests tolerated. Accepted range for this value is 10 – 2147483647. Defaults to 100. Required when consistency_level is set to BoundedStaleness."
type = number
default = 200
}
variable "backup" {
description = "Backup block with type (Continuous / Periodic), interval_in_minutes and retention_in_hours keys"
type = object({
type = string
interval_in_minutes = number
retention_in_hours = number
})
default = {
type = "Periodic"
interval_in_minutes = 3 * 60
retention_in_hours = 7 * 24
}
}
variable "analytical_storage_enabled" {
description = "Enable Analytical Storage option for this Cosmos DB account. Defaults to `false`. Changing this forces a new resource to be created."
type = bool
default = false
}
variable "analytical_storage_type" {
description = "The schema type of the Analytical Storage for this Cosmos DB account. Possible values are `FullFidelity` and `WellDefined`."
type = string
default = null
validation {
condition = try(contains(["FullFidelity", "WellDefined"], var.analytical_storage_type), true)
error_message = "The `analytical_storage_type` value must be valid. Possible values are `FullFidelity` and `WellDefined`."
}
}
variable "identity_type" {
description = "CosmosDB identity type. Possible values for type are: `null` and `SystemAssigned`."
type = string
default = "SystemAssigned"
}

Просмотреть файл

@ -0,0 +1,13 @@
terraform {
required_version = ">= 1.3"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.22"
}
azurecaf = {
source = "aztfmod/azurecaf"
version = "~> 1.2, >= 1.2.22"
}
}
}