Skip to content

Commit 0de113f

Browse files
authored
fix: fixed timing bug with auth policy creation<br>* updated existing_kms_guid to now be existing_kms_crn (#10)
1 parent 7ff0925 commit 0de113f

File tree

7 files changed

+110
-34
lines changed

7 files changed

+110
-34
lines changed

cra-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ CRA_TARGETS:
66
PROFILE_ID: "bfacb71d-4b84-41ac-9825-e8a3a3eb7405" # SCC profile ID (currently set to IBM Cloud Framework for Financial Services 1.6.0 profile).
77
CRA_ENVIRONMENT_VARIABLES:
88
TF_VAR_resource_group_name: "test"
9-
TF_VAR_existing_kms_guid: "XXXXXXXXXXXXXXXX"
9+
TF_VAR_existing_kms_crn: "XXXX:hs-crypto:XXXXXXX:XXXXX:XXXXX"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ibmcloud_api_key": $VALIDATION_APIKEY,
33
"resource_group_name": $PREFIX,
4-
"existing_kms_guid": $HPCS_US_SOUTH_GUID,
4+
"existing_kms_crn": $HPCS_US_SOUTH_CRN,
55
"kms_region": "us-south"
66
}

solutions/instances/main.tf

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@
55
locals {
66
archive_api_key = var.log_archive_api_key == null ? var.ibmcloud_api_key : var.log_archive_api_key
77

8-
cos_instance_crn = var.existing_cos_instance_crn != null ? var.existing_cos_instance_crn : module.cos[0].cos_instance_crn
9-
archive_cos_bucket_name = var.existing_log_archive_cos_bucket_name != null ? var.existing_log_archive_cos_bucket_name : module.cos[0].buckets[var.log_archive_cos_bucket_name].bucket_name
10-
archive_cos_bucket_endpoint = var.existing_log_archive_cos_bucket_endpoint != null ? var.existing_log_archive_cos_bucket_endpoint : module.cos[0].buckets[var.log_archive_cos_bucket_name].s3_endpoint_private
8+
cos_instance_crn = var.existing_cos_instance_crn != null ? var.existing_cos_instance_crn : module.cos_instance[0].cos_instance_crn
9+
existing_kms_guid = var.existing_kms_crn != null ? element(split(":", var.existing_kms_crn), length(split(":", var.existing_kms_crn)) - 3) : length(local.bucket_config_map) == 2 ? null : tobool("The CRN of the existing KMS is not provided.")
10+
cos_instance_guid = var.existing_cos_instance_crn == null ? module.cos_instance[0].cos_instance_guid : element(split(":", var.existing_cos_instance_crn), length(split(":", var.existing_cos_instance_crn)) - 3)
11+
archive_cos_bucket_name = var.existing_log_archive_cos_bucket_name != null ? var.existing_log_archive_cos_bucket_name : module.cos_bucket[0].buckets[var.log_archive_cos_bucket_name].bucket_name
12+
archive_cos_bucket_endpoint = var.existing_log_archive_cos_bucket_endpoint != null ? var.existing_log_archive_cos_bucket_endpoint : module.cos_bucket[0].buckets[var.log_archive_cos_bucket_name].s3_endpoint_private
1113
cos_kms_key_crn = (var.existing_log_archive_cos_bucket_name != null && var.existing_at_cos_target_bucket_name != null) ? null : var.existing_cos_kms_key_crn != null ? var.existing_cos_kms_key_crn : module.kms[0].keys[format("%s.%s", var.cos_key_ring_name, var.cos_key_name)].crn
1214

13-
cos_target_bucket_name = var.existing_at_cos_target_bucket_name != null ? var.existing_at_cos_target_bucket_name : module.cos[0].buckets[var.at_cos_target_bucket_name].bucket_name
14-
cos_target_bucket_endpoint = var.existing_at_cos_target_bucket_endpoint != null ? var.existing_at_cos_target_bucket_endpoint : module.cos[0].buckets[var.at_cos_target_bucket_name].s3_endpoint_private
15+
cos_target_bucket_name = var.existing_at_cos_target_bucket_name != null ? var.existing_at_cos_target_bucket_name : module.cos_bucket[0].buckets[var.at_cos_target_bucket_name].bucket_name
16+
cos_target_bucket_endpoint = var.existing_at_cos_target_bucket_endpoint != null ? var.existing_at_cos_target_bucket_endpoint : module.cos_bucket[0].buckets[var.at_cos_target_bucket_name].s3_endpoint_private
1517

1618
bucket_config_1 = var.existing_log_archive_cos_bucket_name == null ? {
17-
class = var.log_archive_cos_bucket_class
18-
name = var.log_archive_cos_bucket_name
19-
tag = var.archive_bucket_access_tags
20-
policy = var.skip_cos_kms_auth_policy
19+
class = var.log_archive_cos_bucket_class
20+
name = var.log_archive_cos_bucket_name
21+
tag = var.archive_bucket_access_tags
2122
} : null
2223

2324
bucket_config_2 = var.existing_at_cos_target_bucket_name == null ? {
24-
class = var.at_cos_target_bucket_class
25-
name = var.at_cos_target_bucket_name
26-
tag = var.at_cos_bucket_access_tags
27-
policy = var.skip_cos_kms_auth_policy == true ? false : true
25+
class = var.at_cos_target_bucket_class
26+
name = var.at_cos_target_bucket_name
27+
tag = var.at_cos_bucket_access_tags
2828
} : null
2929

3030
bucket_config_map = var.existing_log_archive_cos_bucket_name == null ? (
@@ -43,6 +43,12 @@ locals {
4343
enable = true
4444
days = 366
4545
} : null
46+
47+
kms_service = var.existing_kms_crn != null ? (
48+
can(regex(".*kms.*", var.existing_kms_crn)) ? "kms" : (
49+
can(regex(".*hs-crypto.*", var.existing_kms_crn)) ? "hs-crypto" : null
50+
)
51+
) : null
4652
}
4753

4854
#######################################################################################################################
@@ -51,7 +57,7 @@ locals {
5157

5258
module "resource_group" {
5359
source = "terraform-ibm-modules/resource-group/ibm"
54-
version = "1.1.4"
60+
version = "1.1.5"
5561
resource_group_name = var.existing_resource_group == false ? var.resource_group_name : null
5662
existing_resource_group_name = var.existing_resource_group == true ? var.resource_group_name : null
5763
}
@@ -62,7 +68,7 @@ module "resource_group" {
6268

6369
module "observability_instance" {
6470
source = "terraform-ibm-modules/observability-instances/ibm"
65-
version = "2.11.0"
71+
version = "2.12.2"
6672
providers = {
6773
logdna.at = logdna.at
6874
logdna.ld = logdna.ld
@@ -121,12 +127,12 @@ module "kms" {
121127
providers = {
122128
ibm = ibm.kms
123129
}
124-
count = (var.existing_cos_kms_key_crn != null || (var.existing_log_archive_cos_bucket_name != null && var.existing_at_cos_target_bucket_name != null)) ? 0 : 1 # no need to create any KMS resources if passing an existing key, or bucket
130+
count = (var.existing_cos_kms_key_crn != null || (length(local.bucket_config_map) == 0)) ? 0 : 1 # no need to create any KMS resources if passing an existing key, or bucket
125131
source = "terraform-ibm-modules/kms-all-inclusive/ibm"
126-
version = "4.8.3"
132+
version = "4.8.5"
127133
create_key_protect_instance = false
128134
region = var.kms_region
129-
existing_kms_instance_guid = var.existing_kms_guid
135+
existing_kms_instance_guid = local.existing_kms_guid
130136
key_ring_endpoint_type = var.kms_endpoint_type
131137
key_endpoint_type = var.kms_endpoint_type
132138
keys = [
@@ -151,31 +157,61 @@ module "kms" {
151157
# COS
152158
#######################################################################################################################
153159

154-
module "cos" {
160+
# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
161+
resource "time_sleep" "wait_for_authorization_policy" {
162+
depends_on = [ibm_iam_authorization_policy.policy]
163+
count = var.skip_cos_kms_auth_policy ? 0 : 1
164+
create_duration = "30s"
165+
}
166+
167+
# The auth policy is being created here instead of in COS module because of this limitation: https://github.com/terraform-ibm-modules/terraform-ibm-observability-da/issues/8
168+
169+
# Create IAM Authorization Policy to allow COS to access KMS for the encryption key
170+
resource "ibm_iam_authorization_policy" "policy" {
171+
count = (var.skip_cos_kms_auth_policy || (length(local.bucket_config_map) == 0)) ? 0 : 1
172+
source_service_name = "cloud-object-storage"
173+
source_resource_instance_id = local.cos_instance_guid
174+
target_service_name = local.kms_service
175+
target_resource_instance_id = local.existing_kms_guid
176+
roles = ["Reader"]
177+
description = "Allow the COS instance with GUID ${local.cos_instance_guid} reader access to the kms_service instance GUID ${local.existing_kms_guid}"
178+
}
179+
180+
module "cos_instance" {
155181
providers = {
156182
ibm = ibm.cos
157183
}
158-
count = (var.existing_log_archive_cos_bucket_name == null || var.existing_at_cos_target_bucket_name == null) ? 1 : 0 # no need to call COS module if consumer is passing existing COS bucket
184+
count = (var.existing_cos_instance_crn == null) ? 1 : 0 # no need to call COS module if consumer is using existing COS instance
159185
source = "terraform-ibm-modules/cos/ibm//modules/fscloud"
160186
version = "7.5.3"
161187
resource_group_id = module.resource_group.resource_group_id
162-
create_cos_instance = var.existing_cos_instance_crn == null ? true : false # don't create instance if existing one passed in
188+
create_cos_instance = true
163189
create_resource_key = false
164190
cos_instance_name = var.cos_instance_name
165191
cos_tags = var.cos_instance_tags
166192
existing_cos_instance_id = var.existing_cos_instance_crn
167193
access_tags = var.cos_instance_access_tags
168194
cos_plan = "standard"
195+
}
196+
197+
module "cos_bucket" {
198+
depends_on = [time_sleep.wait_for_authorization_policy]
199+
providers = {
200+
ibm = ibm.cos
201+
}
202+
count = (length(local.bucket_config_map) != 0) ? 1 : 0 # no need to call COS module if consumer is using existing COS bucket
203+
source = "terraform-ibm-modules/cos/ibm//modules/buckets"
204+
version = "7.5.3"
169205
bucket_configs = [
170206
for value in local.bucket_config_map :
171207
{
172208
access_tags = value.tag
173209
bucket_name = value.name
174210
add_bucket_name_suffix = var.add_bucket_name_suffix
175211
kms_encryption_enabled = true
176-
kms_guid = var.existing_kms_guid
212+
kms_guid = local.existing_kms_guid
177213
kms_key_crn = local.cos_kms_key_crn
178-
skip_iam_authorization_policy = value.policy
214+
skip_iam_authorization_policy = true
179215
management_endpoint_type = var.management_endpoint_type_for_bucket
180216
storage_class = value.class
181217
resource_instance_id = local.cos_instance_crn

solutions/instances/outputs.tf

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Outputs
33
##############################################################################
44

5+
## Log analysis
56
output "log_analysis_name" {
67
value = module.observability_instance.log_analysis_name
78
description = "The name of the provisioned Log Analysis instance."
@@ -23,6 +24,7 @@ output "log_analysis_ingestion_key" {
2324
sensitive = true
2425
}
2526

27+
## Cloud Monitoring
2628
output "cloud_monitoring_name" {
2729
value = module.observability_instance.cloud_monitoring_name
2830
description = "The name of the provisioned IBM cloud monitoring instance."
@@ -44,22 +46,56 @@ output "cloud_monitoring_access_key" {
4446
sensitive = true
4547
}
4648

49+
## COS Instance
50+
output "cos_instance_id" {
51+
description = "COS instance id"
52+
value = var.existing_cos_instance_crn == null ? module.cos_instance[0].cos_instance_id : null
53+
}
54+
55+
output "cos_instance_guid" {
56+
description = "COS instance guid"
57+
value = var.existing_cos_instance_crn == null ? module.cos_instance[0].cos_instance_guid : null
58+
}
59+
60+
output "cos_instance_name" {
61+
description = "COS instance name"
62+
value = var.existing_cos_instance_crn == null ? module.cos_instance[0].cos_instance_name : null
63+
}
64+
65+
output "cos_instance_crn" {
66+
description = "COS instance crn"
67+
value = var.existing_cos_instance_crn == null ? module.cos_instance[0].cos_instance_crn : null
68+
}
69+
70+
## COS Buckets
4771
output "log_archive_cos_bucket_name" {
48-
value = var.existing_log_archive_cos_bucket_name == null ? module.cos[0].buckets[var.log_archive_cos_bucket_name].bucket_name : var.existing_log_archive_cos_bucket_name
72+
value = var.existing_log_archive_cos_bucket_name == null ? module.cos_bucket[0].buckets[var.log_archive_cos_bucket_name].bucket_name : var.existing_log_archive_cos_bucket_name
4973
description = "The name of log archive COS bucket"
5074
}
5175

5276
output "at_cos_target_bucket_name" {
53-
value = var.existing_at_cos_target_bucket_name == null ? module.cos[0].buckets[var.at_cos_target_bucket_name].bucket_name : var.existing_at_cos_target_bucket_name
54-
description = "The name of the at cos target bucket"
77+
value = var.existing_at_cos_target_bucket_name == null ? module.cos_bucket[0].buckets[var.at_cos_target_bucket_name].bucket_name : var.existing_at_cos_target_bucket_name
78+
description = "The name of the AT target COS bucket"
5579
}
5680

81+
## Activity Tracker
5782
output "at_cos_targets" {
5883
value = module.observability_instance.activity_tracker_targets
59-
description = "The map of created targets"
84+
description = "The map of created activity_tracker targets"
6085
}
6186

6287
output "at_routes" {
6388
value = module.observability_instance.activity_tracker_routes
64-
description = "The map of created routes"
89+
description = "The map of created activity_tracker routes"
90+
}
91+
92+
## KMS
93+
output "kms_key_rings" {
94+
description = "IDs of new KMS Key Rings created"
95+
value = length(module.kms) > 0 ? module.kms[0].key_rings : null
96+
}
97+
98+
output "kms_keys" {
99+
description = "IDs of new KMS Keys created"
100+
value = length(module.kms) > 0 ? module.kms[0].keys : null
65101
}

solutions/instances/variables.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,10 @@ variable "kms_region" {
251251
description = "The region in which KMS instance exists."
252252
}
253253

254-
variable "existing_kms_guid" {
254+
variable "existing_kms_crn" {
255255
type = string
256256
default = null
257-
description = "The GUID of of the KMS instance used for the COS bucket root Key. Only required if not supplying an existing KMS root key and if 'skip_cos_kms_auth_policy' is true."
257+
description = "The CRN of the KMS instance used for the COS bucket root Key. Only required if not supplying an existing KMS root key and if 'skip_cos_kms_auth_policy' is true."
258258
}
259259

260260
variable "existing_cos_kms_key_crn" {

solutions/instances/version.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@ terraform {
1010
source = "logdna/logdna"
1111
version = "1.16.0"
1212
}
13+
time = {
14+
source = "hashicorp/time"
15+
version = "0.11.1"
16+
}
1317
}
1418
}

tests/pr_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func TestInstancesInSchematics(t *testing.T) {
7676
options.TerraformVars = []testschematic.TestSchematicTerraformVar{
7777
{Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true},
7878
{Name: "resource_group_name", Value: options.Prefix, DataType: "string"},
79-
{Name: "existing_kms_guid", Value: permanentResources["hpcs_south"], DataType: "string"},
79+
{Name: "existing_kms_crn", Value: permanentResources["hpcs_south_crn"], DataType: "string"},
8080
{Name: "kms_region", Value: "us-south", DataType: "string"}, // KMS instance is in us-south
8181
{Name: "cos_region", Value: region, DataType: "string"},
8282
{Name: "cos_instance_tags", Value: options.Tags, DataType: "list(string)"},
@@ -104,7 +104,7 @@ func TestRunUpgradeSolutionInstances(t *testing.T) {
104104
options.TerraformVars = map[string]interface{}{
105105
"resource_group_name": options.Prefix,
106106
"cos_instance_access_tags": permanentResources["accessTags"],
107-
"existing_kms_guid": permanentResources["hpcs_south"],
107+
"existing_kms_crn": permanentResources["hpcs_south_crn"],
108108
"kms_endpoint_type": "public",
109109
"kms_region": "us-south",
110110
"management_endpoint_type_for_bucket": "public",

0 commit comments

Comments
 (0)