Skip to content

Commit ff2e950

Browse files
committed
adding firewall rules and private endpoint
1 parent ed7fd34 commit ff2e950

File tree

7 files changed

+371
-19
lines changed

7 files changed

+371
-19
lines changed

examples/complete/.terraform.lock.hcl

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/complete/main.tf

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,58 @@ module "redis" {
1111
resource_group_name = "rg-shared-westeurope-01"
1212
location = "westeurope"
1313

14+
# Schedule maintenance for Redis. The default maintenance window is 5 hours
15+
# This does not cover any maintenance done by Azure for updating the underlying platform.
16+
1417
redis_server_settings = {
1518
demoredischache-shared = {
16-
sku_name = "Standard"
17-
capacity = 2
19+
sku_name = "Premium"
20+
capacity = 2
21+
shard_count = 3
22+
zones = ["1", "2", "3"]
23+
enable_non_ssl_port = true
24+
patch_schedule = {
25+
days_of_week = "Monday"
26+
start_hour_utc = 21
27+
}
1828
}
1929
}
2030

31+
#Configure virtual network support for a Premium Azure Cache for Redis instance
32+
subnet_id = "/subscriptions/1e3f0eeb-2235-44cd-b3a3-dcded0861d06/resourceGroups/rg-shared-westeurope-01/providers/Microsoft.Network/virtualNetworks/vnet-shared-hub-westeurope-001/subnets/snet-appgateway"
33+
2134
redis_configuration = {
2235
maxmemory_reserved = 2
2336
maxmemory_delta = 2
2437
maxmemory_policy = "allkeys-lru"
2538
}
39+
/* # Redis data backup
40+
enable_data_persistence = true
41+
data_persistence_backup_frequency = 60
42+
data_persistence_backup_max_snapshot_count = 1
43+
*/
44+
# Firewall Rules to allow azure and external clients and specific Ip address/ranges.
45+
# "name" may only contain alphanumeric characters and underscores
46+
firewall_rules = {
47+
access_to_azure = {
48+
start_ip = "1.2.3.4"
49+
end_ip = "1.2.3.4"
50+
},
51+
desktop_ip = {
52+
start_ip = "49.204.228.223"
53+
end_ip = "49.204.228.223"
54+
}
55+
}
56+
57+
# Creating Private Endpoint requires, VNet name and address prefix to create a subnet
58+
# By default this will create a `privatelink.mysql.database.azure.com` DNS zone.
59+
# To use existing private DNS zone specify `existing_private_dns_zone` with valid zone name
60+
# Private endpoints doesn't work If using `subnet_id` to create redis cache inside a specified virtual network
61+
62+
enable_private_endpoint = true
63+
virtual_network_name = "vnet-shared-hub-westeurope-001"
64+
private_subnet_address_prefix = ["10.1.5.0/29"]
65+
# existing_private_dns_zone = "demo.example.com"
2666

2767
# Tags for Azure Resources
2868
tags = {

examples/complete/output.tf

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
output "redis_cache_instance_id" {
2+
description = "The Route ID of Redis Cache Instance"
3+
value = module.redis.redis_cache_instance_id
4+
}
5+
6+
output "redis_cache_hostname" {
7+
description = "The Hostname of the Redis Instance"
8+
value = module.redis.redis_cache_hostname
9+
}
10+
11+
output "redis_cache_ssl_port" {
12+
description = "The SSL Port of the Redis Instance"
13+
value = module.redis.redis_cache_ssl_port
14+
}
15+
16+
output "redis_cache_port" {
17+
description = "The non-SSL Port of the Redis Instance"
18+
value = module.redis.redis_cache_port
19+
}
20+
21+
output "redis_cache_primary_access_key" {
22+
description = "The Primary Access Key for the Redis Instance"
23+
value = module.redis.redis_cache_primary_access_key
24+
sensitive = true
25+
}
26+
27+
output "redis_cache_secondary_access_key" {
28+
description = "The Secondary Access Key for the Redis Instance"
29+
value = module.redis.redis_cache_secondary_access_key
30+
sensitive = true
31+
}
32+
33+
output "redis_cache_primary_connection_string" {
34+
description = "The primary connection string of the Redis Instance."
35+
value = module.redis.redis_cache_primary_connection_string
36+
sensitive = true
37+
}
38+
39+
output "redis_cache_secondary_connection_string" {
40+
description = "The secondary connection string of the Redis Instance."
41+
value = module.redis.redis_cache_secondary_connection_string
42+
sensitive = true
43+
}
44+
45+
output "redis_configuration_maxclients" {
46+
description = "Returns the max number of connected clients at the same time."
47+
value = module.redis.redis_configuration_maxclients
48+
}

main.tf

Lines changed: 161 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,38 @@ resource "azurerm_resource_group" "rg" {
2222
tags = merge({ "Name" = format("%s", var.resource_group_name) }, var.tags, )
2323
}
2424

25+
#---------------------------------------------------------------
26+
# Storage Account to keep logs and backups - Default is "false"
27+
#----------------------------------------------------------------
28+
29+
resource "random_string" "str" {
30+
count = var.enable_data_persistence ? 1 : 0
31+
length = 6
32+
special = false
33+
upper = false
34+
keepers = {
35+
name = var.storage_account_name
36+
}
37+
}
38+
39+
resource "azurerm_storage_account" "storeacc" {
40+
# for_each = var.redis_configuration != {} ? { for rdb_backup_enabled, v in var.redis_configuration : rdb_backup_enabled => v if v == true } : null
41+
count = var.enable_data_persistence ? 1 : 0
42+
name = var.storage_account_name == null ? "rediscachebkpstore${random_string.str.0.result}" : substr(var.storage_account_name, 0, 24)
43+
resource_group_name = local.resource_group_name
44+
location = local.location
45+
account_kind = "StorageV2"
46+
account_tier = "Standard"
47+
account_replication_type = "GRS"
48+
enable_https_traffic_only = true
49+
min_tls_version = "TLS1_2"
50+
tags = merge({ "Name" = format("%s", "stsqlauditlogs") }, var.tags, )
51+
}
52+
53+
#------------------------------------------------------------
54+
# Redis Cache Instance configuration - Default (required).
55+
#------------------------------------------------------------
56+
2557
resource "azurerm_redis_cache" "main" {
2658
for_each = var.redis_server_settings
2759
name = format("%s", each.key)
@@ -34,30 +66,150 @@ resource "azurerm_redis_cache" "main" {
3466
minimum_tls_version = each.value["minimum_tls_version"]
3567
private_static_ip_address = each.value["private_static_ip_address"]
3668
public_network_access_enabled = each.value["public_network_access_enabled"]
37-
replicas_per_master = each.value["sku_name"] == "Premium" && { for shard_count, v in var.redis_server_settings : shard_count => v } == null ? each.value["replicas_per_master"] : null
38-
shard_count = { for sku_name, v in var.redis_server_settings : sku_name => v } == "Premium" && { for replicas_per_master, v in var.redis_server_settings : replicas_per_master => v } == null ? each.value["shard_count"] : null
69+
replicas_per_master = each.value["sku_name"] == "Premium" ? each.value["replicas_per_master"] : null
70+
shard_count = each.value["sku_name"] == "Premium" ? each.value["shard_count"] : null
3971
subnet_id = each.value["sku_name"] == "Premium" ? var.subnet_id : null
4072
zones = each.value["zones"]
4173
tags = merge({ "Name" = format("%s", each.key) }, var.tags, )
4274

4375
redis_configuration {
76+
# aof_backup_enabled = var.enable_aof_backup
77+
# aof_storage_connection_string_0 = var.enable_aof_backup == true ? azurerm_storage_account.storeacc.0.primary_blob_connection_string : null
78+
# aof_storage_connection_string_1 = var.enable_aof_backup == true ? azurerm_storage_account.storeacc.0.secondary_blob_connection_string : null
4479
enable_authentication = lookup(var.redis_configuration, "enable_authentication", true)
45-
maxfragmentationmemory_reserved = lookup(var.redis_configuration, "maxfragmentationmemory_reserved", null)
46-
maxmemory_delta = lookup(var.redis_configuration, "maxmemory_delta")
80+
maxfragmentationmemory_reserved = each.value["sku_name"] == "Premium" || each.value["sku_name"] == "Standard" ? lookup(var.redis_configuration, "maxfragmentationmemory_reserved") : null
81+
maxmemory_delta = each.value["sku_name"] == "Premium" || each.value["sku_name"] == "Standard" ? lookup(var.redis_configuration, "maxmemory_delta") : null
4782
maxmemory_policy = lookup(var.redis_configuration, "maxmemory_policy")
48-
maxmemory_reserved = lookup(var.redis_configuration, "maxmemory_reserved")
83+
maxmemory_reserved = each.value["sku_name"] == "Premium" || each.value["sku_name"] == "Standard" ? lookup(var.redis_configuration, "maxmemory_reserved") : null
4984
notify_keyspace_events = lookup(var.redis_configuration, "notify_keyspace_events")
50-
rdb_backup_enabled = lookup(var.redis_configuration, "rdb_backup_enabled", false)
51-
rdb_backup_frequency = { for rdb_backup_enabled, v in var.redis_configuration : rdb_backup_enabled => v } == true ? lookup(var.redis_configuration, "rdb_backup_frequency") : null
52-
rdb_backup_max_snapshot_count = { for rdb_backup_enabled, v in var.redis_configuration : rdb_backup_enabled => v } == true ? lookup(var.redis_configuration, "rdb_backup_max_snapshot_count") : null
53-
rdb_storage_connection_string = { for rdb_backup_enabled, v in var.redis_configuration : rdb_backup_enabled => v } == true ? lookup(var.redis_configuration, "rdb_storage_connection_string") : null
85+
rdb_backup_enabled = each.value["sku_name"] == "Premium" && var.enable_data_persistence == true ? true : false
86+
rdb_backup_frequency = each.value["sku_name"] == "Premium" && var.enable_data_persistence == true ? var.data_persistence_backup_frequency : null
87+
rdb_backup_max_snapshot_count = each.value["sku_name"] == "Premium" && var.enable_data_persistence == true ? var.data_persistence_backup_max_snapshot_count : null
88+
rdb_storage_connection_string = each.value["sku_name"] == "Premium" && var.enable_data_persistence == true ? azurerm_storage_account.storeacc.0.primary_blob_connection_string : null
89+
}
90+
91+
patch_schedule {
92+
day_of_week = each.value.patch_schedule["days_of_week"]
93+
start_hour_utc = each.value.patch_schedule["start_hour_utc"]
5494
}
5595

5696
lifecycle {
5797
# A bug in the Redis API where the original storage connection string isn't being returned
5898
ignore_changes = [redis_configuration.0.rdb_storage_connection_string]
5999
}
100+
}
101+
102+
#----------------------------------------------------------------------
103+
# Adding Firewall rules for Redis Cache Instance - Default is "false"
104+
#----------------------------------------------------------------------
105+
resource "azurerm_redis_firewall_rule" "name" {
106+
for_each = var.firewall_rules != null ? { for k, v in var.firewall_rules : k => v if v != null } : {}
107+
name = format("%s", each.key)
108+
redis_cache_name = element([for n in azurerm_redis_cache.main : n.name], 0)
109+
resource_group_name = local.resource_group_name
110+
start_ip = each.value["start_ip"]
111+
end_ip = each.value["end_ip"]
112+
}
113+
60114

115+
#---------------------------------------------------------
116+
# Private Link for SQL Server - Default is "false"
117+
#---------------------------------------------------------
118+
data "azurerm_virtual_network" "vnet01" {
119+
count = var.enable_private_endpoint ? 1 : 0
120+
name = var.virtual_network_name
121+
resource_group_name = local.resource_group_name
61122
}
62123

124+
resource "azurerm_subnet" "snet-ep" {
125+
count = var.enable_private_endpoint ? 1 : 0
126+
name = "snet-endpoint-shared-${local.location}"
127+
resource_group_name = local.resource_group_name
128+
virtual_network_name = data.azurerm_virtual_network.vnet01.0.name
129+
address_prefixes = var.private_subnet_address_prefix
130+
enforce_private_link_endpoint_network_policies = true
131+
}
63132

133+
resource "azurerm_private_endpoint" "pep1" {
134+
count = var.enable_private_endpoint ? 1 : 0
135+
name = format("%s-private-endpoint", element([for n in azurerm_redis_cache.main : n.name], 0))
136+
location = local.location
137+
resource_group_name = local.resource_group_name
138+
subnet_id = azurerm_subnet.snet-ep.0.id
139+
tags = merge({ "Name" = format("%s-private-endpoint", element([for n in azurerm_redis_cache.main : n.name], 0)) }, var.tags, )
140+
141+
private_service_connection {
142+
name = "rediscache-privatelink"
143+
is_manual_connection = false
144+
private_connection_resource_id = element([for i in azurerm_redis_cache.main : i.id], 0)
145+
subresource_names = ["redisCache"]
146+
}
147+
}
148+
149+
data "azurerm_private_endpoint_connection" "private-ip1" {
150+
count = var.enable_private_endpoint ? 1 : 0
151+
name = azurerm_private_endpoint.pep1.0.name
152+
resource_group_name = local.resource_group_name
153+
depends_on = [azurerm_redis_cache.main]
154+
}
155+
156+
resource "azurerm_private_dns_zone" "dnszone1" {
157+
count = var.existing_private_dns_zone == null && var.enable_private_endpoint ? 1 : 0
158+
name = "privatelink.redis.cache.windows.net"
159+
resource_group_name = local.resource_group_name
160+
tags = merge({ "Name" = format("%s", "RedisCache-Private-DNS-Zone") }, var.tags, )
161+
}
162+
163+
resource "azurerm_private_dns_zone_virtual_network_link" "vent-link1" {
164+
count = var.existing_private_dns_zone == null && var.enable_private_endpoint ? 1 : 0
165+
name = "vnet-private-zone-link"
166+
resource_group_name = local.resource_group_name
167+
private_dns_zone_name = azurerm_private_dns_zone.dnszone1.0.name
168+
virtual_network_id = data.azurerm_virtual_network.vnet01.0.id
169+
tags = merge({ "Name" = format("%s", "vnet-private-zone-link") }, var.tags, )
170+
}
171+
172+
resource "azurerm_private_dns_a_record" "arecord1" {
173+
count = var.enable_private_endpoint ? 1 : 0
174+
name = element([for n in azurerm_redis_cache.main : n.name], 0)
175+
zone_name = var.existing_private_dns_zone == null ? azurerm_private_dns_zone.dnszone1.0.name : var.existing_private_dns_zone
176+
resource_group_name = local.resource_group_name
177+
ttl = 300
178+
records = [data.azurerm_private_endpoint_connection.private-ip1.0.private_service_connection.0.private_ip_address]
179+
}
180+
181+
#------------------------------------------------------------------
182+
# azurerm monitoring diagnostics - Default is "false"
183+
#------------------------------------------------------------------
184+
/*
185+
resource "azurerm_monitor_diagnostic_setting" "extaudit" {
186+
count = var.log_analytics_workspace_name != null ? 1 : 0
187+
name = lower("extaudit-${var.mysqlserver_name}-diag")
188+
target_resource_id = azurerm_mysql_server.main.id
189+
log_analytics_workspace_id = data.azurerm_log_analytics_workspace.logws.0.id
190+
storage_account_id = var.enable_threat_detection_policy ? azurerm_storage_account.storeacc.0.id : null
191+
192+
dynamic "log" {
193+
for_each = var.extaudit_diag_logs
194+
content {
195+
category = log.value
196+
enabled = true
197+
retention_policy {
198+
enabled = false
199+
}
200+
}
201+
}
202+
203+
metric {
204+
category = "AllMetrics"
205+
206+
retention_policy {
207+
enabled = false
208+
}
209+
}
210+
211+
lifecycle {
212+
ignore_changes = [log, metric]
213+
}
214+
}
215+
*/

output.tf

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
output "redis_cache_instance_id" {
2+
description = "The Route ID of Redis Cache Instance"
3+
value = { for k, v in azurerm_redis_cache.main : k => v.id }
4+
}
5+
6+
output "redis_cache_hostname" {
7+
description = "The Hostname of the Redis Instance"
8+
value = { for k, v in azurerm_redis_cache.main : k => v.hostname }
9+
}
10+
11+
output "redis_cache_ssl_port" {
12+
description = "The SSL Port of the Redis Instance"
13+
value = { for k, v in azurerm_redis_cache.main : k => v.ssl_port }
14+
}
15+
16+
output "redis_cache_port" {
17+
description = "The non-SSL Port of the Redis Instance"
18+
value = { for k, v in azurerm_redis_cache.main : k => v.port }
19+
}
20+
21+
output "redis_cache_primary_access_key" {
22+
description = "The Primary Access Key for the Redis Instance"
23+
value = { for k, v in azurerm_redis_cache.main : k => v.primary_access_key }
24+
sensitive = true
25+
}
26+
27+
output "redis_cache_secondary_access_key" {
28+
description = "The Secondary Access Key for the Redis Instance"
29+
value = { for k, v in azurerm_redis_cache.main : k => v.secondary_access_key }
30+
sensitive = true
31+
}
32+
33+
output "redis_cache_primary_connection_string" {
34+
description = "The primary connection string of the Redis Instance."
35+
value = { for k, v in azurerm_redis_cache.main : k => v.primary_connection_string }
36+
sensitive = true
37+
}
38+
39+
output "redis_cache_secondary_connection_string" {
40+
description = "The secondary connection string of the Redis Instance."
41+
value = { for k, v in azurerm_redis_cache.main : k => v.secondary_connection_string }
42+
sensitive = true
43+
}
44+
45+
output "redis_configuration_maxclients" {
46+
description = "Returns the max number of connected clients at the same time."
47+
value = { for k, v in azurerm_redis_cache.main : k => v.redis_configuration.0.maxclients }
48+
}

0 commit comments

Comments
 (0)