Note:

Configure Private DNS Zones, Views, and Resolvers to Accelerate OCI Architect Professional Certification with Terraform

Introduction

Achieving Oracle Cloud Infrastructure (OCI) Architect Professional certification demands a deep understanding of Oracle Cloud and hands-on experience. This tutorial series accelerates your journey by leveraging Infrastructure as Code (IaC) with Terraform and Ansible.

image

Figure 1 illustrates the architecture to be deployed for the OCI Architect Professional Certification Lab 2: Oracle Cloud Infrastructure Architect Professional (Oracle University Lab - 6h 14m).

image Figure 1: Local Peering Gateway (LPG) Endpoints to Create Private DNS Domain Name

Private DNS Key Benefits

Private DNS offers several advantages for managing and securing your OCI resources. This includes but not limited to the following:

We will dive into how to leverage OCI’s private DNS to manage custom domains and connect resources across networks. You will learn to create private zones, define records, and configure resolvers for internal use, giving you granular control over resource access within OCI.

Semi-Automated Approach in Seven Tasks

The tutorial will guide you through automating a scalable and multi-VCN environment in OCI with private DNS resolution. Using the OCI Console, Terraform, and Ansible, you will create two VCNs, establish local peering gateways (LPGs) between them, launch a virtual machine (VM) instance, configure custom private DNS zones, and thoroughly test DNS resolution before and after setting up the VCN resolver. By the end, you will have a fully functional multi-VCN environment with private DNS functionality across your networks.

Objectives

This is the second tutorial of the series following tutorial 1: Lab 1: Accelerate Oracle Cloud Infrastructure Architect Professional Certification with Terraform to accelerate your OCI Architect Professional Certification (2024) preparation. We leverage IaC principles with Terraform and Ansible, focusing on core DNS concepts relevant to the exam. While the certification hands-on labs: Lab 2: Oracle Cloud Infrastructure Architect Professional (Oracle University Lab - 6h 14m) are comprehensive, Lab 2 can be time-consuming, taking over 30 minutes to complete manually. Automating routine tasks like the creation of VCNs, public and private subnets, LPGs, and VMs, significantly reduces completion time by over 80% as demonstrated in Tutorial 1: Accelerate Oracle Cloud Infrastructure Architect Professional Certification with Terraform, allowing you to focus on mastering core OCI DNS concepts.

Prerequisites

Task 1: Create Two Virtual Cloud Networks

Manual Option:

You can create VCNs manually using the OCI Console. To indicate this manual creation, the is_vcn1_created and is_vcn2_created flags should be initialized to false.

To create core networking resources like VCN, internet gateway, route table, security list, public and private subnets, see Virtual Networking Quickstart.

image Figure 2: Console Views to Collect VCN-01/VCN-02 OCIDs, and VCN-01 Public Subnet OCID

Go to the OCI Console, navigate to Networking, Virtual Cloud Networks and view the details of VCN-01, note its OCID and the OCID of its public subnet. Do the same for VCN-02, note down its OCIDs, and add the collected OCIDs to your Terraform configuration file (input.auto.tfvars or variables.tf).

# Create VCN-01 and VCN-02 with OCI VCN Wizard (set is_vcn1_created and is_vcn2_created to false)
is_vcn1_created    = false
is_vcn2_created    = false

# Update VCN-01 OCID and its Public Subnet OCID, as well as VCN-02 OCID
vcn1_id            = "REPLACE_CREATED_VCN1_OCID_HERE"
public_subnet1_id  = "REPLACE_CREATED_PUBLIC_SUBNET1_OCID_HERE"
vcn2_id            = "REPLACE_CREATED_VCN2_OCID_HERE"

Automated Option:

We also provide two automation options to create the VCN (VCN-01 and VCN-02): a Root Module approach and a Child Module approach. The first one is simpler and suitable for development and testing or one-time VCNs deployment. The second one offers better organization and scalability for larger, complex deployments, promoting code reusability and maintainability, making it ideal for production environments.

To instruct Terraform to create the VCNs, first you need to set both is_vcn1_created and is_vcn2_created flags to true in input.auto.tfvars or as default values in variables.tf. Then specify the VCN CIDR block (vcn?_cidr_block), public subnet CIDR block (public_subnet?_cidr_block), private subnet CIDR block (private_subnet?_cidr_block), and hostname prefix (host_name?_prefix). Variable names are abstracted through the use of question mark (?) as a placeholder. By replacing the ? with either 1 or 2, you will define separate configurations for VCN-01 and VCN-02, respectively.

You also need to define the values for specific variables: oci_regions (mapping region identifiers to keys), network_deployment_option (TF-ROOT-MODULE or TF-CHILD-MODULE) and dipslay_name_prefix (for example,AP-Lab-02-1). The final VCN display name includes the network_deployment_option value to generate comprehensive names (for example, PHX-AP-LAB02-1-TF-ROOT-MODULE-VCN-01).

Task 2: Create Two Local Peering Gateways

Manual Option:

To create LPGs in OCI manually, see Creating a Local Peering Gateway. In this case, set the is_lpg1_created and is_lpg2_created flags to false in your configuration file (input.auto.tfvars or variables.tf).

Automated Option:

To automate the task using Terraform set these flags to true. This instructs Terraform to create LPG-01 and LPG-02.

# Create 2 Local Peering Gateways (LPG-01 and LPG-02) then peer them.
is_lpg1_created = true
is_lpg2_created = true

The following Terraform code snippet creates both LPG-01 and LPG-02 and establishes a peering relationship between them, enabling private connectivity between your VCNs.

# LPG-01 Creation
resource "oci_core_local_peering_gateway" "lpg-01" {
  count = (var.is_vcn1_created && var.is_lpg1_created) ? 1 : 0

  # Required
  compartment_id = var.compartment_id
  display_name   = var.is_vcn1_created ?  "${try(var.regions_keys_map[var.region], "OCI")}-${var.display_name_prefix}-${var.network_deployment_option}-LPG-01" : "${try(var.regions_keys_map[var.region], "OCI")}-${var.display_name_prefix}-LPG-01"
  vcn_id = var.is_vcn1_created ? module.vcn-01.vcn_ocid : var.vcn1_id
}

# LPG-02 Creation
resource "oci_core_local_peering_gateway" "lpg-02" {
  depends_on     = [oci_core_local_peering_gateway.lpg_01]
  count = (var.is_vcn2_created && var.is_lpg2_created) ? 1 : 0

  # Required
  compartment_id = var.compartment_id
  display_name   = var.is_vcn1_created ? "${try(var.regions_keys_map[var.region], "OCI")}-${var.display_name_prefix}-${var.network_deployment_option}-LPG-02" : "${try(var.regions_keys_map[var.region], "OCI")}-${var.display_name_prefix}-LPG-02"
  vcn_id = var.is_vcn2_created ? module.vcn-02.vcn_ocid : var.vcn2_id

  # Peering lpg-02 with lpg-01
  peer_id = oci_core_local_peering_gateway.lpg_01[count.index].id
}

Task 3: Launch a Virtual Machine Instance

Manual Option:

To launch a VM instance manually through OCI Console, see Creating an Instance.

Automated Option:

We will provide an automation of the VM provisioning using a simplified version of the Terraform code from Tutorial 1: Accelerate Oracle Cloud Infrastructure Architect Professional Certification with Terraform. To instruct Terraform to create a virtual machine VM-01, set the is_instance_created flag to true. The VM’s display name will include the network_deployment_option setting (for example, PHX-AP-LAB02-1-TF-ROOT-MODULE-VM-01 or PHX-AP-LAB02-1-TF-CHILD-MODULE-VM-01) if the VCN is created with Terraform.

# Task 3: Launch a VM(VM-01) in the Public Subnet of VCN-01.
is_instance_created = true

The following Terraform code automates the creation of a VM-01 as shown in Figure 1 within VCN-01 public subnet.

resource "oci_core_instance" "this" {
  count = (var.is_instance_created) ? 1 : 0

  availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
  compartment_id              = var.compartment_id
  create_vnic_details {
    assign_private_dns_record = "true"
    assign_public_ip          = "true"
    subnet_id                 = var.is_vcn1_created ? module.vcn-01.public_subnet_ocid : var.public_subnet1_id
  }
  display_name = var.is_vcn1_created ? "${try(var.regions_keys_map[var.region], "OCI")}-${var.display_name_prefix}-${var.network_deployment_option}-VM-0${count.index + 1}" : "${try(var.regions_keys_map[var.region], "OCI")}-${var.display_name_prefix}-VM-0${count.index + 1}"

  instance_options {
    are_legacy_imds_endpoints_disabled = "false"
  }
  metadata = {
    "ssh_authorized_keys" = "${file(var.ssh_public_key)}"
  }

  shape = var.shape_name
  shape_config {
    memory_in_gbs             = var.shape_memory_in_gbs
    ocpus                     = var.shape_numberof_ocpus
  }
  source_details {
    source_id   = var.image_ids[var.region]
    source_type = "image"
  }
}

Task 4: Create Custom Private Zones for VCN-01 and VCN-02

OCI’s private DNS zones store internal DNS records, accessible only within a VCN. To understand the DNS concepts, we will first show how to manually create two custom private zones. Figure 3 illustrates the creation of a private DNS Zone zone-a.local in VCN-01 (PHX-AP-LAB02-1-VCN-01) and add a record to it .

image Figure 3: Create Private DNS zone and associate it with VCN-01, then add a new record to the zone

Manual Option:

  1. Create and configure a private DNS zone for VCN-01 (zone-a.local).

    1. Go to the OCI Console, navigate to Networking, DNS Management, Zones and click Private Zones.

    2. Click Create Zone, enter zone name (zone-a.local), select Select existing DNS Private View, PHX-AP-LAB02-1-VCN-01 as the associated VCN and click Create.

    3. After the zone is created, view the automatically generated NS and SOA records.

    4. Click Manage Records and select Add Record.

    5. Enter the following information and click Add Record.

      • Name: Enter server01.
      • Type: Select A - IPv4 Address.
      • TTL: Enter 30 seconds (unlock the field if necessary).
      • Address: Enter 10.0.0.2.
    6. Click Publish Changes and Confirm Publish Changes.

      Notes: Wait for the operation to finish successfully (state changed from UPDATING to ACTIVE).

  2. Create and configure a private DNS zone for VCN-02 (zone-b.local). Follow the same steps as Figure 3 to create a private zone for VCN-02 (PHX-AP-LAB02-1-VCN-02).

    1. Navigate to Zones, Private Zones, click Create Zone.

    2. Enter Name as zone-b.local, select Select existing DNS Private View, PHX-AP-LAB02-1-VCN-02 as the associated VCN and click Create.

    3. Click Manage Records and select Add Record.

    4. Enter the following information and click Add Record.

      • Name: Enter server01.
      • Type: Select A - IPv4 Address.
      • TTL: Enter 60 seconds (unlock the field if necessary).
      • Address: Enter 172.16.0.123.
    5. Click Publish Changes and Confirm Publish Changes.

      Notes: If you skip a manual creation step, it leads to errors like: zone not found: 3 (NXDOMAIN).

Automated Option:

This tutorial also provides an advanced automated approach using Ansible. Ansible is an open-source automation tool that manages configurations for your infrastructure. In this context, an Ansible playbook is a collection of tasks that automate the creation of private DNS zones. For more information, see Ansible Playbook Keywords.

Set is_task4_automated to true in input.auto.tfvars or in variabes.tf to trigger an Ansible playbook execution in playbooks.sh, automating in a single run both private DNS zones creation and records addition.

# Task 4: Create and Configure two DNS zones (zone-a and zone-b).
is_task4_automated = true

Using Terraform’s local-exec provisioner, you can execute an Ansible playbook to automatically create zone-a.local in VCN-01 and zone-b.local zones in VCN-02 with their respective records. For more information, see Source Code: oci-ansible-collection.

# Create 2 Custom Private Zones and Associated Records in OCI
resource "null_resource" "ansible-create-zones-playbook" {
  count      = (var.is_task4_automated) ? 1 : 0

  # Create inventory
  provisioner "local-exec" {
    command = "sh ~/terraform-ws/lab2-demos/playbooks.sh"
  }
}

Task 5: Test your Instance for Associated Zone A

Manual Option:

Manually SSH into the VM instance to verify if your VM instance is associated with zone-a.local.

  1. SSH into the instance with the public IP address.

    ssh -i <private_ssh_key> <public_ip_address>
    
  2. Look up DNS records for server01.zone-a.local.

    host server01.zone-a.local
    

    Expected Output:

    server01.zone-a.local has address 10.0.0.2
    
  3. Verify the system generated zone entry.

    host -t NS zone-a.local
    

    Expected Output:

    zone-a.local has NS record vcn-dns.oraclevcn.com.
    
  4. Verify the authority record for the zone.

    host -t SOA zone-a.local
    

    Expected Output:

    zone-a.local has SOA record ven-dns.oraclevcn.com.
    hostmaster.oracle.com. 2 3600 3600 3600 10
    
  5. Observe the difference in DNS resolution based on the associated VCN views.

    host server01.zone-b.local
    

    Expected Output:

    server01.zone-b.local not found: 3 (NXDOMAIN)
    

    The output indicates that zone-b.local is not associated with any of the VCN’s views.

Automated Option:

Set the is_test_instance_associated_zone_a flag to true to instruct Terraform to test the VM-01 association with zone-a.local.

# Test Instance for Associated Zone (zone-a.local)
is_test_instance_associated_zone_a = true

The following Terraform code uses remote-exec provisioner to automate the testing of the VM-01 zone association.

resource "null_resource" "dns_test_1" {
  depends_on = [oci_core_instance.this[0]]
  count      = (var.is_test_instance_associated_zone_a) ? 1 : 0

  connection {
    agent       = false
    timeout     = "30m"
    host        = oci_core_instance.this[0].public_ip
    user        = "opc"
    private_key = file(var.ssh_private_key) # Avoid exposing SSH keys directly
  }

  provisioner "remote-exec" {
    inline = [
      "echo \"Begin Test 1 - Instance Associated Zone-A\"",
      "echo \"1. Successful SSH to the instance using public ip address: ${oci_core_instance.this[0].public_ip}\"",
      "echo \"2. Look up DNS records for server01.zone-a.local.\"",
      "host server01.zone-a.local",
      "echo \"3. Verify the system-generated zone entry.\"",
      "host -t NS zone-a.local",
      "echo \"4. Verify the authority record for the zone.\"",
      "host -t SOA zone-a.local",
      "echo \"5. Observe the difference in DNS resolution based on the associated VCN views.\"",
      "host server01.zone-b.local",
      "echo \"End Test 1 - Instance Associated Zone-A\"",    ]
  }
}

Task 6: Configure the VCN Resolver and Add the Other Private View

Manual Option:

To configure the VCN resolver manually, navigate to the VCN-01 details page on the OCI Console, select VCN Resolver and Private View.

Select VCN-02 from the drop-down menu and click Save to save the changes. Wait for the private resolver details page status to change from UPDATING to ACTIVE.

Automated Option:

To automate VCN resolver configuration, we leverage Terraform’s local-exec provisioner to run OCI CLI, Ansible playbooks, or Terraform modules.

Set the is_task6_automated flag to true to instruct Terraform.

is_task6_automated = true

The provided bash script update_resolver.sh highlights the steps to update the private resolver for VCN-01 and associate VCN-02 as a DNS private view. Additionally, a hybrid Terraform DNS configuration example for OCI is available here: terraform-oci-hybrid-dns.

# Task 6: Configure the VCN Resolver, adding the Other Private View
resource "null_resource" "run-get-resolver" {
  count      = (var.is_task6_automated) ? 1 : 0

  # Create inventory
  provisioner "local-exec" {
    command = "sh ~/terraform-ws/lab2-demos/update_resolver.sh"
  }
}

Task 7: Test your Instance for Associated Zone B

Manual Option:

Verify that the server resolves properly after configuring the VCN resolver.

  1. SSH into the instance with the public IP address.

    ssh -i <private_ssh_key> <public_ip_address>
    
  2. Look up DNS records for server01.zone-a.local.

    host server01.zone-b.local
    

    Expected Output:

    server01.zone-b.local has address 172.16.0.123
    

Note: If DNS resolution fails, wait a few minutes for changes to take effect. If needed, reboot the instance.

Automated Option:

Set the is_test_instance_associated_zone_b flag to true to instruct Terraform to test the association of VM-01 with the second zone (zone-b.local) in the second VCN (VCN-02).

# Test Instance for Assoicated Zone B
is_test_instance_associated_zone_b = true

The following code uses Terraform’s remote-exec provisioner to automate the test, verifying the VM instance’s association with zone-b.local.

resource "null_resource" "dns_test_2" {
  depends_on = [oci_core_instance.this[0]]
  count      = (var.is_test_instance_associated_zone_a) ? 1 : 0

  connection {
    agent       = false
    timeout     = "30m"
    host        = oci_core_instance.this[0].public_ip
    user        = "opc"
    private_key = file(var.ssh_private_key)
  }

  provisioner "remote-exec" {
    inline = [
      "echo \"Begin Test 2 - Instance Associated Zone-B\"",
      "echo \"1. Successfull SSH into the instance using its public ip address: ${oci_core_instance.this[0].public_ip}\"",
      "echo \"2. Look up DNS records for server01.zone-b.local.\"",
      "host server01.zone-b.local",
      "echo \"End Test 2 - Instance Associated Zone-B\""    ]
  }
}

Deployment Options

We will explore two deployment options:

To provision Lab 2 resources (VCN-01/VCN-02, LPG-01/LPG-02, and VM-01) and trigger the required tests, you need to provide default values for: image OCIDs map for each used region (image_ids), compartment OCID (compartment_id), display name prefix (display_name_prefix), networking (is_vcn1_created, is_vcn2_created, is lpg1_created, is_lpg2_created, vcn_1_id, vcn_2_id, and public_subnet1_id), compute instance (is_instance_created, shape_name), and testing flags for instance and zone associations (is_test_instance_associated_zone_a and is_test_instance_associated_zone_b).

Option 1: Use Oracle Resource Manager (ORM)

Figure 4 shows the ORM stack creation for Lab 2 resources creation.

image Figure 4: Oracle Resource Manager - Create Lab2 Stack (VCN-01, VCN-02, LPG-01 and LPG-02, VM-01)

Terraform automates infrastructure provisioning in seven steps as shown in Figure 5: analyzing source configurations, building the Terraform template package, providing default variable values, creating ORM stacks, planning changes, applying those changes to provision resources in OCI, and optionally destroying resources. Integrating DevOps CI/CD tools like Jenkins or OCI DevOps can automate the whole process, providing a convenient, near to a single-click solution.

image Figure 5: Oracle Resource Manager Stack Workflow (create, plan, apply and destroy)

Option 2: Use Terraform Command Line Interface (CLI) (Community Edition)

Terraform CLI is a powerful infrastructure as code tool that enables flexible and scalable management of cloud resources through declarative configuration files. Download the Terraform code from here: oci-blog-fast-tracking-apcertif-part2.zip and customize the input.auto.tfvars file with your OCI details (compartment_id, image_ids), and follow the instructions in the README.md to set up the environment, run the terraform init, terraform plan and terraform apply commands to complete Lab 2.

We have included bash scripts for each task that pre-set the required Terraform flags, reducing clicks and completion time. These scripts offer multiple levels of flexibility:

In essence, this package provides guides and best practices for configuring private DNS, simplifying Lab 2 and ensuring a smooth learning experience with OCI DNS.

##########################################################################
# Terraform module: Configuring Private DNS Zones, Views, and Resolvers. #
# File Name: input.auto.tfvars                                           #
# Copyright (c) 2024 Oracle        Author: Mahamat H. Guiagoussou.       #
##########################################################################

# Working Compartment
compartment_id      = "REPLACE_WITH_YOUR_WORKING_COMPARTMENT_OCID_HERE"

# Region based display name prefix
display_name_prefix = "AP-LAB02-1"   # Replace with your prefix

# TASK 1 - Create 2 VCNs (VCN-01 and VCN-02) manually using the OCI
# VCN Wizard (semi automated option) or Terraform (Root or Child)

# Turn flags off to indicate VCN-01 and VCN-02 are not created with TF
#is_vcn1_created    = false   # Set to 'false' to create VCN-01
#is_vcn2_created    = false   # Set to 'false' to create VCN-02

# After Creating VCN-01 & VCN-02 with VCN Wizard, updae OCIDs
vcn_id            = "REPLACE_VCN1_OCID_HERE"
vcn_id            = "REPLACE_VCN2_OCID_HERE"
public_subnet_id  = "REPLACE_PUBLIC_VCN1_SUBNET_OCID_HERE"

# Create VCN-01 and VCN-02 with Terraform. Use only one of 2 options:
# (1) Root Module  - Dupplicated code ("network1.tf" & "network2.tf")
# (2) Child Module - Use an existing Terraform Network Module.

# Network Deployment Options (Root Module)
network_deployment_option = "TF-ROOT-MODULE" # "TF-CHILD-MODULE"

# Turn flags on to instruct Terraform to create VCN-02 and VCN-02
is_vcn1_created            = true   # Set to 'true' to create VCN-01
is_vcn2_created            = true   # Set to 'true' to create VCN-02

# Networking parameters: CIDR Blocks and Host Name prefix
vcn1_cidr_block            = "10.0.0.0/16"
vcn2_cidr_block            = "172.0.0.0/16"
public_subnet1_cidr_block  = "10.0.0.0/24"
public_subnet2_cidr_block  = "172.0.0.0/24"
private_subnet1_cidr_block = "10.0.1.0/24"
private_subnet2_cidr_block = "172.0.1.0/24"
host_name_prefix           = "<region-key>apl1"

# Task 2: Create two(2) Local Peering Gateways (LPG-01 & LPG-02)
is_lpg1_created            = false
is_lpg2_created            = false

# Task 3: Launch a VM (VM-01) in the public subnet
is_instance_created        = false

# Shape Definition
shape_name                 = "VM.Standard.A1.Flex"
shape_memory_in_gbs        = "6"
shape_numberof_ocpus       = "1"

# SSH keys
ssh_public_key             = "REPLACE_SSH_PUBLIC_KEY_PATH"
ssh_private_key            = "REPLACE_SSH_PRIVATE_KEY_PATH"

# Task 4: Create and Configure OCI Private Zones (zone-a/b.local)
is_task4_automated         = false

# Task 5: Test your instance for Associated Zone A.
is_test_instance_associated_zone_a = false

# Task 6: Configure the VCN Resolver, adding the Other Private View.
is_task6_automated         = false

# Task 7: Test your Instance for Associated Zone B.
is_test_instance_assoracle = false

This tutorial provided a comprehensive approach to configuring private DNS zones, views, and resolvers in Oracle Cloud Infrastructure (OCI). It offered both manual and automated methods to create, configure, and test these components. This hands-on, semi-automated approach ensures a solid understanding of DNS resolution across different VCNs in OCI.

Through seven tasks, you have created two VCNs, established LPGs, launched a VM, configured two custom DNS zones, and verified VM DNS association before and after adding the second VCN as an associated private view to the DNS Resolver of the first VCN.

Next Steps

By automating OCI infrastructure provisioning using Infrastructure as Code IaC tools like Terraform, Ansible, Oracle Resource Manager ORM, and OCI CLI bash shell scripting, this tutorial helps OCI Architect Professional Certification (2024) candidates accelerate complex tasks, such as those in Lab 2 DNS configurations, from 30 minutes to just 5 minutes. This time efficiency boost reduces human errors, lowers resource management costs, and increases success rates at scale.

Learn Terraform and Ansible, then leverage ORM, OCI CLI, and bash scripting to explore best IaC practices for effective OCI infrastructure management.

Acknowledgments

More Learning Resources

Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.

For product documentation, visit Oracle Help Center.