Terraform VCN for Oracle Cloud Infrastructure
The Terraform VCN module for Oracle Cloud Infrastructure provides a reusable Terraform module that provisions a minimal VCN on OCI.
It creates the following resources:
- A VCN with one or more customizable CIDR blocks
- An optional Internet Gateway with a corresponding route table
- An optional NAT Gateway with a corresponding route table
- An optional Service Gateway
- One or more optional Local Peering Gateways in requestor or acceptor mode, and possibilities to associate a Route Table
It also controls the Default Security List, with a Lockdown mode that can be enabled or disabled.
Custom route rules can be added to the two route tables created by the module.
This module is primarily meant to be reusable to create more advanced infrastructure on OCI either manually in the OCI Console or by extending the Terraform code.
Documentation
Related Documentation, Blog
- Oracle Cloud Infrastructure Documentation
- Terraform OCI Provider Documentation
- Erik Berg on Networks, Subnets and CIDR
Changelog
View the CHANGELOG.
Acknowledgement
Code derived and adapted from Terraform OCI Examples and Hashicorp's Terraform 0.12 examples
Contributors
Folks who contributed with explanations, code, feedback, ideas, testing etc.
Learn how to contribute.
License
Copyright (c) 2019, 2023 Oracle and/or its associates.
Licensed under the Universal Permissive License 1.0 as shown at https://oss.oracle.com/licenses/upl.
Pre-requisites
- Local development tools: Git, Terraform, a terminal.
- Understanding of Oracle Cloud Infrastructure (OCI) and its services, in particular the Virtual Cloud Networking (VCN) service.
Generate and upload your OCI API keys
Follow the documentation for generating and uploading your API keys.
Note the key fingerprint.
Create an OCI compartment
Follow the documentation for creating a compartment.
Obtain the necessary OCIDs
The following OCIDs are required:
- Compartment OCID
- Tenancy OCID
- User OCID
Follow the documentation for obtaining the tenancy and user OCIDs.
To obtain the compartment OCID:
- Navigate to Identity > Compartments
- Click on your Compartment
- Locate OCID on the page and click on
Copy
Configuring Policies
-
Create a group (e.g. mygroup) and add a user to the group.
-
Create a policy:
Allow group mygroup to manage virtual-network-family in compartment id ocid1.compartment.oc1..aaa
User Guide
- Creating a Virtual Cloud Network
- Reusing as a Terraform module
- Virtual Cloud Network Gateways
- Configuring routing rules
- Using Resource Manager
Creating a VCN
Assumptions
- You have setup the required keys
- You know the required OCIDs
- You have the necessary permissions
Pre-requisites
- Git is installed
- SSH client is installed
- Terraform 1.3.0 or greater is installed
Instructions
Provisioning using this git repo
- Clone the repo:
git clone https://github.com/oracle-terraform-modules/terraform-oci-vcn.git tfvcn
cd tfvcn
cp terraform.tfvars.example terraform.tfvars
- Create a provider.tf file and add the following:
provider "oci" {
fingerprint = var.api_fingerprint
private_key_path = var.api_private_key_path
region = var.region
tenancy_ocid = var.tenancy_id
user_ocid = var.user_id
}
# provider identity parameters
variable "api_fingerprint" {
description = "fingerprint of oci api private key"
type = string
}
variable "api_private_key_path" {
description = "path to oci api private key used"
type = string
}
variable "tenancy_id" {
description = "tenancy id where to create the sources"
type = string
}
variable "user_id" {
description = "id of user that terraform will use to create the resources"
type = string
}
- Set mandatory provider parameters in terraform.tfvars:
api_fingerprint
api_private_key_path
region
tenancy_id
user_id
- Override other parameters in terraform.tfvars:
compartment_id
label_prefix
vcn_name
- Optional parameters to override:
create_internet_gateway
create_nat_gateway
create_service_gateway
freeform_tags
attached_drg_id
vcn_dns_label
- Run Terraform:
terraform init
terraform plan
terraform apply
Reusing as a Terraform module
You can also use the method below to reuse this in your own module.
-
Create a variable.tf file in your root project and add the contents of the variables.tf from the example.
-
Create a provider.tf file in your root directory and add the following:
provider "oci" {
fingerprint = var.api_fingerprint
private_key_path = var.api_private_key_path
region = var.region
tenancy_ocid = var.tenancy_id
user_ocid = var.user_id
}
- Create a main.tf file and add the following:
module "vcn" {
source = "github.com/oracle-terraform-modules/terraform-oci-vcn"
# to use the terraform registry version comment the previous line and uncomment the 2 lines below
# source = "oracle-terraform-modules/vcn/oci"
# version = "specify_version_number"
# general oci parameters
compartment_id = var.compartment_id
label_prefix = var.label_prefix
freeform_tags = var.freeform_tags
defined_tags = var.defined_tags
# vcn parameters
create_internet_gateway = var.create_internet_gateway # boolean: true or false
lockdown_default_seclist = var.lockdown_default_seclist # boolean: true or false
create_nat_gateway = var.create_nat_gateway # boolean: true or false
create_service_gateway = var.create_service_gateway # boolean: true or false
enable_ipv6 = var.enable_ipv6
vcn_cidrs = var.vcn_cidrs # List of IPv4 CIDRs
vcn_dns_label = var.vcn_dns_label
vcn_name = var.vcn_name
# gateways parameters
internet_gateway_display_name = var.internet_gateway_display_name
nat_gateway_display_name = var.nat_gateway_display_name
service_gateway_display_name = var.service_gateway_display_name
attached_drg_id = var.attached_drg_id
}
- In order to obtain and reuse the VCN resources created, export the OCIDs in outputs.tf:
# Outputs
output "module_vcn_ids" {
description = "vcn and gateways information"
value = {
internet_gateway_id = module.vcn.internet_gateway_id
internet_gateway_route_id = module.vcn.ig_route_id
nat_gateway_id = module.vcn.nat_gateway_id
nat_gateway_route_id = module.vcn.nat_route_id
service_gateway_id = module.vcn.service_gateway_id
vcn_dns_label = module.vcn.vcn_all_attributes.dns_label
vcn_default_security_list_id = module.vcn.vcn_all_attributes.default_security_list_id
vcn_default_route_table_id = module.vcn.vcn_all_attributes.default_route_table_id
vcn_default_dhcp_options_id = module.vcn.vcn_all_attributes.default_dhcp_options_id
vcn_id = module.vcn.vcn_id
}
}
- Copy terraform.tfvars.example to terraform.tfvars
cp terraform.tfvars.example terraform.tfvars
- Set the mandatory provider parameters:
api_fingerprint
api_private_key_path
region
tenancy_id
user_id
- Override other parameters in terraform.tfvars:
compartment_id
label_prefix
vcn_name
- Optional parameters to override:
attached_drg_id
create_internet_gateway
create_nat_gateway
create_service_gateway
freeform_tags
defined_tags
vcn_dns_label
- Run Terraform:
terraform init
terraform plan
terraform apply
Related documentation:
- All Terraform configuration options for this project.
VCN Gateways
Local Peering Gateways
Local Peering Gateways are used to establish a single peering relationship between two VCNs. For more information about how Local Peering works on OCI, see Important Local Peering concepts and Transit Routing.
The VCN module allows you to declare several LPG using the module's local_peering_gateways
variable Input:
- each key of
local_peering_gateways
is an LPG. - the key is the LPG's display name.
- you can optionally declare a
route_table_id
to be attached to the LPG. This is useful on to create a Hub VCN for Transit Routing. - you can optionally declare a
peer_id
, so your module will act as a requestor and trigger the peering processus (to be used either in the hub vcn module or the spoke vcn module, but not both).
Using the module outputs to retrieve an LPG OCID
You can dynamically retrieve the OCID of an LPG created with this module using the module's lpg_all_attributes
output: module.*<module_name>*.lpg_all_attributes["*<lpg_key>*"]["id"]
.
This is particularly useful when both VCNs to be peered are in the same Terraform configuration and created using this module.
Generic values for route_table_id
or peer_id
If you need to attach a Routing Table or peer with an LPG created outside of the VCN module, you can simply provide the resource OCID using a valid Terraform method (any {uri-tf-namedvalues}[Named Value]).
Examples
This is an example that shows how to declare LPGs in three different ways:
module "vcn_hub" {
...
local_peering_gateways = {
to_spoke1 = {
// this LPG will have a Route Table associated with it
route_table_id = oci_core_route_table.VTR_spokes.id
}
to_spoke2 = {
// this LPG will have a Route Table associated with it and the peering connection will be established (requestor mode)
route_table_id = oci_core_route_table.VTR_spokes.id
peer_id = module.vcn_spoke2.lpg_all_attributes["to_hub"]["id"]
}
to_spoke3 = {}
// this LPG will be created without any Route Table associated, and ready to be peered (acceptor mode)
}
}
See the hub-and-spoke example that for more details on how to use this feature.
Configuring routing rules
When you create an Internet or a NAT gateway, the terraform-oci-vcn module automatically creates a dedicated route table for each gateway:
<label_prefix>-internet-route
route table is created ifcreate_internet_gateway = true
<label_prefix>-nat-route
route table is created ifcreate_nat_gateway = true
These automatically created route tables comes with automatic rules, that cannot be controlled by the module user.
internet-route route table
internet-route is meant to be attached to public subnets you provision. It comes with one automatic/non-editable rule that redirects all unknown destination to the Internet Gateway created by this module: 0.0.0.0/0 --> Internet Gateway
.
nat-route route table
nat-route table is meant to be attached to private subnets you provision. It comes with one automatic/non-editable rule that redirects all unknown destination to the NAT Gateway created by this module: 0.0.0.0/0 --> NAT Gateway
.
If a Service Gateway is also created by the module with create_service_gateway = true
, a second rule is added to redirect all Oracle Network Services traffic to the Service Gateway created by this module: All <REGION> services in OSN --> Service Gateway
Custom routes
terraform-oci-vcn module have two optional Input Variables to inject user-defined route rules into internet-route
and nat-route
route tables using respectively:
internet_gateway_route_rules
defined as alist(map(string))
with the following expected schema:
variable "internet_gateway_route_rules" {
description = "(Updatable) List of routing rules to add to Internet Gateway Routing Table"
type = list(object({
destination = string # required
destination_type = string # required
network_entity_id = string # required
description = string # optional
}))
default = null
}
nat_gateway_route_rules
defined as alist(map(string))
with the following expected schema:
variable "nat_gateway_route_rules" {
description = "(Updatable) List of routing rules to add to NAT Gateway Routing Table"
type = list(object({
destination = string # required
destination_type = string # required
network_entity_id = string # required
description = string # optional
}))
default = null
}
They share the same schema but each Input Variable controls the associated route table:
destination
accept string value and represent the CIDR that will be affected by the rule,destination_type
accept string value, withCIDR_BLOCK
orSERVICE_CIDR_BLOCK
as valid values,network_entity_id
accept string value and represent the gateway to be the target of the rule,description
accept arbitrary string value and give context about the goal of the rule.
Special values for network_entity_id
For routing rules targeting a gateway created by the module, network_entity_id
accepts some special strings to automatically retrieve the gateway OCID.
internet_gateway_route_rules
andnat_gateway_route_rules
recognise the"drg"
string and resolve it to the Dynamic Routing Gateway(DRG) OCID attached to the module (if available),internet_gateway_route_rules
recognise the"internet_gateway"
string and resolve it to the Internet Gateway OCID created by the module,nat_gateway_route_rules
recognise the"nat_gateway"
string and resolve it to the NAT Gateway OCID created by the module.
Generic values for network_entity_id
If you need to create a routing rule with a target gateway created outside of the module, you can simply provide the resource OCID using a valid Terraform method (any named value).
Examples
For example configuration using this option, see custom route rules.
Using Resource Manager
- Overview
- Create Stack
- Step by Step Instructions
git clone https://github.com/oracle-terraform-modules/terraform-oci-vcn.git
zip terraform-oci-vcn.zip *.tf schema.yaml -x main.tf
-
Upload zip file:
-
Configure variables as per your needs:
-
Check the relevant boxes if you need gateways:
-
Review your stack:
-
Run Terraform plan and apply:
-
Check the logs:
Terraform Options
Provider
Parameter | Description | Type | Default |
---|---|---|---|
region | Region where to provision the vcn. List of regions. Required. | string |
General OCI
Parameter | Description | Type | Default |
---|---|---|---|
compartment_id | Compartment id where the VCN Cluster will be provisioned. Required. | string | |
label_prefix | a string to be prepended to the name of resources. Required. | string | none |
freeform_tags | simple key-value pairs to tag the resources created specified in the form of a map | map(any) | freeform_tags = { environment = "dev" } |
defined_tags | predefined and scoped to a namespace to tag the resources created using defined tags. | map(string) | null |
VCN
Parameter | Description | Type | Default |
---|---|---|---|
attached_drg_id | DRG OCID to be attached to the VCN. | string | |
create_internet_gateway | Whether to create an Internet Gateway. | bool | false |
create_nat_gateway | Whether to create an NAT gateway. | bool | false |
create_service_gateway | Whether to create a service gateway to use Oracle Services. | bool | false |
enable_ipv6 | (Updatable) Whether IPv6 is enabled for the VCN. If enabled, Oracle will assign the VCN a IPv6 /56 CIDR block. | bool | false |
internet_gateway_display_name | (Updatable) Name of Internet Gateway. Does not have to be unique. | string | internet-gateway |
internet_gateway_route_rules | (Updatable) List of routing rules to add to Internet Gateway Route Table. | list(map(string)) | null |
local_peering_gateways | Map of Local Peering Gateways to attach to the VCN | map(any) | null |
lockdown_default_seclist | Whether to remove all default security rules from the VCN Default Security List | bool | true |
nat_gateway_display_name | (Updatable) Name of NAT Gateway. It does not have to be unique. | string | nat-gateway |
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 |
nat_gateway_route_rules | (Updatable) List of routing rules to add to NAT Gateway Route Table | list(map(string)) | null |
service_gateway_display_name | (Updatable) Name of Service Gateway. Does not have to be unique. | string | service-gateway |
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"] |
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 |
vcn_name | (Optional)(Updatable) The name of the VCN that will be appended to the label_prefix. | string | vcn |
Subnets
Parameter | Description | Type | Default |
---|---|---|---|
subnets | Subnets to be created in the VCN | any | {} |