Skip to content

Commit 5fd3628

Browse files
committed
Add IPv6 Support
1 parent f50424b commit 5fd3628

18 files changed

+298
-47
lines changed

docs/terraformoptions.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
| create_nat_gateway | Whether to create an NAT gateway. | bool | false|
2525
| create_service_gateway | Whether to create a service gateway to use Oracle Services. | bool | false|
2626
| enable_ipv6 | (Updatable) Whether IPv6 is enabled for the VCN. If enabled, Oracle will assign the VCN a IPv6 /56 CIDR block. | bool | false|
27+
| igw_ngw_mixed_route_table_display_name | (Updatable) Name of the Mixed Route Table (NGW for IPv4, IGW for IPv6). Does not have to be unique. | string | igw-ngw-mixed-gateway |
2728
| internet_gateway_display_name | (Updatable) Name of Internet Gateway. Does not have to be unique.| string | internet-gateway|
2829
| internet_gateway_route_rules | (Updatable) List of routing rules to add to Internet Gateway Route Table.| list(map(string)) | null|
2930
| local_peering_gateways | Map of Local Peering Gateways to attach to the VCN | map(any) | null|
@@ -32,8 +33,11 @@
3233
| nat_gateway_public_ip_id | OCID of reserved IP address for NAT gateway. If default value "none" is used, then a public IP address is selected from Oracle’s public IP pool. | string | none|
3334
| nat_gateway_route_rules | (Updatable) List of routing rules to add to NAT Gateway Route Table | list(map(string)) | null|
3435
| service_gateway_display_name | (Updatable) Name of Service Gateway. Does not have to be unique. | string | service-gateway|
36+
| vcn_byoipv6cidr_details | (Optional)List of BYOIPv6 CIDR blocks to be used for the VCN. | list(object) | [] |
3537
| vcn_cidrs | (Updatable) The list of IPv4 CIDR blocks the VCN will use. The CIDR block specified for the VCN must not overlap with the CIDR block of another network. | string | ["10.0.0.0/16"]|
3638
| vcn_dns_label | (Optional)A DNS label for the VCN, used in conjunction with the VNIC’s hostname and subnet’s DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet. DNS resolution for hostnames in the VCN is disabled if null. | string | vcnmodule|
39+
| vcn_ipv6private_cidr_blocks | (Optional)List of IPv6 private CIDR blocks to be used for the VCN. | list(string) | []|
40+
| vcn_is_oracle_gua_allocation_enabled | (Optional)If Oracle will assign the VCN a IPv6 /56 CIDR block when IPv6 is enabled. | bool | true|
3741
| vcn_name | (Optional)(Updatable) The name of the VCN that will be appended to the label_prefix. | string | vcn|
3842

3943
### Subnets

docs/terraformoptions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
| create_nat_gateway | Whether to create an NAT gateway. | bool | false|
2525
| create_service_gateway | Whether to create a service gateway to use Oracle Services. | bool | false|
2626
| enable_ipv6 | (Updatable) Whether IPv6 is enabled for the VCN. If enabled, Oracle will assign the VCN a IPv6 /56 CIDR block. | bool | false|
27+
| igw_ngw_mixed_route_table_display_name | (Updatable) Name of the Mixed Route Table (NGW for IPv4, IGW for IPv6). Does not have to be unique. | string | igw-ngw-mixed-gateway |
2728
| internet_gateway_display_name | (Updatable) Name of Internet Gateway. Does not have to be unique.| string | internet-gateway|
2829
| internet_gateway_route_rules | (Updatable) List of routing rules to add to Internet Gateway Route Table.| list(map(string)) | null|
2930
| local_peering_gateways | Map of Local Peering Gateways to attach to the VCN | map(any) | null|
@@ -32,8 +33,11 @@
3233
| nat_gateway_public_ip_id | OCID of reserved IP address for NAT gateway. If default value "none" is used, then a public IP address is selected from Oracle’s public IP pool. | string | none|
3334
| nat_gateway_route_rules | (Updatable) List of routing rules to add to NAT Gateway Route Table | list(map(string)) | null|
3435
| service_gateway_display_name | (Updatable) Name of Service Gateway. Does not have to be unique. | string | service-gateway|
36+
| vcn_byoipv6cidr_details | (Optional)List of BYOIPv6 CIDR blocks to be used for the VCN. | list(object) | [] |
3537
| vcn_cidrs | (Updatable) The list of IPv4 CIDR blocks the VCN will use. The CIDR block specified for the VCN must not overlap with the CIDR block of another network. | string | ["10.0.0.0/16"]|
3638
| vcn_dns_label | (Optional)A DNS label for the VCN, used in conjunction with the VNIC’s hostname and subnet’s DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet. DNS resolution for hostnames in the VCN is disabled if null. | string | vcnmodule|
39+
| vcn_ipv6private_cidr_blocks | (Optional)List of IPv6 private CIDR blocks to be used for the VCN. | list(string) | []|
40+
| vcn_is_oracle_gua_allocation_enabled | (Optional)If Oracle will assign the VCN a IPv6 /56 CIDR block when IPv6 is enabled. | bool | true|
3741
| vcn_name | (Optional)(Updatable) The name of the VCN that will be appended to the label_prefix. | string | vcn|
3842

3943
### Subnets

examples/drg/version.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
oci = {
44
source = "oracle/oci"
5-
version = ">=4.67.3"
5+
version = ">=6.32.0"
66
}
77
}
88
required_version = ">= 1.0.0"

examples/hub-spoke/version.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
oci = {
44
source = "oracle/oci"
5-
version = ">=4.67.3"
5+
version = ">=6.32.0"
66
}
77
}
88
required_version = ">= 1.0.0"

examples/module_composition/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ module "vcn" {
6666
vcn_name = var.vcn_name
6767
lockdown_default_seclist = var.lockdown_default_seclist
6868
attached_drg_id = var.attached_drg_id
69+
70+
# IPv6 parameters (Optional)
71+
vcn_is_oracle_gua_allocation_enabled = var.vcn_is_oracle_gua_allocation_enabled # Enable Global Unicast Address (GUA) VCN allocation
72+
vcn_ipv6private_cidr_blocks = var.vcn_ipv6private_cidr_blocks # List with IPv6 private CIDR blocks
73+
vcn_byoipv6cidr_details = var.vcn_byoipv6cidr_details # List with BYOIPv6 CIDR blocks
74+
ipv6_private_subnet_route_table_display_name = var.ipv6_private_subnet_route_table_display_name # Name of the route table used for private subnets
6975
}
7076
```
7177

examples/module_composition/main.tf

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,24 @@ module "vcn" {
1818
defined_tags = var.defined_tags
1919

2020
# vcn parameters
21-
create_internet_gateway = var.create_internet_gateway # boolean: true or false
22-
lockdown_default_seclist = var.lockdown_default_seclist # boolean: true or false
23-
create_nat_gateway = var.create_nat_gateway # boolean: true or false
24-
create_service_gateway = var.create_service_gateway # boolean: true or false
25-
enable_ipv6 = var.enable_ipv6
26-
vcn_cidrs = var.vcn_cidrs # List of IPv4 CIDRs
27-
vcn_dns_label = var.vcn_dns_label
28-
vcn_name = var.vcn_name
21+
create_internet_gateway = var.create_internet_gateway # boolean: true or false
22+
lockdown_default_seclist = var.lockdown_default_seclist # boolean: true or false
23+
create_nat_gateway = var.create_nat_gateway # boolean: true or false
24+
create_service_gateway = var.create_service_gateway # boolean: true or false
25+
enable_ipv6 = var.enable_ipv6
26+
vcn_cidrs = var.vcn_cidrs # List of IPv4 CIDRs
27+
vcn_dns_label = var.vcn_dns_label
28+
vcn_name = var.vcn_name
29+
vcn_is_oracle_gua_allocation_enabled = var.vcn_is_oracle_gua_allocation_enabled # boolean: true or false
30+
vcn_ipv6private_cidr_blocks = var.vcn_ipv6private_cidr_blocks # List of IPv6 private CIDRs
31+
vcn_byoipv6cidr_details = var.vcn_byoipv6cidr_details # List of IPv6 BYO CIDR details
2932

3033
# gateways parameters
31-
internet_gateway_display_name = var.internet_gateway_display_name
32-
nat_gateway_display_name = var.nat_gateway_display_name
33-
service_gateway_display_name = var.service_gateway_display_name
34-
attached_drg_id = var.attached_drg_id
34+
internet_gateway_display_name = var.internet_gateway_display_name
35+
nat_gateway_display_name = var.nat_gateway_display_name
36+
service_gateway_display_name = var.service_gateway_display_name
37+
igw_ngw_mixed_route_table_display_name = var.igw_ngw_mixed_route_table_display_name
38+
attached_drg_id = var.attached_drg_id
3539
}
3640

3741
# Outputs

examples/module_composition/variables.tf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,29 @@ variable "service_gateway_display_name" {
139139
default = "sgw"
140140
}
141141

142+
variable "vcn_is_oracle_gua_allocation_enabled" {
143+
description = "If Oracle will assign the VCN a IPv6 /56 CIDR block when IPv6 is enabled."
144+
type = bool
145+
default = false
146+
}
147+
148+
variable "vcn_ipv6private_cidr_blocks" {
149+
description = "List of private IPv6 CIDR blocks to be used for the VCN."
150+
type = list(string)
151+
default = []
152+
}
153+
154+
variable "vcn_byoipv6cidr_details" {
155+
description = "List of BYOIPv6 CIDR blocks to be used for the VCN."
156+
type = list(object({
157+
byoipv6range_id = string
158+
ipv6cidr_block = string
159+
}))
160+
default = []
161+
}
162+
163+
variable "igw_ngw_mixed_route_table_display_name" {
164+
description = "(Updatable) Name of Route Table. Does not have to be unique."
165+
type = string
166+
default = "igw-ngw-mixed-gateway"
167+
}

examples/module_composition/version.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
oci = {
44
source = "oracle/oci"
5-
version = ">=4.67.3"
5+
version = ">=6.32.0"
66
}
77
}
88
required_version = ">= 1.0.0"

modules/subnet/subnet.tf

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
locals {
55
dhcp_default_options = data.oci_core_dhcp_options.dhcp_options.options.0.id
6-
// Tenancy-specific availability domains in region
6+
// Tenancy-specific availability domains in region
77
// Common reference for data source re-used throughout module
88
ads = data.oci_identity_availability_domains.all.availability_domains
99

1010
// Map of parsed availability domain numbers to tenancy-specific names
1111
// Used by resources with AD placement for generic selection
1212
ad_numbers_to_names = local.ads != null ? {
13-
for ad in local.ads : parseint(substr(ad.name, -1, -1), 10) => ad.name
13+
for ad in local.ads : parseint(substr(ad.name, -1, -1), 10) => ad.name
1414
} : { -1 : "" } # Fallback handles failure when unavailable but not required
1515

1616
// List of availability domain numbers in region
@@ -23,24 +23,30 @@ data "oci_identity_availability_domains" "all" {
2323
}
2424

2525
resource "oci_core_subnet" "vcn_subnet" {
26-
for_each = var.subnets
27-
cidr_block = each.value.cidr_block
28-
compartment_id = var.compartment_id
29-
vcn_id = var.vcn_id
26+
for_each = var.subnets
27+
28+
cidr_block = each.value.cidr_block
29+
compartment_id = var.compartment_id
30+
vcn_id = var.vcn_id
3031
availability_domain = lookup(each.value, "availability_domain", null) != null ? local.ad_numbers_to_names[each.value.availability_domain] : null
31-
32+
3233
defined_tags = var.defined_tags
3334
dhcp_options_id = local.dhcp_default_options
3435
display_name = lookup(each.value, "name", each.key)
3536
dns_label = lookup(each.value, "dns_label", null)
3637
freeform_tags = var.freeform_tags
3738
#commented for IPV6 support
38-
#ipv6cidr_block = var.enable_ipv6 == false ? null : each.value.ipv6cidr_block
39-
#ipv6cidr_blocks = var.enable_ipv6 == false ? null : [each.value.ipv6cidr_block]
40-
#prohibit_internet_ingress = var.enable_ipv6 && lookup(each.value,"type","public") == "public" ? each.value.prohibit_internet_ingress : false
41-
prohibit_public_ip_on_vnic = lookup(each.value, "type", "public") == "public" ? false : true
42-
route_table_id = lookup(each.value, "type", "public") == "public" ? var.ig_route_id : var.nat_route_id
43-
security_list_ids = null
39+
# ipv6cidr_block = var.enable_ipv6 == false ? null : each.value.ipv6cidr_block
40+
ipv6cidr_blocks = var.enable_ipv6 == false ? null : each.value.ipv6cidr_blocks
41+
prohibit_internet_ingress = lookup(each.value, "type", "public") == "public" ? false : true
42+
# prohibit_public_ip_on_vnic = lookup(each.value, "type", "public") == "public" ? false : true
43+
route_table_id = lookup(each.value, "type", "public") == "public" ? (
44+
lookup(each.value, "igw_ngw_mixed_rt", false) == true ?
45+
var.igw_ngw_mixed_route_id :
46+
var.ig_route_id
47+
) : var.nat_route_id
48+
49+
security_list_ids = null
4450

4551
lifecycle {
4652
ignore_changes = [defined_tags, dns_label, freeform_tags]

modules/subnet/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ variable "nat_route_id" {
3434
type = string
3535
}
3636

37+
variable "igw_ngw_mixed_route_id" {
38+
description = "IPv6 route table id with IGW for IPv6 and NGW for IPv4."
39+
type = string
40+
default = null
41+
}
42+
3743
variable "defined_tags" {
3844
description = "predefined and scoped to a namespace to tag the resources created using defined tags."
3945
type = map(string)

modules/subnet/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ terraform {
55
required_providers {
66
oci = {
77
source = "oracle/oci"
8-
version = ">=4.67.3"
8+
version = ">=6.32.0"
99
}
1010
}
1111
required_version = ">= 1.0.0"

outputs.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ output "ig_route_id" {
2727
value = join(",", oci_core_route_table.ig[*].id)
2828
}
2929

30+
output "igw_ngw_mixed_route_id" {
31+
description = "id of the internet gateway & nat gateway mixed route table"
32+
value = one(oci_core_route_table.igw_ngw_mixed_route_id[*].id)
33+
}
34+
3035
output "nat_route_id" {
3136
description = "id of VCN NAT gateway route table"
3237
value = join(",", oci_core_route_table.nat[*].id)
@@ -37,6 +42,7 @@ output "sgw_route_id" {
3742
value = join(",", oci_core_route_table.service_gw[*].id)
3843
}
3944

45+
4046
# New complete outputs for each resources with provider parity. Auto-updating.
4147
# Usefull for module composition.
4248

terraform.tfvars.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,15 @@ attached_drg_id = null
115115
# sub3 = {cidr_block="10.0.6.0/24",availability_domain=1}
116116
#}
117117

118+
#Subnets when `enable_ipv6 = true`
119+
## Supported notation for ipv6cidr_blocks is "newbits, netnum" or "IPv6_CIDR"
120+
## E.g.: ipv6cidr_blocks=["8, 0", "FC00::/64"]
121+
#subnets = {
122+
# sub1 = {name = "subnet1", type="public", cidr_block = "10.0.4.0/24"}
123+
# sub2 = {cidr_block="10.0.5.0/24",ipv6cidr_blocks=["8, 0"], igw_ngw_mixed_rt=true}
124+
# sub3 = {cidr_block="10.0.7.0/24",type="private",ipv6cidr_blocks=["8, 1"]}
125+
#}
126+
118127
#Logging
119128
#enable_vcn_logging = true
120129
#log_retention_duration = 30

variables.tf

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,27 @@ variable "enable_ipv6" {
6464
default = false
6565
}
6666

67+
variable "vcn_is_oracle_gua_allocation_enabled" {
68+
description = "If Oracle will assign the VCN a IPv6 /56 CIDR block when IPv6 is enabled."
69+
type = bool
70+
default = true
71+
}
72+
73+
variable "vcn_ipv6private_cidr_blocks" {
74+
description = "List of IPv6 private CIDR blocks to be used for the VCN."
75+
type = list(string)
76+
default = []
77+
}
78+
79+
variable "vcn_byoipv6cidr_details" {
80+
description = "List of BYOIPv6 CIDR blocks to be used for the VCN."
81+
type = list(object({
82+
byoipv6range_id = string
83+
ipv6cidr_block = string
84+
}))
85+
default = []
86+
}
87+
6788
variable "lockdown_default_seclist" {
6889
description = "whether to remove all default security rules from the VCN Default Security List"
6990
default = true
@@ -143,6 +164,17 @@ variable "service_gateway_display_name" {
143164
}
144165
}
145166

167+
variable "igw_ngw_mixed_route_table_display_name" {
168+
description = "(Updatable) Name of the Mixed Route Table (NGW for IPv4, IGW for IPv6). Does not have to be unique."
169+
type = string
170+
default = "igw-ngw-mixed-gateway"
171+
172+
validation {
173+
condition = length(var.igw_ngw_mixed_route_table_display_name) > 0
174+
error_message = "The igw_ngw_mixed_route_table_display_name value cannot be an empty string."
175+
}
176+
}
177+
146178
variable "internet_gateway_route_rules" {
147179
description = "(Updatable) List of routing rules to add to Internet Gateway Route Table"
148180
type = list(map(string))

vcn.tf

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,42 @@
44
resource "oci_core_vcn" "vcn" {
55
# We still allow module users to declare a cidr using `vcn_cidr` instead of the now recommended `vcn_cidrs`, but internally we map both to `cidr_blocks`
66
# The module always use the new list of string structure and let the customer update his module definition block at his own pace.
7-
cidr_blocks = var.vcn_cidrs[*]
8-
compartment_id = var.compartment_id
9-
display_name = var.label_prefix == "none" ? var.vcn_name : "${var.label_prefix}-${var.vcn_name}"
10-
dns_label = var.vcn_dns_label
11-
is_ipv6enabled = var.enable_ipv6
7+
cidr_blocks = var.vcn_cidrs[*]
8+
compartment_id = var.compartment_id
9+
display_name = var.label_prefix == "none" ? var.vcn_name : "${var.label_prefix}-${var.vcn_name}"
10+
dns_label = var.vcn_dns_label
11+
is_ipv6enabled = var.enable_ipv6
12+
is_oracle_gua_allocation_enabled = var.enable_ipv6 ? var.vcn_is_oracle_gua_allocation_enabled : null
13+
ipv6private_cidr_blocks = var.enable_ipv6 ? var.vcn_ipv6private_cidr_blocks : null
14+
15+
dynamic "byoipv6cidr_details" {
16+
for_each = var.enable_ipv6 ? var.vcn_byoipv6cidr_details : []
17+
content {
18+
byoipv6range_id = byoipv6cidr_details.value.byoipv6range_id
19+
ipv6cidr_block = byoipv6cidr_details.value.ipv6cidr_block
20+
}
21+
}
1222

1323
freeform_tags = var.freeform_tags
1424
defined_tags = var.defined_tags
1525

1626
lifecycle {
17-
ignore_changes = [defined_tags, dns_label, freeform_tags]
27+
ignore_changes = [defined_tags, dns_label, freeform_tags, is_oracle_gua_allocation_enabled]
1828
}
1929
}
2030

2131
#Module for Subnet
2232
module "subnet" {
2333
source = "./modules/subnet"
2434

25-
compartment_id = var.compartment_id
26-
tenancy_id = var.tenancy_id
27-
subnets = var.subnets
28-
enable_ipv6 = var.enable_ipv6
29-
vcn_id = oci_core_vcn.vcn.id
30-
ig_route_id = var.create_internet_gateway ? oci_core_route_table.ig[0].id : null
31-
nat_route_id = var.create_nat_gateway ? oci_core_route_table.nat[0].id : null
35+
compartment_id = var.compartment_id
36+
tenancy_id = var.tenancy_id
37+
subnets = local.enriched_subnets
38+
enable_ipv6 = var.enable_ipv6
39+
vcn_id = oci_core_vcn.vcn.id
40+
ig_route_id = var.create_internet_gateway ? oci_core_route_table.ig[0].id : null
41+
nat_route_id = var.create_nat_gateway ? oci_core_route_table.nat[0].id : null
42+
igw_ngw_mixed_route_id = var.enable_ipv6 && var.create_internet_gateway && var.create_nat_gateway ? oci_core_route_table.igw_ngw_mixed_route_id[0].id : null
3243

3344
freeform_tags = var.freeform_tags
3445

@@ -41,6 +52,17 @@ locals {
4152
subnet = {
4253
for key, value in var.subnets : key => contains(keys(value), "name") ? value.name : key
4354
}
55+
56+
subnet_ipv6_cidr_blocks = var.enable_ipv6 && var.vcn_is_oracle_gua_allocation_enabled ? {
57+
for key, value in var.subnets : key => contains(keys(value), "ipv6cidr_blocks") ?
58+
{ "ipv6cidr_blocks" : [for entry in value["ipv6cidr_blocks"] : length(regexall("^\\d+,[ ]?\\d+$", entry)) > 0 ? cidrsubnet(coalesce([for cidr in oci_core_vcn.vcn.ipv6cidr_blocks : cidr]...), tonumber(split(",", entry)[0]), tonumber(trim(split(",", entry)[1], " "))) : entry] } :
59+
{ "ipv6cidr_blocks" : [] }
60+
} : {}
61+
62+
enriched_subnets = { for k, v in var.subnets :
63+
k => merge(v, lookup(local.subnet_ipv6_cidr_blocks, k, null))
64+
}
65+
4466
service_logdef = { for k in local.subnet : format("%s_%s", k, "log") => { loggroup = "loggrp", service = "flowlogs", resource = k } }
4567
}
4668

0 commit comments

Comments
 (0)