Friday, March 14, 2025

 

OCI - Shielded compute instance creation through Terraform


We all know about the features of Oracle cloud infrastructure (OCI). It has big portfolio to manage any real time environments. One the common requirement is making automation of infrastructure provisioning. At real time environments it’s not easy to perform the provisioning of each resource by clicks via GUI. It will take lot of time. To solve that “Infrastructure as a code” has been innovated. Most commonly used automation tool is Terraform.

In this article we are going to discuss how terraform can be used to create an instance in OCI.  This terraform code uses terraform module approach. In module approach we segregate the business logic from required instance specific variables. Business logic is called as module here. The module will have the code to create instance and it will accept the instance specifications as variables. By doing this way we can reuse the module for instance creations. 

 

Module for Instance

-----------------------------------

resource "oci_core_instance" "this" {

  availability_domain = var.availability_domain

  compartment_id      = var.compartment_id

  display_name        = var.display_name

  shape               = var.shape

  is_pv_encryption_in_transit_enabled = true

  create_vnic_details {

  subnet_id           = var.subnet_id

 nsg_ids =  var.nsg_ids != null ? var.nsg_ids : []

  }

 

  shape_config {

    memory_in_gbs = 4

    ocpus = 1

  }

 

  source_details{

  source_id            = var.image_id

  source_type =   "image"

  boot_volume_size_in_gbs = 50

  kms_key_id = "<kms_id>"

}

  # Shielded instance-specific setting

 # shielded = true

platform_config {

    type = "AMD_VM"

    is_measured_boot_enabled = true

    is_secure_boot_enabled = true

    is_symmetric_multi_threading_enabled = true

    is_trusted_platform_module_enabled  = true

}

  metadata = {

    ssh_authorized_keys = var.ssh_public_key

  }

 extended_metadata = var.extended_metadata

}

 

This above module code expects variables availability domain name, compartment OCID, Instance display name, Instance shape, Instance image id, SSH key, subnet ocid, nsg ocids.

Few parameters are mandatory to create the instance and few are optional. Environments might require different parameters based on their requirement. For example, instance might or might not require NSG (Network security group). Instance might not require to be shielded. In such cases modules should written to handle all such requirements. It needs to check the parameter values and based on that it should perform the provisioning. The unneeded feature can be set to null. For example in the below terraform,tfvars file we pass values for 2 instances. All 2 instance values will go through module for creation. Unneeded parameters can be set to null as we see nsg_ids below.

Terraform.tfvars

Terraform.tfvars carries the variables and values to pass to the module.

For example, for the above module we could design terraform.tfvars as below.

instance_var = {

    "MyShieldedInstance1" = {

availability_domain = "MvNG:PHX-AD-2"

compartment_id      = "ocid1.compartment.oc1..aaaaaaaamgamfabcedgwu42gozmpp4snfgzfzmqb4equ5yq"

display_name        = "MyShieldedInstance1"

shape               = "VM.Standard.E3.Flex"

image_id            = "ocid1.image.oc1.phx.aaaaaaaahgrs3zcwrvutjtni557ttrt62uggseijsmqxacr7dym423uaokcq"

ssh_public_key      = "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAhqXpiwufmWCWjfP3r44hKOXeQut7sj7yRDbJW+ /6eJqtk6qWhHHj == rsa-key-20170125."

subnet_id           = "ocid1.subnet.oc1.phx.aaaaaaaabyfqmurw7q46ox4s6fx64far4a"

nsg_ids = ["ocid1.networksecuritygroup.oc1.phx.aaaaaaaaafp2n2gkhb77ohyyvzssat2hjkbfa","ocid1.networksecuritygroup.oc1.phx.aaaaaaaa7i5ybjbbx3l2nv2ie4yynq"]

extended_metadata   = {

  project = "ShieldedInstanceProject"

}

},

    "MyShieldedInstance2" = {

availability_domain = "MvNG:PHX-AD-3"

compartment_id      = "ocid1.compartment.oc1..aaaaaaaamgamf64s7adosddcdfdfdpp4snfgzfzmqb4equ5yq"

display_name        = "MyShieldedInstance2"

shape               = "VM.Standard.E3.Flex"

image_id            = "ocid1.image.oc1.phx.aaaaaaaahgrs3zcwrvutjtni557ttrt62uggseijsmqxacr7dym423uaokcq"

ssh_public_key      = "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAhqXpiwufmWCWjfP3r44hKOXeQut7sj7yRDbJW+ /6eJqtk6qWhHHj3yZVUv/jKtfs2eTU+HsgsxBGKhiebzo598T8w== rsa-key-20170125."

subnet_id           = "ocid1.subnet.oc1.phx.aaaaaaadb4zlyx7q46ox4s6fx64far4a"

nsg_ids             = null

extended_metadata   = {

  project = "ShieldedInstanceProject"

}

},

}

 

In the above terraform.tfvars, we could see two instances with required specifications are passed. First instance MyShieldedInstance1 requires NSG to be set and MyShieldedInstance2 doesn’t require NSG settings. We can keep adding the instances as required in the terraform.tfvars. Modules need not to be modified at any point of time unless instance provisioning comes up with new features.

 The main.tf will be very simple. It just need to call the module and pass the terraform.tfvars to the module.

 module "shielded_instance" {

  source = "./modules/instance"  ===è Module location

 

  for_each          = var.instance_var

  availability_domain = each.value.availability_domain

  compartment_id      = each.value.compartment_id

  display_name        = each.value.display_name

  shape               = each.value.shape

  image_id            = each.value.image_id

  ssh_public_key      = each.value.ssh_public_key

  extended_metadata   = each.value.extended_metadata

  subnet_id           = each.value.subnet_id

  nsg_ids             = each.value.nsg_ids

}

 for_each sets the for loop and calls each instance values in terraform.tfvars.

We need to define variables in variable.tf for module and main file.

You can find more terraform codes in my github page.

https://github.com/kmkittu/Terraform


No comments:

Post a Comment

 OCI IAM - OCI Command line - Uploading API Keys to User in Default and Custom Domain In our previous post, we explored how to create users ...