@@ -10,6 +10,10 @@ variable "key_management_guid" {
1010 description = " Key management guid"
1111}
1212
13+ variable "key_management_key_map" {
14+ description = " Key management key IDs"
15+ }
16+
1317variable "cos_instance_ids" {
1418 description = " Map of COS instance IDs"
1519}
@@ -38,28 +42,123 @@ variable "clusters" {
3842 description = " Add cluster to kms auth policies"
3943}
4044
45+ variable "vsi" {
46+ description = " Add vsi block storage to auth policies"
47+ }
48+
49+ variable "vpcs" {
50+ description = " Direct reference to vpcs variable"
51+ }
52+
53+ # #############################################################################
54+
55+ # #############################################################################
56+ # BUCKET MAP
57+ # Create a flattened out map of all configured cos buckets.
58+ # This map will have the bucket name as the key, and have attributes
59+ # from both the bucket and the parent instance that we need in further queries.
60+ # This map will be used to perform lookups based on bucket name to get data related to either
61+ # the bucket itself or its parent instance.
4162# #############################################################################
63+ module "cos_bucket_map" {
64+ source = " ../list_to_map"
65+ list = flatten ([
66+ for instance in var . cos :
67+ [
68+ for bucket in instance . buckets :
69+ [
70+ {
71+ name = bucket.name
72+ instance_name = instance.name
73+ bucket_key_name = lookup (bucket, " kms_key" , null )
74+ skip_kms_s2s_auth_policy = lookup (instance, " skip_kms_s2s_auth_policy" , false )
75+ skip_flowlogs_s2s_auth_policy = lookup (instance, " skip_flowlogs_s2s_auth_policy" , false )
76+ skip_atracker_s2s_auth_policy = lookup (instance, " skip_atracker_s2s_auth_policy" , false )
77+ }
78+ ]
79+ ]
80+ ])
81+ }
4282
4383# #############################################################################
4484# Locals
4585# #############################################################################
4686
4787locals {
4888 target_key_management_service = lookup (var. key_management , " name" , null ) != null ? lookup (var. key_management , " use_hs_crypto" , false ) == true ? " hs-crypto" : " kms" : null
89+
90+ # create a list of keys used for all buckets, since we are going to scope the auth policy to keys.
91+ # doing this in a local first becase it needs a distinct to get rid of duplicates from same keys used
92+ # on multiple buckets, and a distinct on the final map may error in terraform for_each before first apply.
93+ cos_bucket_key_list_distinct = distinct (
94+ flatten ([
95+ for bucket in module . cos_bucket_map . value :
96+ [
97+ {
98+ instance_name = bucket.instance_name
99+ bucket_key_name = lookup (bucket, " bucket_key_name" , null )
100+ }
101+ ] if ! bucket . skip_kms_s2s_auth_policy
102+ ])
103+ )
104+
105+ # get all keys that will be used for VSI block storage
106+ # this is combination of all boot volume keys, plus the extra storage volume keys
107+ block_storage_key_list_distinct = distinct (
108+ flatten ([
109+ [
110+ for vsi in var . vsi :
111+ [
112+ { block_key_name = lookup (vsi, " boot_volume_encryption_key_name" , null ) }
113+ ]
114+ ],
115+ [
116+ for vsi in var . vsi :
117+ [
118+ for block in coalesce (lookup (vsi, " block_storage_volumes" , null ), []) :
119+ [
120+ { block_key_name = lookup (block, " encryption_key" , null ) }
121+ ]
122+ ]
123+ ]
124+ ])
125+ )
126+
127+ # get all keys used in clusters
128+ # is combination of boot keys and config keys
129+ kube_key_list_distinct = distinct (
130+ flatten ([
131+ [
132+ for cluster in var . clusters :
133+ [
134+ { cluster_key_name = lookup (cluster, " boot_volume_crk_name" , null ) }
135+ ]
136+ ],
137+ [
138+ for cluster in var . clusters :
139+ [
140+ { cluster_key_name = lookup (cluster. kms_config , " crk_name" , null ) }
141+ ] if lookup (cluster, " kms_config" , null ) != null
142+ ]
143+ ])
144+ )
49145}
50146
51147module "kms_to_block_storage" {
52148 source = " ../list_to_map"
53149 list = [
54- for instance in (var . skip_kms_block_storage_s2s_auth_policy ? [] : [ " block-storage " ]) :
150+ for instance in local . block_storage_key_list_distinct :
55151 {
56- name = instance
152+ name = " block-storage-to- ${ instance . block_key_name } "
57153 source_service_name = " server-protect"
58- description = " Allow block storage volumes to be encrypted by KMS instance "
154+ description = " Allow block storage volumes to be encrypted by KMS key "
59155 roles = [" Reader" ]
60156 target_service_name = local.target_key_management_service
61157 target_resource_instance_id = var.key_management_guid
62- } if local . target_key_management_service != null
158+ target_resource_type = " key"
159+ target_resource_id = split (" :" , var. key_management_key_map [instance . block_key_name ]. crn )[9 ]
160+ target_resource_account_id = trimprefix (split (" :" , var. key_management_key_map [instance . block_key_name ]. crn )[6 ], " a/" )
161+ } if local . target_key_management_service != null && ! var . skip_kms_block_storage_s2s_auth_policy && instance . block_key_name != null
63162 ]
64163}
65164
@@ -69,15 +168,18 @@ module "kms_to_block_storage" {
69168module "kube_to_kms" {
70169 source = " ../list_to_map"
71170 list = [
72- for instance in ( length (var . clusters ) > 0 ? [ " containers-kubernetes " ] : []) :
171+ for instance in local . kube_key_list_distinct :
73172 {
74- name = instance
173+ name = " kube-to- ${ instance . cluster_key_name } "
75174 source_service_name = " containers-kubernetes"
76175 description = " Allow cluster to be encrypted by KMS instance"
77176 roles = [" Reader" ]
78177 target_service_name = local.target_key_management_service
79178 target_resource_instance_id = var.key_management_guid
80- } if local . target_key_management_service != null && ! var . skip_kms_kube_s2s_auth_policy
179+ target_resource_type = " key"
180+ target_resource_id = split (" :" , var. key_management_key_map [instance . cluster_key_name ]. crn )[9 ]
181+ target_resource_account_id = trimprefix (split (" :" , var. key_management_key_map [instance . cluster_key_name ]. crn )[6 ], " a/" )
182+ } if local . target_key_management_service != null && ! var . skip_kms_kube_s2s_auth_policy && instance . cluster_key_name != null
81183 ]
82184}
83185
@@ -90,32 +192,58 @@ module "kube_to_kms" {
90192module "cos_to_key_management" {
91193 source = " ../list_to_map"
92194 list = [
93- for instance in var . cos :
195+ for bucket_key in local . cos_bucket_key_list_distinct :
94196 {
95- name = " cos-${ instance . name } -to-key-management "
197+ name = " cos-${ bucket_key . instance_name } -to-key-${ bucket_key . bucket_key_name } "
96198 source_service_name = " cloud-object-storage"
97- source_resource_instance_id = split (" :" , var. cos_instance_ids [instance . name ])[7 ]
98- description = " Allow COS instance to read from KMS instance "
199+ source_resource_instance_id = split (" :" , var. cos_instance_ids [bucket_key . instance_name ])[7 ]
200+ description = " Allow COS instance to read KMS key "
99201 roles = [" Reader" ]
100202 target_service_name = local.target_key_management_service
101203 target_resource_instance_id = var.key_management_guid
102- } if local . target_key_management_service != null && ! instance . skip_kms_s2s_auth_policy
204+ target_resource_type = " key"
205+ target_resource_id = split (" :" , var. key_management_key_map [bucket_key . bucket_key_name ]. crn )[9 ]
206+ target_resource_account_id = trimprefix (split (" :" , var. key_management_key_map [bucket_key . bucket_key_name ]. crn )[6 ], " a/" )
207+ } if local . target_key_management_service != null && bucket_key . bucket_key_name != null
103208 ]
104209}
105210
211+ # #############################################################################
212+ # VPC Flow Logs to COS bucket
213+ # #############################################################################
214+ locals {
215+ flow_log_bucket_list_distinct = distinct (
216+ flatten ([
217+ for vpc in var . vpcs :
218+ [
219+ {
220+ bucket_name = vpc.flow_logs_bucket_name
221+ }
222+ ] if lookup (vpc, " flow_logs_bucket_name" , null ) != null
223+ ])
224+ )
225+ }
226+
227+ # NOTE:
228+ # Due to terraform plan cycle issues, we cannot reference the true bucket instance here in this module,
229+ # so we will pass back the reference name of the bucket in `target_resource_id` and look up details
230+ # when applying the auth policy
106231module "flow_logs_to_cos" {
107232 source = " ../list_to_map"
108233 list = [
109- for instance in var . cos :
234+ for instance in local . flow_log_bucket_list_distinct :
110235 {
111- name = " flow-logs-${ instance . name } "
236+ name = " flow-logs-${ instance . bucket_name } "
112237 source_service_name = " is"
113238 source_resource_type = " flow-log-collector"
114239 description = " Allow flow logs write access cloud object storage instance"
115240 roles = [" Writer" ]
116241 target_service_name = " cloud-object-storage"
117- target_resource_instance_id = split (" :" , var. cos_instance_ids [instance . name ])[7 ]
118- } if ! instance . skip_flowlogs_s2s_auth_policy
242+ target_resource_instance_id = null
243+ target_resource_type = " bucket"
244+ target_resource_id = instance.bucket_name
245+ target_resource_account_id = null
246+ } if ! module . cos_bucket_map . value [instance . bucket_name ]. skip_flowlogs_s2s_auth_policy
119247 ]
120248}
121249
@@ -125,30 +253,29 @@ module "flow_logs_to_cos" {
125253# Atracker to COS
126254# #############################################################################
127255
128- locals {
129- atracker_cos_instance = var. atracker_cos_bucket == null ? null : one (flatten ([
130- for instance in var . cos :
131- [
132- for bucket in instance . buckets :
133- [instance . name ] if bucket . name == var . atracker_cos_bucket
134- ] if ! instance . skip_atracker_s2s_auth_policy
135- ]))
136- }
137-
256+ # NOTE:
257+ # Due to terraform plan cycle issues, we cannot reference the true bucket instance here in this module,
258+ # so we will pass back the reference name of the bucket in `target_resource_id` and look up details
259+ # when applying the auth policy
138260module "atracker_to_cos" {
139261 source = " ../list_to_map"
140262 list = [
141- for instance in (var . atracker_cos_bucket != null && local . atracker_cos_instance != null ? [" atracker-to-cos" ] : []) :
263+ for instance in [" atracker-to-cos" ] :
142264 {
143265 name = instance
144266 source_service_name = " atracker"
145- description = " Allow atracker to write to COS"
267+ description = " Allow atracker to write to COS bucket "
146268 roles = [" Object Writer" ]
147269 target_service_name = " cloud-object-storage"
148- target_resource_instance_id = split (" :" , var. cos_instance_ids [local . atracker_cos_instance ])[7 ]
149- }
270+ target_resource_instance_id = null
271+ target_resource_type = " bucket"
272+ target_resource_id = var.atracker_cos_bucket
273+ target_resource_account_id = null
274+ } if var . atracker_cos_bucket != null && ! try (module. cos_bucket_map . value [var . atracker_cos_bucket ]. skip_atracker_s2s_auth_policy , false )
150275 ]
151276}
277+ # DEV NOTE: needed a `try()` on the `cos_bucket_map` lookup above to take care of the case where atracker is turned off
278+ # and a bucket name is NULL. This causes plan errors which the try should catch.
152279
153280# #############################################################################
154281# Outputs
0 commit comments