Skip to content

Commit 5ac15fc

Browse files
vburckhardtAk-skyAashiq-J
authored
feat: add secure-by-default cbr submodule (#267)
Co-authored-by: Akash Kumar <[email protected]> Co-authored-by: Akash Kumar <[email protected]> Co-authored-by: Aashiq-J <[email protected]>
1 parent 4ec347e commit 5ac15fc

File tree

17 files changed

+866
-126
lines changed

17 files changed

+866
-126
lines changed

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
This module can be used to provision and configure [Context Based Restrictions](https://cloud.ibm.com/docs/account?topic=account-context-restrictions-create&interface=ui).
1313

14+
See in particular the [fscloud profile](./profiles/fscloud/) module that enables creating an opiniated account-level coarse-grained set of CBR rules and zones aligned with the "secure by default" principles.
15+
1416
## Usage
1517

1618
```hcl
@@ -55,32 +57,33 @@ You need the following permissions to run this module.
5557
<!-- BEGIN EXAMPLES HOOK -->
5658
## Examples
5759

60+
- [ Pre-wired CBR configuration for FS Cloud example](examples/fscloud)
5861
- [ CBR Multi Service Profile](examples/multi-service-profile)
5962
- [ Multi-zone example](examples/multizone-rule)
6063
- [ Zone example](examples/zone)
6164
<!-- END EXAMPLES HOOK -->
6265
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
63-
## Requirements
66+
### Requirements
6467

6568
| Name | Version |
6669
|------|---------|
6770
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
6871
| <a name="requirement_ibm"></a> [ibm](#requirement\_ibm) | >= 1.49.0 |
6972

70-
## Modules
73+
### Modules
7174

7275
| Name | Source | Version |
7376
|------|--------|---------|
7477
| <a name="module_cbr_rule"></a> [cbr\_rule](#module\_cbr\_rule) | ./cbr-rule-module | n/a |
7578
| <a name="module_cbr_zone"></a> [cbr\_zone](#module\_cbr\_zone) | ./cbr-zone-module | n/a |
7679

77-
## Resources
80+
### Resources
7881

7982
| Name | Type |
8083
|------|------|
8184
| [ibm_iam_account_settings.iam_account_settings](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/iam_account_settings) | data source |
8285

83-
## Inputs
86+
### Inputs
8487

8588
| Name | Description | Type | Default | Required |
8689
|------|-------------|------|---------|:--------:|
@@ -94,7 +97,7 @@ You need the following permissions to run this module.
9497
| <a name="input_rule_description"></a> [rule\_description](#input\_rule\_description) | (Optional, String) The description of the rule | `string` | `null` | no |
9598
| <a name="input_zone_description"></a> [zone\_description](#input\_zone\_description) | (Optional, String) The description of the zone | `string` | `null` | no |
9699

97-
## Outputs
100+
### Outputs
98101

99102
| Name | Description |
100103
|------|-------------|

cbr-service-profile/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ locals {
2929
vpc_zone_list = (length(var.zone_vpc_crn_list) > 0) ? [{
3030
name = "${var.prefix}-cbr-vpc-zone"
3131
account_id = data.ibm_iam_account_settings.iam_account_settings.account_id
32-
zone_description = "cbr-vpc-zone-terraform"
32+
zone_description = "${var.prefix}-cbr-vpc-zone-terraform"
3333
addresses = [
3434
for zone_vpc_crn in var.zone_vpc_crn_list :
3535
{ "type" = "vpc", value = zone_vpc_crn }

cbr-zone-module/variables.tf

Lines changed: 2 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,9 @@ variable "excluded_addresses" {
201201
default = []
202202
validation {
203203
condition = alltrue([
204-
for address in var.excluded_addresses : contains(["ipAddress", "ipRange", "subnet", "vpc", "serviceRef"], address.type)
204+
for address in var.excluded_addresses : contains(["ipAddress", "ipRange", "subnet"], address.type)
205205
])
206-
error_message = "Valid values for address types are 'ipAddress', 'ipRange', 'subnet', 'vpc', and 'serviceRef'"
206+
error_message = "Valid values for address types are 'ipAddress', 'ipRange' and 'subnet'"
207207
}
208208
validation {
209209
condition = alltrue([
@@ -215,121 +215,4 @@ variable "excluded_addresses" {
215215
])
216216
error_message = "Value should be a valid as per the type"
217217
}
218-
219-
validation {
220-
condition = alltrue(
221-
flatten(
222-
[for address in var.excluded_addresses :
223-
(address.ref != null ?
224-
(
225-
alltrue(
226-
[for ref in address.ref : alltrue([
227-
length(address.ref.account_id) >= 1,
228-
length(address.ref.account_id) <= 128,
229-
can(regex("^[a-zA-Z0-9-]+$", address.ref.account_id))
230-
])]
231-
)
232-
) : true
233-
)
234-
]
235-
)
236-
)
237-
error_message = "Value should be a valid account id"
238-
}
239-
240-
validation {
241-
condition = alltrue(
242-
flatten(
243-
[for address in var.excluded_addresses :
244-
(address.ref != null ?
245-
(
246-
alltrue(
247-
[for ref in address.ref : anytrue([
248-
address.ref.location == null,
249-
alltrue([
250-
can(length(address.ref.location) >= 1),
251-
can(length(address.ref.location) <= 128),
252-
can(regex("^[0-9a-z-]+$", address.ref.location))
253-
])
254-
])]
255-
)
256-
) : true
257-
)
258-
]
259-
)
260-
)
261-
error_message = "Value should be a valid location"
262-
}
263-
264-
validation {
265-
condition = alltrue(
266-
flatten(
267-
[for address in var.excluded_addresses :
268-
(address.ref != null ?
269-
(
270-
alltrue(
271-
[for ref in address.ref : anytrue([
272-
address.ref.service_instance == null,
273-
alltrue([
274-
can(length(address.ref.service_instance) >= 1),
275-
can(length(address.ref.service_instance) <= 128),
276-
can(regex("^[0-9a-z-/]+$", address.ref.service_instance))
277-
])
278-
])]
279-
)
280-
) : true
281-
)
282-
]
283-
)
284-
)
285-
error_message = "Value should be a valid service instance"
286-
}
287-
288-
validation {
289-
condition = alltrue(
290-
flatten(
291-
[for address in var.excluded_addresses :
292-
(address.ref != null ?
293-
(
294-
alltrue(
295-
[for ref in address.ref : anytrue([
296-
address.ref.service_name == null,
297-
alltrue([
298-
can(length(address.ref.service_name) >= 1),
299-
can(length(address.ref.service_name) <= 128),
300-
can(regex("^[0-9a-z-/]+$", address.ref.service_name))
301-
])
302-
])]
303-
)
304-
) : true
305-
)
306-
]
307-
)
308-
)
309-
error_message = "Value should be a valid service name"
310-
}
311-
312-
validation {
313-
condition = alltrue(
314-
flatten(
315-
[for address in var.excluded_addresses :
316-
(address.ref != null ?
317-
(
318-
alltrue(
319-
[for ref in address.ref : anytrue([
320-
address.ref.service_type == null,
321-
alltrue([
322-
can(length(address.ref.service_type) >= 1),
323-
can(length(address.ref.service_type) <= 128),
324-
can(regex("^[0-9a-z_]+$", address.ref.service_type))
325-
])
326-
])]
327-
)
328-
) : true
329-
)
330-
]
331-
)
332-
)
333-
error_message = "Value should be a valid service type"
334-
}
335218
}

examples/fscloud/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Pre-wired CBR configuration for FS Cloud example
2+
3+
This example demonstrates how to use the [fscloud profile](../../profiles/fscloud/) module to lay out a complete "secure by default" coarse-grained CBR topology in a given account.
4+
5+
This examples is designed to show case some of the key customization options for the module. In addition to the pre-wired CBR rules documented at [fscloud profile](../../profiles/fscloud/), this examples show how to customize the module to:
6+
1. Open up network traffic flow from ICD mongodb, ICD Postgresql to the Key Protect private endpoints
7+
2. Open up network traffic flow from Schematics to Key Protect public endpoints
8+
3. Open up network traffic flow from a block of IPs to the Schematics public endpoint
9+
4. Open up network traffic flow from the VPC created in this example to ICD postgresql private endpoints
10+
11+
Context: this examples covers a "pseudo" real-world scenario where:
12+
1. ICD Mongodb, and Postgresql instances are encrypted using keys storage in Key Protect.
13+
2. Schematics is used to execute terraform that create Key Protect keys and key ring over its public endpoint
14+
3. Operators used machines with a set list of public IPs to interact with Schematics
15+
4. Applications are running the VPC and need access to PostgreSQL via the private endpoint - eg: a VPE.

examples/fscloud/main.tf

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
##############################################################################
2+
# Resource Group
3+
##############################################################################
4+
5+
module "resource_group" {
6+
source = "terraform-ibm-modules/resource-group/ibm"
7+
version = "1.0.5"
8+
# if an existing resource group is not set (null) create a new one using prefix
9+
resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null
10+
existing_resource_group_name = var.resource_group
11+
}
12+
13+
# ##############################################################################
14+
# # Get Cloud Account ID
15+
# ##############################################################################
16+
data "ibm_iam_account_settings" "iam_account_settings" {
17+
}
18+
19+
##############################################################################
20+
# VPC
21+
##############################################################################
22+
resource "ibm_is_vpc" "example_vpc" {
23+
name = "${var.prefix}-vpc"
24+
resource_group = module.resource_group.resource_group_id
25+
tags = var.resource_tags
26+
}
27+
28+
resource "ibm_is_public_gateway" "testacc_gateway" {
29+
name = "${var.prefix}-pgateway"
30+
vpc = ibm_is_vpc.example_vpc.id
31+
zone = "${var.region}-1"
32+
resource_group = module.resource_group.resource_group_id
33+
}
34+
35+
resource "ibm_is_subnet" "testacc_subnet" {
36+
name = "${var.prefix}-subnet"
37+
vpc = ibm_is_vpc.example_vpc.id
38+
zone = "${var.region}-1"
39+
public_gateway = ibm_is_public_gateway.testacc_gateway.id
40+
total_ipv4_address_count = 256
41+
resource_group = module.resource_group.resource_group_id
42+
}
43+
44+
##############################################################################
45+
# CBR zone & rule creation
46+
##############################################################################
47+
48+
module "cbr_account_level" {
49+
source = "../../profiles/fscloud"
50+
prefix = var.prefix
51+
zone_vpc_crn_list = [ibm_is_vpc.example_vpc.crn]
52+
allow_cos_to_kms = var.allow_cos_to_kms
53+
allow_block_storage_to_kms = var.allow_block_storage_to_kms
54+
allow_roks_to_kms = var.allow_roks_to_kms
55+
allow_vpcs_to_container_registry = var.allow_vpcs_to_container_registry
56+
allow_vpcs_to_cos = var.allow_vpcs_to_cos
57+
58+
## Enable enforcement for key protect as an example
59+
## The other services not referenced here, are either report, or disabled (when not support report)
60+
target_service_details = {
61+
"kms" = {
62+
"enforcement_mode" = "enabled"
63+
}
64+
}
65+
66+
# Demonstrates how additional context to the rules created by this module can be added.
67+
# This example open up:
68+
# 1. Flows from icd mongodb, postgresql to kms on private endpoint
69+
# 2. Flow from schematics on public kms endpoint
70+
# 3. Add a block of ips to schematics public endpoint
71+
# 4. Flow from vpc(s) specified in input zone_vpc_crn_list to postgresql private endpoint
72+
custom_rule_contexts_by_service = {
73+
"kms" = [{
74+
endpointType = "private"
75+
service_ref_names = ["databases-for-mongodb", "databases-for-postgresql"]
76+
},
77+
{
78+
endpointType = "public"
79+
service_ref_names = ["schematics"]
80+
}
81+
],
82+
"schematics" = [{
83+
endpointType = "public"
84+
zone_ids = [module.cbr_zone_operator_ips.zone_id]
85+
}],
86+
"databases-for-postgresql" = [{
87+
endpointType = "private"
88+
## Give access to the zone containing the VPC passed in zone_vpc_crn_list input
89+
add_managed_vpc_zone = true
90+
}]
91+
}
92+
}
93+
94+
## Example of zone using ip addresses, and reference in one of the zone created by the cbr_account_level above.
95+
## A zone used to group operator machine ips.
96+
module "cbr_zone_operator_ips" {
97+
source = "../../cbr-zone-module"
98+
name = "List of operator environment public IPs"
99+
account_id = data.ibm_iam_account_settings.iam_account_settings.account_id
100+
zone_description = "Zone grouping list of known public ips for operator machines"
101+
addresses = [{
102+
type = "subnet"
103+
value = "0.0.0.0/0" # All ip for this public example - this would be narrowed down typically to an enterprise ip block
104+
}]
105+
}
106+
107+
## Examples of data lookup on objects (zone, rule) created by the fscoud profile module
108+
## Get rule targetting "event-notification"
109+
data "ibm_cbr_rule" "event_notification_rule" {
110+
rule_id = module.cbr_account_level.map_target_service_rule_ids["event-notifications"].rule_id
111+
}
112+
113+
## Get zone having "event-notification" as single source
114+
data "ibm_cbr_zone" "event_notifications_zone" {
115+
zone_id = module.cbr_account_level.map_service_ref_name_zoneid["event-notifications"].zone_id
116+
}

examples/fscloud/outputs.tf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
##############################################################################
2+
# Outputs
3+
##############################################################################
4+
5+
output "account_id" {
6+
value = data.ibm_iam_account_settings.iam_account_settings.account_id
7+
description = "Account ID (used in tests)"
8+
}
9+
10+
output "map_service_ref_name_zoneid" {
11+
value = module.cbr_account_level.map_service_ref_name_zoneid
12+
description = "Map of service reference and zone ids"
13+
}
14+
15+
output "map_vpc_zoneid" {
16+
value = module.cbr_account_level.map_vpc_zoneid
17+
description = "Map of VPC and zone ids"
18+
}
19+
20+
output "map_target_service_rule_ids" {
21+
value = module.cbr_account_level.map_target_service_rule_ids
22+
description = "Map of target service and rule ids"
23+
}
24+
25+
output "example_event_notification_zone" {
26+
value = data.ibm_cbr_rule.event_notification_rule
27+
description = "Example of rule created by the module. Demonstrates data lookup."
28+
}
29+
30+
output "example_event_notification_rule" {
31+
value = data.ibm_cbr_zone.event_notifications_zone
32+
description = "Example of zone created by the module. Demonstrates data lookup."
33+
}

examples/fscloud/provider.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
provider "ibm" {
2+
ibmcloud_api_key = var.ibmcloud_api_key
3+
region = var.region
4+
}

0 commit comments

Comments
 (0)