forked from hashicorp/terraform-azurerm-hcp-consul
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.tf
187 lines (166 loc) · 7 KB
/
main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
terraform {
required_version = ">= 1.0.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.59"
}
azuread = {
source = "hashicorp/azuread"
version = "~> 2.14"
}
hcp = {
source = "hashicorp/hcp"
version = ">= 0.23.1"
}
}
provider_meta "hcp" {
module_name = "hcp-consul"
}
}
locals {
ingress_consul_rules = [
{
description = "Consul LAN Serf (tcp)"
rule_name = "consul-lan-tcp"
port = 8301
protocol = "Tcp"
},
{
description = "Consul LAN Serf (udp)"
rule_name = "consul-lan-udp"
port = 8301
protocol = "Udp"
},
]
# If a list of security_group_ids was provided, construct a rule set.
hcp_consul_security_groups = flatten([
for _, sg in var.security_group_names : [
for i, rule in local.ingress_consul_rules : {
description = rule.description
destination_port = rule.port
protocol = rule.protocol
rule_name = rule.rule_name
security_group_name = sg
}
]
])
}
# Azure data sources unfortunately rely on name, and resource group name which will never be computed
# fields since they are known input fields. This results in the terraform failing since the data
# source tries to look them up before they are actually created. In aws data sources take computed
# and randomized unique names so we never have this problem.
#
# To get around this we are using the id of the vnet and the subnet (which are computed fields)
# to look them up. The benefit of this is that Azure ids have a known structure (unlike aws ids)
# that is unlikely to ever change:
#
# /subscriptions/<subscription id>/resourceGroups/<resource group name>/providers/Microsoft.Network/virtualNetworks/<vnet name>
#
# Using this known structure we can trim the prefix after matching everything up to virtualNetworks/
data "azurerm_virtual_network" "vnet" {
name = trimprefix(var.vnet_id, regex(".*virtualNetworks\\/", var.vnet_id))
resource_group_name = var.vnet_rg
}
// Similar to above a subnet id will have a known structure that is unlikely to ever change:
//
// "/subscriptions/<subscription ids>/resourceGroups/<resource group name>/providers/Microsoft.Network/virtualNetworks/<vnet name>/subnets/<subnet name>
//
// Using this known strcuture we can trim the prefix after matching everything up to subnets/
data "azurerm_subnet" "selected" {
count = length(var.subnet_ids)
name = trimprefix(var.subnet_ids[count.index], regex(".*subnets\\/", var.subnet_ids[count.index]))
resource_group_name = var.vnet_rg
virtual_network_name = data.azurerm_virtual_network.vnet.name
}
resource "hcp_azure_peering_connection" "peering" {
hvn_link = var.hvn.self_link
peering_id = "${var.prefix}-peer"
peer_vnet_name = data.azurerm_virtual_network.vnet.name
peer_subscription_id = var.subscription_id
peer_tenant_id = var.tenant_id
peer_resource_group_name = var.vnet_rg
peer_vnet_region = data.azurerm_virtual_network.vnet.location
}
resource "azuread_service_principal" "principal" {
application_id = hcp_azure_peering_connection.peering.application_id
}
resource "azurerm_role_definition" "definition" {
name = "${var.prefix}-role-name"
scope = var.vnet_id
assignable_scopes = [
var.vnet_id
]
permissions {
actions = [
"Microsoft.Network/virtualNetworks/peer/action",
"Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read",
"Microsoft.Network/virtualNetworks/virtualNetworkPeerings/write"
]
}
}
resource "azurerm_role_assignment" "role_assignment" {
principal_id = azuread_service_principal.principal.id
role_definition_id = azurerm_role_definition.definition.role_definition_resource_id
scope = var.vnet_id
}
data "hcp_azure_peering_connection" "peering" {
hvn_link = var.hvn.self_link
peering_id = hcp_azure_peering_connection.peering.peering_id
wait_for_active_state = true
}
# HVN route tables to point to subnets
resource "hcp_hvn_route" "route" {
count = length(data.azurerm_subnet.selected)
hvn_link = var.hvn.self_link
hvn_route_id = "${var.prefix}-${count.index}"
# TODO: handle multiple cidrs attached to a single subnet. Taking first for now
destination_cidr = data.azurerm_subnet.selected[count.index].address_prefixes[0]
target_link = data.hcp_azure_peering_connection.peering.self_link
}
resource "azurerm_network_security_rule" "hcp_consul_existing_sg_rules" {
count = length(local.hcp_consul_security_groups)
access = "Allow"
description = local.hcp_consul_security_groups[count.index].description
destination_address_prefix = "*"
destination_port_range = local.hcp_consul_security_groups[count.index].destination_port
direction = "Inbound"
name = "${var.prefix}-${local.hcp_consul_security_groups[count.index].rule_name}"
network_security_group_name = local.hcp_consul_security_groups[count.index].security_group_name
priority = 100 + count.index
protocol = local.hcp_consul_security_groups[count.index].protocol
resource_group_name = var.vnet_rg
source_address_prefix = var.hvn.cidr_block
source_port_range = "*"
}
# If no security_group_names were provided, create a new security_group.
resource "azurerm_network_security_group" "nsg" {
count = length(var.security_group_names) == 0 ? 1 : 0
name = "${var.prefix}-nsg"
location = data.azurerm_virtual_network.vnet.location
resource_group_name = var.vnet_rg
}
# If no security_group_names were provided associate the new security
# group with all the subnets
resource "azurerm_subnet_network_security_group_association" "subnetnsg" {
count = length(var.security_group_names) == 0 ? length(var.subnet_ids) : 0
subnet_id = var.subnet_ids[count.index]
network_security_group_id = azurerm_network_security_group.nsg[0].id
}
# If no security_group_ids were provided, use the new security_group.
resource "azurerm_network_security_rule" "hcp_consul_new_sg_rules" {
count = length(var.security_group_names) == 0 ? length(local.ingress_consul_rules) : 0
access = "Allow"
destination_address_prefix = "*"
destination_port_range = local.ingress_consul_rules[count.index].port
direction = "Inbound"
name = "${var.prefix}-${local.ingress_consul_rules[count.index].rule_name}"
network_security_group_name = azurerm_network_security_group.nsg[0].name
priority = 100 + count.index
protocol = local.ingress_consul_rules[count.index].protocol
resource_group_name = var.vnet_rg
source_address_prefix = var.hvn.cidr_block
source_port_range = "*"
}