Before creating database I will create jump host on public subnet so we will be able to access our database once it’s created. If I would have connection setup to our corporate network I could access the private subnet directly if my network configuration would allow it.

This way I can limit the surface on where and how people can connect to my OCI network.

The compute instance and public subnet could have configuration to allow only SSH access from my IP address and nobody else could login. Even if I’m doing something for demonstration purposes it’s something to consider, that way you create a habit where you don’t leave ports open.

Creating the instance is quite straightforward. From the console you don’t need to define too many settings if you would go from that route. Mainly networking options and which image and shape to use.

From Terraform they are almost the same but you definitely need to check the official documentation in the provider documentation from here.


In the Terraform setup I’ve left some optional variables out and also added a data source which uses a filter to take latest linux image available. That part is taken from what Stephen Cross has published, he has really good examples here.

My gets new data source and the part where I create the compute instance.

// Get latest Linux shape but exclude GPU images using

data "oci_core_images" "oraclelinux" {
  compartment_id = "${}"

  operating_system         = "${var.operating_system}"
  operating_system_version = "${var.operating_system_version}"

  # exclude GPU specific images
  filter {
    name   = "display_name"
    values = ["^([a-zA-z]+)-([a-zA-z]+)-([\\.0-9]+)-([\\.0-9-]+)$"]
    regex  = true

As you can see I’m getting the images by sending OS and OS version (in this case OEL 7.6) and excluding GPU specific images.

Compute instance get’s then created using existing values for network and values from this data source.

resource "oci_core_instance" "CreateInstance" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[0],"name")}"
  compartment_id      = "${}"
  shape               = "${var.instance_shape_name}"

  source_details {
    source_id   = "${lookup(data.oci_core_images.oraclelinux.images[0],"id")}"
    source_type = "${var.source_type}"

  create_vnic_details {
    subnet_id        = "${}"
    assign_public_ip = "${var.assign_public_ip}"
    hostname_label = "${var.instance_create_vnic_details_hostname_label}"

  display_name = "${var.instance_display_name}"

  metadata {
    ssh_authorized_keys = "${var.ssh_public_key}"

    #		user_data = "${base64encode(file(var.bootstrapfile))}" // If you want to add bootstrap scripts edit this file

  subnet_id = "${}"

On line 7 I take the newest image for my compute instance. I will not run any bootstrap scripts in this case but I could add them also if I’d like Terraform to perform additional configuration on the instance.

SSH key is created as per instructions from documentation.

VNIC is created with a variable assign_public_ip true since we are creating the instance on the public subnet and note that it will get both public and private IP.

In the I have following:



variable "operating_system" {
  default = "Oracle Linux"
} // Name for the OS

variable "operating_system_version" {
  default = "7.6"
} // OS Version

// Image for the compute instance - change this to Windows image if needed
variable "instance_shape_name" {
  default = "VM.Standard2.1"
} // Shape what to be used. Smallest shape selected by default

variable "source_type" {
  default = "image"
} // What type the image source is

variable "ssh_public_key" {
  default = "ssh-rsa xxxxx"
} // For DEMO purposes key is not shown

// Create your own SSH key for the image and paste the public key here
// See for more details
// Windows images do not use SSH key

variable "assign_public_ip" {
  default = "true"

// Since this is server in public subnet it will have a public IP
variable "instance_display_name" {
  default = "MyJumpServer"
} // Name for the instance

I’m also introducing third file now which is named It will print out information on our instance and database after execution.

I could always view information from the console after execution but this way we see public IP etc right after.

output "instanceName" {value = "${oci_core_instance.CreateInstance.display_name}"}
output "instancePublicIP" {value = "${oci_core_instance.CreateInstance.public_ip}"}
output "instancePrivateIP" {value = "${oci_core_instance.CreateInstance.private_ip}"}

Now after running Terraform I see resource gets created and in addition I see also the outputs. Private IP is given from the public subnets CIDR block.

Apply complete! Resources: 1 added, 0 changed, 0 destroyed


instanceName = MyPublicServer
instancePrivateIP =
instancePublicIP = 130.XXX.XXX.231

And to verify I can login I will use the previously made private key with opc user.

[simo@vm01 ~]# ssh opc@130.XXX.XXX.231 -i public_demo.ppk
Last login: Tue Feb 26 15:04:44 2019 from 
[opc@public-1 ~]$  uname -a
Linux public-1 4.14.35-1844.2.5.el7uek.x86_64 #2 SMP Mon Feb 4 18:24:45 PST 2019 x86_64 x86_64 x86_64 GNU/Linux

Now I have network and a jump server to access my to-be database on the private subnet. Database will be created on the next part which will be last part before summarizing everything!

Leave a Reply

Your email address will not be published. Required fields are marked *