-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathmain.tf
More file actions
365 lines (327 loc) · 16.7 KB
/
main.tf
File metadata and controls
365 lines (327 loc) · 16.7 KB
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
#######################################################################################################################
# Resource Group
#######################################################################################################################
module "resource_group" {
source = "terraform-ibm-modules/resource-group/ibm"
version = "1.6.0"
existing_resource_group_name = var.existing_resource_group_name
}
#######################################################################################################################
# KMS Key
#######################################################################################################################
module "existing_kms_crn_parser" {
count = var.existing_kms_instance_crn != null ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.5.0"
crn = var.existing_kms_instance_crn
}
module "existing_boot_volume_kms_key_crn_parser" {
count = var.existing_boot_volume_kms_key_crn != null ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.5.0"
crn = var.existing_boot_volume_kms_key_crn
}
locals {
boot_volume_key_ring_name = "${local.prefix}${var.boot_volume_key_ring_name}"
boot_volume_key_name = "${local.prefix}${var.boot_volume_key_name}"
kms_region = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].region : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].region : null
existing_kms_guid = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].service_instance : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].service_instance : null
kms_service_name = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].service_name : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].service_name : null
kms_account_id = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].account_id : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].account_id : null
kms_key_id = var.existing_kms_instance_crn != null ? module.kms[0].keys[format("%s.%s", local.boot_volume_key_ring_name, local.boot_volume_key_name)].key_id : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].resource : null
boot_volume_kms_key_crn = var.kms_encryption_enabled_boot_volume ? var.existing_boot_volume_kms_key_crn != null ? var.existing_boot_volume_kms_key_crn : module.kms[0].keys[format("%s.%s", local.boot_volume_key_ring_name, local.boot_volume_key_name)].crn : null
create_cross_account_auth_policy = !var.skip_block_storage_kms_iam_auth_policy && var.ibmcloud_kms_api_key == null ? false : (data.ibm_iam_account_settings.iam_account_settings.account_id != local.kms_account_id)
}
data "ibm_iam_account_settings" "iam_account_settings" {
}
resource "ibm_iam_authorization_policy" "block_storage_kms_policy" {
count = local.create_cross_account_auth_policy ? 1 : 0
provider = ibm.kms
source_service_account = data.ibm_iam_account_settings.iam_account_settings.account_id
source_service_name = "server-protect"
roles = ["Reader"]
description = "Allow block storage volumes to read the ${local.kms_service_name} key ${local.kms_key_id} from the instance ${local.existing_kms_guid}"
resource_attributes {
name = "serviceName"
operator = "stringEquals"
value = local.kms_service_name
}
resource_attributes {
name = "accountId"
operator = "stringEquals"
value = local.kms_account_id
}
resource_attributes {
name = "serviceInstance"
operator = "stringEquals"
value = local.existing_kms_guid
}
resource_attributes {
name = "resourceType"
operator = "stringEquals"
value = "key"
}
resource_attributes {
name = "resource"
operator = "stringEquals"
value = local.kms_key_id
}
# Scope of policy now includes the key, so ensure to create new policy before
# destroying old one to prevent any disruption to every day services.
lifecycle {
create_before_destroy = true
}
}
# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
resource "time_sleep" "wait_for_authorization_policy" {
depends_on = [ibm_iam_authorization_policy.block_storage_kms_policy]
count = local.create_cross_account_auth_policy ? 1 : 0
create_duration = "30s"
}
# KMS root key for boot volume encryption
module "kms" {
providers = {
ibm = ibm.kms
}
count = var.kms_encryption_enabled_boot_volume && var.existing_boot_volume_kms_key_crn == null ? 1 : 0
source = "terraform-ibm-modules/kms-all-inclusive/ibm"
version = "5.6.0"
create_key_protect_instance = false
region = local.kms_region
existing_kms_instance_crn = var.existing_kms_instance_crn
key_ring_endpoint_type = var.kms_endpoint_type
key_endpoint_type = var.kms_endpoint_type
keys = [
{
key_ring_name = local.boot_volume_key_ring_name
existing_key_ring = false
keys = [
{
key_name = local.boot_volume_key_name
standard_key = false
rotation_interval_month = 3
dual_auth_delete_enabled = false
force_delete = var.force_delete_kms_key
}
]
}
]
}
#######################################################################################################################
# VSI
#######################################################################################################################
module "existing_vpc_crn_parser" {
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.5.0"
crn = var.existing_vpc_crn
}
locals {
vpc_region = module.existing_vpc_crn_parser.region
existing_vpc_id = module.existing_vpc_crn_parser.resource
}
data "ibm_is_subnet" "subnet" {
count = var.existing_subnet_id != null ? 1 : 0
identifier = var.existing_subnet_id
}
data "ibm_is_vpc" "vpc" {
identifier = local.existing_vpc_id
}
data "ibm_is_subnet" "secondary_subnet" {
count = var.existing_secondary_subnet_id != null ? 1 : 0
identifier = var.existing_secondary_subnet_id
}
locals {
prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : ""
# When `existing_subnet_id` is not provided, use the first subnet from the existing VPC.
subnet = var.existing_subnet_id != null ? [{
name = data.ibm_is_subnet.subnet[0].name
id = data.ibm_is_subnet.subnet[0].id
zone = data.ibm_is_subnet.subnet[0].zone
}] : [{
name = data.ibm_is_vpc.vpc.subnets[0].name
id = data.ibm_is_vpc.vpc.subnets[0].id
zone = data.ibm_is_vpc.vpc.subnets[0].zone
}]
secondary_subnet = var.existing_secondary_subnet_id != null ? [{
name = data.ibm_is_subnet.secondary_subnet[0].name
id = data.ibm_is_subnet.secondary_subnet[0].id
zone = data.ibm_is_subnet.secondary_subnet[0].zone
}] : []
ssh_keys = concat(
var.existing_ssh_key_ids != null ? var.existing_ssh_key_ids : [],
length(var.ssh_public_keys) > 0 ? [for ssh in ibm_is_ssh_key.ssh_key : ssh.id] : [],
var.auto_generate_ssh_key ? [ibm_is_ssh_key.auto_generate_ssh_key[0].id] : []
)
custom_vsi_volume_names = { (var.existing_subnet_id != null ? data.ibm_is_subnet.subnet[0].name : data.ibm_is_vpc.vpc.subnets[0].name) = {
"${local.prefix}${var.vsi_name}" = [for block in var.block_storage_volumes : block.name] } }
}
##############################################################################
# Create New SSH Key
##############################################################################
resource "ibm_is_ssh_key" "ssh_key" {
for_each = { for idx, ssh in var.ssh_public_keys :
idx => ssh }
name = "${local.prefix}${var.vsi_name}-ssh-key-${each.key}"
public_key = replace(each.value, "/==.*$/", "==")
resource_group = module.resource_group.resource_group_id
tags = var.vsi_resource_tags
}
resource "tls_private_key" "auto_generate_ssh_key" {
count = var.auto_generate_ssh_key ? 1 : 0
algorithm = "RSA"
rsa_bits = 4096
}
resource "ibm_is_ssh_key" "auto_generate_ssh_key" {
count = var.auto_generate_ssh_key ? 1 : 0
name = "${var.prefix}${var.vsi_name}-ssh-key"
public_key = resource.tls_private_key.auto_generate_ssh_key[0].public_key_openssh
}
########################################################################################################################
# Virtual Server Instance
########################################################################################################################
module "vsi" {
source = "../../"
depends_on = [time_sleep.wait_for_authorization_policy[0]]
resource_group_id = module.resource_group.resource_group_id
prefix = "${local.prefix}${var.vsi_name}"
tags = var.vsi_resource_tags
vpc_id = local.existing_vpc_id
subnets = local.subnet
image_id = var.image_id
ssh_key_ids = local.ssh_keys
machine_type = var.machine_type
vsi_per_subnet = 1
user_data = var.user_data
skip_iam_authorization_policy = local.create_cross_account_auth_policy ? false : var.skip_block_storage_kms_iam_auth_policy
boot_volume_encryption_key = local.boot_volume_kms_key_crn
boot_volume_size = var.boot_volume_size
use_boot_volume_key_as_default = var.use_boot_volume_key_as_default
kms_encryption_enabled = var.kms_encryption_enabled_boot_volume
manage_reserved_ips = var.manage_reserved_ips
use_static_boot_volume_name = var.use_static_boot_volume_name
enable_floating_ip = var.enable_floating_ip
allow_ip_spoofing = var.allow_ip_spoofing
create_security_group = var.security_group != null ? true : false
security_group = var.security_group
security_group_ids = var.security_group_ids
block_storage_volumes = var.block_storage_volumes
load_balancers = var.load_balancers
access_tags = var.vsi_access_tags
snapshot_consistency_group_id = var.snapshot_consistency_group_id
boot_volume_snapshot_crn = var.boot_volume_snapshot_crn
enable_dedicated_host = var.dedicated_host_id != null ? true : false
dedicated_host_id = var.dedicated_host_id
use_legacy_network_interface = false
secondary_allow_ip_spoofing = var.secondary_allow_ip_spoofing
secondary_floating_ips = var.secondary_floating_ips
secondary_security_groups = var.secondary_security_groups
secondary_use_vsi_security_group = var.secondary_use_vsi_security_group
secondary_subnets = local.secondary_subnet
placement_group_id = var.placement_group_id
primary_vni_additional_ip_count = var.primary_virtual_network_interface_additional_ip_count
custom_vsi_volume_names = local.custom_vsi_volume_names
install_logging_agent = var.install_logging_agent
logging_target_host = var.logging_target_host
logging_target_port = var.logging_target_port
logging_target_path = var.logging_target_path
logging_auth_mode = var.logging_auth_mode
logging_api_key = var.logging_api_key
logging_trusted_profile_id = var.logging_auth_mode == "VSITrustedProfile" ? (var.logging_trusted_profile_id != null ? var.logging_trusted_profile_id : (local.create_logging_trusted_profile ? module.trusted_profile[0].profile_id : null)) : null
logging_use_private_endpoint = var.logging_use_private_endpoint
logging_subsystem_name = var.logging_subsystem_name
logging_application_name = var.logging_application_name
logging_secure_access_enabled = var.logging_secure_access_enabled
logging_agent_version = var.logging_agent_version
install_monitoring_agent = var.install_monitoring_agent
monitoring_access_key = var.monitoring_access_key
monitoring_collector_endpoint = var.monitoring_collector_endpoint
monitoring_collector_port = var.monitoring_collector_port
monitoring_tags = var.monitoring_tags
monitoring_agent_version = var.monitoring_agent_version
}
########################################################################################################################
# Trusted Profile for Logging Agent
########################################################################################################################
locals {
# Determine if we need to create a trusted profile
create_logging_trusted_profile = var.install_logging_agent && var.logging_auth_mode == "VSITrustedProfile" && var.logging_trusted_profile_id == null
# Extract Cloud Logs instance ID from ingress endpoint
cloud_logs_instance_id = var.logging_target_host != null ? element(split(".", var.logging_target_host), 0) : null
}
module "trusted_profile" {
count = local.create_logging_trusted_profile ? 1 : 0
source = "terraform-ibm-modules/trusted-profile/ibm"
version = "3.3.0"
trusted_profile_name = "${local.prefix}-vsi-logging-trusted-profile"
trusted_profile_description = "Trusted profile for VSI instances to send logs to IBM Cloud Logs instance - ${local.cloud_logs_instance_id}"
# Create links to VSI instances
trusted_profile_links = [
for vsi in module.vsi.list : {
unique_identifier = "trusted-profile-link"
cr_type = "VSI"
name = "${vsi.name}-link"
links = [
{
crn = vsi.crn
name = vsi.name
}
]
}
]
# Create policy to grant Sender access to Cloud Logs
trusted_profile_policies = [
{
unique_identifier = "vsi-logging-policy"
roles = ["Sender"]
resource_attributes = concat(
[
{
name = "serviceName"
operator = "stringEquals"
value = "logs"
}
],
local.cloud_logs_instance_id != null ? [
{
name = "serviceInstance"
operator = "stringEquals"
value = local.cloud_logs_instance_id
}
] : []
)
}
]
}
########################################################################################################################
# Secrets Manager
########################################################################################################################
module "existing_secret_manager_crn_parser" {
count = var.existing_secrets_manager_instance_crn != null ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.5.0"
crn = var.existing_secrets_manager_instance_crn
}
locals {
existing_secrets_manager_instance_guid = var.existing_secrets_manager_instance_crn != null ? module.existing_secret_manager_crn_parser[0].service_instance : null
existing_secrets_manager_instance_region = var.existing_secrets_manager_instance_crn != null ? module.existing_secret_manager_crn_parser[0].region : null
}
module "secrets_manager_arbitrary_secret" {
count = var.existing_secrets_manager_instance_crn != null && var.auto_generate_ssh_key ? 1 : 0
source = "terraform-ibm-modules/secrets-manager/ibm//modules/secrets"
version = "2.14.0"
existing_sm_instance_guid = local.existing_secrets_manager_instance_guid
existing_sm_instance_region = local.existing_secrets_manager_instance_region
endpoint_type = var.existing_secrets_manager_endpoint_type
secrets = [{
secret_group_name = "${local.prefix}${var.ssh_key_secret_group_name}"
secret_group_description = "The ssh private key secret group."
secrets = [
{
secret_name = "${local.prefix}${var.ssh_key_secret_name}"
secret_description = "The ssh private key data in [PEM (RFC 1421)](https://datatracker.ietf.org/doc/html/rfc1421) format."
secret_type = "arbitrary"
secret_payload_password = tls_private_key.auto_generate_ssh_key[0].private_key_pem
}
]
}]
}