Skip to content

Commit 6cd3eb3

Browse files
feat: add support to enable vpc flow logs (#411)
1 parent 717a362 commit 6cd3eb3

File tree

8 files changed

+288
-8
lines changed

8 files changed

+288
-8
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ You need the following permissions to run this module.
8484

8585
| Name | Type |
8686
|------|------|
87+
| [ibm_iam_authorization_policy.policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource |
88+
| [ibm_is_flow_log.flow_logs](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_flow_log) | resource |
8789
| [ibm_is_network_acl.network_acl](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_network_acl) | resource |
8890
| [ibm_is_public_gateway.gateway](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_public_gateway) | resource |
8991
| [ibm_is_security_group_rule.default_vpc_rule](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_security_group_rule) | resource |
@@ -100,9 +102,14 @@ You need the following permissions to run this module.
100102
|------|-------------|------|---------|:--------:|
101103
| <a name="input_address_prefixes"></a> [address\_prefixes](#input\_address\_prefixes) | OPTIONAL - IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes | <pre>object({<br> zone-1 = optional(list(string))<br> zone-2 = optional(list(string))<br> zone-3 = optional(list(string))<br> })</pre> | <pre>{<br> "zone-1": null,<br> "zone-2": null,<br> "zone-3": null<br>}</pre> | no |
102104
| <a name="input_classic_access"></a> [classic\_access](#input\_classic\_access) | OPTIONAL - Classic Access to the VPC | `bool` | `false` | no |
105+
| <a name="input_create_authorization_policy_vpc_to_cos"></a> [create\_authorization\_policy\_vpc\_to\_cos](#input\_create\_authorization\_policy\_vpc\_to\_cos) | Create authorisation policy for VPC to access COS. Set as false if authorization policy exists already | `bool` | `false` | no |
103106
| <a name="input_default_network_acl_name"></a> [default\_network\_acl\_name](#input\_default\_network\_acl\_name) | OPTIONAL - Name of the Default ACL. If null, a name will be automatically generated | `string` | `null` | no |
104107
| <a name="input_default_routing_table_name"></a> [default\_routing\_table\_name](#input\_default\_routing\_table\_name) | OPTIONAL - Name of the Default Routing Table. If null, a name will be automatically generated | `string` | `null` | no |
105108
| <a name="input_default_security_group_name"></a> [default\_security\_group\_name](#input\_default\_security\_group\_name) | OPTIONAL - Name of the Default Security Group. If null, a name will be automatically generated | `string` | `null` | no |
109+
| <a name="input_enable_vpc_flow_logs"></a> [enable\_vpc\_flow\_logs](#input\_enable\_vpc\_flow\_logs) | Flag to enable vpc flow logs. If true, flow log collector will be created | `bool` | `false` | no |
110+
| <a name="input_existing_cos_instance_guid"></a> [existing\_cos\_instance\_guid](#input\_existing\_cos\_instance\_guid) | GUID of the COS instance to create Flow log collector | `string` | `null` | no |
111+
| <a name="input_existing_storage_bucket_name"></a> [existing\_storage\_bucket\_name](#input\_existing\_storage\_bucket\_name) | Name of the COS bucket to collect VPC flow logs | `string` | `null` | no |
112+
| <a name="input_is_flow_log_collector_active"></a> [is\_flow\_log\_collector\_active](#input\_is\_flow\_log\_collector\_active) | Indicates whether the collector is active. If false, this collector is created in inactive mode. | `bool` | `true` | no |
106113
| <a name="input_name"></a> [name](#input\_name) | Name for VPC | `string` | n/a | yes |
107114
| <a name="input_network_acls"></a> [network\_acls](#input\_network\_acls) | List of ACLs to create. Rules can be automatically created to allow inbound and outbound traffic from a VPC tier by adding the name of that tier to the `network_connections` list. Rules automatically generated by these network connections will be added at the beginning of a list, and will be web-tierlied to traffic first. At least one rule must be provided for each ACL. | <pre>list(<br> object({<br> name = string<br> network_connections = optional(list(string))<br> add_ibm_cloud_internal_rules = optional(bool)<br> add_vpc_connectivity_rules = optional(bool)<br> prepend_ibm_rules = optional(bool)<br> rules = list(<br> object({<br> name = string<br> action = string<br> destination = string<br> direction = string<br> source = string<br> tcp = optional(<br> object({<br> port_max = optional(number)<br> port_min = optional(number)<br> source_port_max = optional(number)<br> source_port_min = optional(number)<br> })<br> )<br> udp = optional(<br> object({<br> port_max = optional(number)<br> port_min = optional(number)<br> source_port_max = optional(number)<br> source_port_min = optional(number)<br> })<br> )<br> icmp = optional(<br> object({<br> type = optional(number)<br> code = optional(number)<br> })<br> )<br> })<br> )<br> })<br> )</pre> | <pre>[<br> {<br> "add_ibm_cloud_internal_rules": true,<br> "add_vpc_connectivity_rules": true,<br> "name": "vpc-acl",<br> "prepend_ibm_rules": true,<br> "rules": [<br> {<br> "action": "allow",<br> "destination": "0.0.0.0/0",<br> "direction": "inbound",<br> "name": "allow-all-443-inbound",<br> "source": "0.0.0.0/0",<br> "tcp": {<br> "port_max": 443,<br> "port_min": 443<br> }<br> },<br> {<br> "action": "allow",<br> "destination": "0.0.0.0/0",<br> "direction": "outbound",<br> "name": "allow-all-443-outbound",<br> "source": "0.0.0.0/0",<br> "tcp": {<br> "source_port_max": 443,<br> "source_port_min": 443<br> }<br> }<br> ]<br> }<br>]</pre> | no |
108115
| <a name="input_network_cidr"></a> [network\_cidr](#input\_network\_cidr) | Network CIDR for the VPC. This is used to manage network ACL rules for cluster provisioning. | `string` | `"10.0.0.0/8"` | no |
@@ -126,6 +133,7 @@ You need the following permissions to run this module.
126133
| <a name="output_subnet_ids"></a> [subnet\_ids](#output\_subnet\_ids) | The IDs of the subnets |
127134
| <a name="output_subnet_zone_list"></a> [subnet\_zone\_list](#output\_subnet\_zone\_list) | A list containing subnet IDs and subnet zones |
128135
| <a name="output_vpc_crn"></a> [vpc\_crn](#output\_vpc\_crn) | CRN of VPC created |
136+
| <a name="output_vpc_flow_logs"></a> [vpc\_flow\_logs](#output\_vpc\_flow\_logs) | Details of VPC flow logs collector |
129137
| <a name="output_vpc_id"></a> [vpc\_id](#output\_vpc\_id) | ID of VPC created |
130138
| <a name="output_vpc_name"></a> [vpc\_name](#output\_vpc\_name) | Name of VPC created |
131139
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/default/main.tf

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,42 @@ data "ibm_resource_group" "existing_resource_group" {
1414
name = var.resource_group
1515
}
1616

17+
#############################################################################
18+
# Provision cloud object storage and bucket
19+
#############################################################################
20+
21+
resource "ibm_resource_instance" "cos_instance" {
22+
count = var.enable_vpc_flow_logs ? 1 : 0
23+
24+
name = "${var.prefix}-vpc-logs-cos"
25+
resource_group_id = var.resource_group != null ? data.ibm_resource_group.existing_resource_group[0].id : ibm_resource_group.resource_group[0].id
26+
service = "cloud-object-storage"
27+
plan = var.cos_plan
28+
location = var.cos_location
29+
}
30+
31+
resource "ibm_cos_bucket" "cos_bucket" {
32+
count = var.enable_vpc_flow_logs ? 1 : 0
33+
34+
bucket_name = "${var.prefix}-vpc-logs-cos-bucket"
35+
resource_instance_id = ibm_resource_instance.cos_instance[0].id
36+
region_location = var.region
37+
storage_class = "standard"
38+
}
39+
1740
#############################################################################
1841
# Provision VPC
1942
#############################################################################
2043

2144
module "slz_vpc" {
22-
source = "../../"
23-
resource_group_id = var.resource_group != null ? data.ibm_resource_group.existing_resource_group[0].id : ibm_resource_group.resource_group[0].id
24-
region = var.region
25-
name = var.name
26-
prefix = var.prefix
27-
tags = var.resource_tags
45+
source = "../../"
46+
resource_group_id = var.resource_group != null ? data.ibm_resource_group.existing_resource_group[0].id : ibm_resource_group.resource_group[0].id
47+
region = var.region
48+
name = var.name
49+
prefix = var.prefix
50+
tags = var.resource_tags
51+
enable_vpc_flow_logs = var.enable_vpc_flow_logs
52+
create_authorization_policy_vpc_to_cos = var.create_authorization_policy_vpc_to_cos
53+
existing_cos_instance_guid = ibm_resource_instance.cos_instance[0].guid
54+
existing_storage_bucket_name = ibm_cos_bucket.cos_bucket[0].bucket_name
2855
}

examples/default/outputs.tf

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,27 @@
22
# Outputs
33
##############################################################################
44

5-
output "id" {
5+
output "vpc_id" {
66
value = module.slz_vpc.vpc_id
77
description = "VPC id"
88
}
99

10-
output "crn" {
10+
output "vpc_crn" {
1111
value = module.slz_vpc.vpc_crn
1212
description = "VPC crn"
1313
}
14+
15+
output "vpc_flow_logs_collector" {
16+
value = module.slz_vpc.vpc_flow_logs
17+
description = "VPC flow logs collector"
18+
}
19+
20+
output "cos_instance_crn" {
21+
value = ibm_resource_instance.cos_instance[0].crn
22+
description = "COS instance crn"
23+
}
24+
25+
output "cos_bucket_name" {
26+
value = ibm_cos_bucket.cos_bucket[0].bucket_name
27+
description = "COS bucket name"
28+
}

examples/default/variables.tf

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,31 @@ variable "resource_tags" {
3333
type = list(string)
3434
default = null
3535
}
36+
37+
variable "enable_vpc_flow_logs" {
38+
type = bool
39+
description = "Enable VPC Flow Logs, it will create Flow logs collector if set to true"
40+
default = true
41+
}
42+
43+
variable "cos_plan" {
44+
description = "Plan to be used for creating cloud object storage instance"
45+
type = string
46+
default = "standard"
47+
validation {
48+
condition = contains(["standard", "lite"], var.cos_plan)
49+
error_message = "The specified cos_plan is not a valid selection!"
50+
}
51+
}
52+
53+
variable "cos_location" {
54+
description = "Location of the cloud object storage instance"
55+
type = string
56+
default = "global"
57+
}
58+
59+
variable "create_authorization_policy_vpc_to_cos" {
60+
description = "Set it to true if authorization policy is required for VPC to access COS"
61+
type = bool
62+
default = true
63+
}

main.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,37 @@ resource "ibm_is_public_gateway" "gateway" {
8888
}
8989

9090
##############################################################################
91+
92+
##############################################################################
93+
# Add VPC to Flow Logs
94+
##############################################################################
95+
96+
locals {
97+
# tflint-ignore: terraform_unused_declarations
98+
validate_vpc_flow_logs_inputs = (var.enable_vpc_flow_logs) ? ((var.create_authorization_policy_vpc_to_cos) ? ((var.existing_cos_instance_guid != null && var.existing_storage_bucket_name != null) ? true : tobool("Please provide COS instance & bucket name to create flow logs collector.")) : ((var.existing_storage_bucket_name != null) ? true : tobool("Please provide COS bucket name to create flow logs collector"))) : false
99+
}
100+
101+
# Create authorization policy to allow VPC to access COS instance
102+
resource "ibm_iam_authorization_policy" "policy" {
103+
count = (var.enable_vpc_flow_logs) ? ((var.create_authorization_policy_vpc_to_cos) ? 1 : 0) : 0
104+
105+
source_service_name = "is"
106+
source_resource_type = "flow-log-collector"
107+
target_service_name = "cloud-object-storage"
108+
target_resource_instance_id = var.existing_cos_instance_guid
109+
roles = ["Writer"]
110+
}
111+
112+
# Create VPC flow logs collector
113+
resource "ibm_is_flow_log" "flow_logs" {
114+
count = (var.enable_vpc_flow_logs) ? 1 : 0
115+
116+
name = "${var.prefix}-${var.name}-logs"
117+
target = ibm_is_vpc.vpc.id
118+
active = var.is_flow_log_collector_active
119+
storage_bucket = var.existing_storage_bucket_name
120+
resource_group = var.resource_group_id
121+
tags = var.tags
122+
}
123+
124+
##############################################################################

module-metadata.json

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
},
3333
"immutable": true
3434
},
35+
"create_authorization_policy_vpc_to_cos": {
36+
"name": "create_authorization_policy_vpc_to_cos",
37+
"type": "bool",
38+
"description": "Create authorisation policy for VPC to access COS. Set as false if authorization policy exists already",
39+
"default": false,
40+
"pos": {
41+
"filename": "variables.tf",
42+
"line": 408
43+
}
44+
},
3545
"default_network_acl_name": {
3646
"name": "default_network_acl_name",
3747
"type": "string",
@@ -80,6 +90,61 @@
8090
"matches": "^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$",
8191
"computed": true
8292
},
93+
"enable_vpc_flow_logs": {
94+
"name": "enable_vpc_flow_logs",
95+
"type": "bool",
96+
"description": "Flag to enable vpc flow logs. If true, flow log collector will be created",
97+
"default": false,
98+
"source": [
99+
"ibm_iam_authorization_policy.policy.count",
100+
"ibm_is_flow_log.flow_logs.count"
101+
],
102+
"pos": {
103+
"filename": "variables.tf",
104+
"line": 402
105+
}
106+
},
107+
"existing_cos_instance_guid": {
108+
"name": "existing_cos_instance_guid",
109+
"type": "string",
110+
"description": "GUID of the COS instance to create Flow log collector",
111+
"source": [
112+
"ibm_iam_authorization_policy.policy.target_resource_instance_id"
113+
],
114+
"pos": {
115+
"filename": "variables.tf",
116+
"line": 414
117+
},
118+
"immutable": true,
119+
"computed": true
120+
},
121+
"existing_storage_bucket_name": {
122+
"name": "existing_storage_bucket_name",
123+
"type": "string",
124+
"description": "Name of the COS bucket to collect VPC flow logs",
125+
"required": true,
126+
"source": [
127+
"ibm_is_flow_log.flow_logs.storage_bucket"
128+
],
129+
"pos": {
130+
"filename": "variables.tf",
131+
"line": 420
132+
},
133+
"immutable": true
134+
},
135+
"is_flow_log_collector_active": {
136+
"name": "is_flow_log_collector_active",
137+
"type": "bool",
138+
"description": "Indicates whether the collector is active. If false, this collector is created in inactive mode.",
139+
"default": true,
140+
"source": [
141+
"ibm_is_flow_log.flow_logs.active"
142+
],
143+
"pos": {
144+
"filename": "variables.tf",
145+
"line": 426
146+
}
147+
},
83148
"name": {
84149
"name": "name",
85150
"type": "string",
@@ -153,6 +218,7 @@
153218
"description": "The prefix that you would like to append to your resources",
154219
"required": true,
155220
"source": [
221+
"ibm_is_flow_log.flow_logs.name",
156222
"ibm_is_network_acl.network_acl.name",
157223
"ibm_is_public_gateway.gateway.name",
158224
"ibm_is_vpc.vpc.name",
@@ -189,6 +255,7 @@
189255
"description": "The resource group ID where the VPC to be created",
190256
"required": true,
191257
"source": [
258+
"ibm_is_flow_log.flow_logs.resource_group",
192259
"ibm_is_network_acl.network_acl.resource_group",
193260
"ibm_is_public_gateway.gateway.resource_group",
194261
"ibm_is_subnet.subnet.resource_group",
@@ -277,6 +344,7 @@
277344
"type": "list(string)",
278345
"description": "List of Tags for the resource created",
279346
"source": [
347+
"ibm_is_flow_log.flow_logs.tags",
280348
"ibm_is_public_gateway.gateway.tags",
281349
"ibm_is_subnet.subnet.tags",
282350
"ibm_is_vpc.vpc.tags"
@@ -378,6 +446,14 @@
378446
"type": "TypeString",
379447
"cloud_data_type": "crn"
380448
},
449+
"vpc_flow_logs": {
450+
"name": "vpc_flow_logs",
451+
"description": "Details of VPC flow logs collector",
452+
"pos": {
453+
"filename": "outputs.tf",
454+
"line": 104
455+
}
456+
},
381457
"vpc_id": {
382458
"name": "vpc_id",
383459
"description": "ID of VPC created",
@@ -416,6 +492,42 @@
416492
}
417493
},
418494
"managed_resources": {
495+
"ibm_iam_authorization_policy.policy": {
496+
"mode": "managed",
497+
"type": "ibm_iam_authorization_policy",
498+
"name": "policy",
499+
"attributes": {
500+
"count": "enable_vpc_flow_logs",
501+
"target_resource_instance_id": "existing_cos_instance_guid"
502+
},
503+
"provider": {
504+
"name": "ibm"
505+
},
506+
"pos": {
507+
"filename": "main.tf",
508+
"line": 102
509+
}
510+
},
511+
"ibm_is_flow_log.flow_logs": {
512+
"mode": "managed",
513+
"type": "ibm_is_flow_log",
514+
"name": "flow_logs",
515+
"attributes": {
516+
"active": "is_flow_log_collector_active",
517+
"count": "enable_vpc_flow_logs",
518+
"name": "prefix",
519+
"resource_group": "resource_group_id",
520+
"storage_bucket": "existing_storage_bucket_name",
521+
"tags": "tags"
522+
},
523+
"provider": {
524+
"name": "ibm"
525+
},
526+
"pos": {
527+
"filename": "main.tf",
528+
"line": 113
529+
}
530+
},
419531
"ibm_is_network_acl.network_acl": {
420532
"mode": "managed",
421533
"type": "ibm_is_network_acl",

outputs.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,23 @@ output "network_acls" {
9696
}
9797

9898
##############################################################################
99+
100+
##############################################################################
101+
# VPC flow logs
102+
##############################################################################
103+
104+
output "vpc_flow_logs" {
105+
description = "Details of VPC flow logs collector"
106+
value = var.enable_vpc_flow_logs != true ? [] : [
107+
for flow_log_collector in ibm_is_flow_log.flow_logs :
108+
{
109+
name = flow_log_collector.name
110+
id = flow_log_collector.id
111+
crn = flow_log_collector.crn
112+
href = flow_log_collector.href
113+
state = flow_log_collector.lifecycle_state
114+
}
115+
]
116+
}
117+
118+
##############################################################################

0 commit comments

Comments
 (0)