Hello blog! Sorry I’ve been lacking with my posts but let’s kick it off again and with a bang!

I’ve had few cases previously where I’m using Terraform modules and the blocks need to support one to many different values. This means that sometimes the values exist and sometimes they don’t.

For this I thought creating OCI DHCP Options for your subnet would a great simple example. Check out this video to see it in use live!

Summarizing above, one way to create dynamic modules is to use blocks and define the values null from a lookup in a map when you use Terraform 0.12. Like this:

variable "vcn_id" {}
variable "compartment_ocid" {}
variable "dhcp_options" {}
variable "dhcp_display_name" {}

resource "oci_core_dhcp_options" "CreateDHCPOptions" {
    compartment_id = var.compartment_ocid
    display_name = var.dhcp_display_name
    vcn_id = var.vcn_id 
    dynamic "options" {
        iterator = dhcpoptions
        for_each = [for y in var.dhcp_options : {
        type = y.dhcp_type 
        server_type = lookup(y, "dhcp_server_type", null) 
        custom_dns_servers = lookup(y, "custom_dns_servers", null) 
        search_domain_names = lookup(y, "search_domain_names", null)
      content {
          type = dhcpoptions.value.type
          server_type = dhcpoptions.value.server_type
          custom_dns_servers = dhcpoptions.value.custom_dns_servers
          search_domain_names = dhcpoptions.value.search_domain_names

As I talk in the video sometimes you don’t pass all values in the options block. If we look example from Terraform documentation to create DHCP Options resource it looks like this:

resource "oci_core_dhcp_options" "test_dhcp_options" {
    compartment_id = "${var.compartment_id}"
    options {
        type = "DomainNameServer"
        server_type = "CustomDnsServer"
        custom_dns_servers = [ "", "", "" ]

    options {
        type = "SearchDomain"
        search_domain_names = [ "test.com" ]

    vcn_id = "${oci_core_vcn.test_vcn.id}"

    defined_tags = {"Operations.CostCenter"= "42"}
    display_name = "${var.dhcp_options_display_name}"
    freeform_tags = {"Department"= "Finance"}

You see there are two options blocks now, one for DNS and other one for SearchDomain. Iterating over map with for_each is a handy way of doing it in my opinion. If we look variable what I have for dhcp_options you can see how the options are build up.

variable "vcn_dns_label" { default = "demo" }

variable "dhcp_display_name" { default = "MyCustomDHCP" }
variable "custom_dhcp_options" { default = {
    option1 =  {
     dhcp_type = "DomainNameServer"
     dhcp_server_type = "CustomDnsServer"
     custom_dns_servers = [ "", ""]
option2 = {
dhcp_type = "SearchDomain"
search_domain_names = [ "thatfinnishguy.blog" ]

You can label them as you like (I use option1, option2 etc in this case) and then define the necessary variables inside the map. When you use lookup in the module it will not apply them to that options block where they don’t exist.

I recommend you to try it, once you get hold on modules it’s very easy to use same for all you do with Terraform!

All code I used in my example is available from my Git repo.

One thought on “Terraform and OCI DHCP Options”

  1. Your demonstrations are great! Thank you for sharing. I have a question regarding the custom DNS servers. Do you have to have the DNS server already created before creating the module or when you execute the module, it creates it automatically for you and works as a dhcp server? I’m really not sure how the custom DNS servers work on OCI? Any information is appreciated

Leave a Reply

Your email address will not be published.