<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Vicknesh's blog]]></title><description><![CDATA[Dr. Vicknesh advocates cloud security best practices & governance on various cloud platforms which include Microsoft Azure,  AWS & Oracle Cloud Infrastructure. ]]></description><link>https://vicknesh.cloud</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1645786324794/0o-bMiv3B.png</url><title>Vicknesh&apos;s blog</title><link>https://vicknesh.cloud</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 02:59:40 GMT</lastBuildDate><atom:link href="https://vicknesh.cloud/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Deploying Workloads on Oracle Cloud Infrastructure (OCI) via Terraform - PART 2]]></title><description><![CDATA[Welcome to Part 2 of my series Working with Terraform on Oracle Cloud Infrastructure (OCI)
If you need a refresher, visit Part 1
In Part 1, we have done the following:

Installed Terraform
Created .tf scripts
Executed the workflows, Initialize > Plan...]]></description><link>https://vicknesh.cloud/deploying-workloads-on-oracle-cloud-infrastructure-oci-via-terraform-part-2</link><guid isPermaLink="true">https://vicknesh.cloud/deploying-workloads-on-oracle-cloud-infrastructure-oci-via-terraform-part-2</guid><category><![CDATA[Terraform]]></category><category><![CDATA[Oracle]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[code]]></category><category><![CDATA[infrastructure]]></category><dc:creator><![CDATA[Dr. J Vickneshwaran]]></dc:creator><pubDate>Thu, 10 Mar 2022 15:13:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1646925103023/BgnSFkqCU.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome to Part 2 of my series <a target="_blank" href="https://vicknesh.cloud/series/oci-terraform">Working with Terraform on Oracle Cloud Infrastructure (OCI)</a></p>
<p>If you need a refresher, visit <a target="_blank" href="https://vicknesh.cloud/deploying-workloads-on-oracle-compute-infrastructure-oci-via-terraform-part-1">Part 1</a></p>
<p>In <a target="_blank" href="https://vicknesh.cloud/deploying-workloads-on-oracle-compute-infrastructure-oci-via-terraform-part-1">Part 1</a>, we have done the following:</p>
<ul>
<li>Installed Terraform</li>
<li>Created .tf scripts</li>
<li>Executed the workflows, Initialize &gt; Plan &gt; Apply</li>
<li>Authenticated our OCI tenant with the Terraform provider scripts</li>
</ul>

<p>In Part 2, let's look at how we can provision compartments &amp; provision compute &amp; network resources within these compartments.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646790284228/0gBqFYi7Q.png" alt="terraform-compartment-diagram.png" /></p>
<p>In <a target="_blank" href="https://vicknesh.cloud/deploying-workloads-on-oracle-compute-infrastructure-oci-via-terraform-part-1">Part 1</a>, we created the following .tf file which allowed Terraform to authenticate with our OCI tenant.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646792647531/b-6PVIgTC.png" alt="provider.tf.png" /></p>
<p>In Part 2, we will first need to create a compartment to store our resources that we'll be creating later. To do this, we will need 2 .tf files in our working folder.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646793630668/ldtKFgiRQ.png" alt="provider.tf.png" /></p>
<h1 id="heading-creating-the-working-directory">Creating the Working Directory</h1>
<p>Let's begin with creating the working directory to store our files in it. Once, the files are defined, we'll initialize Terraform &amp; put it to work from this directory.</p>
<p>Create a directory called 'tf-compartment' under your root directory.</p>
<pre><code>$ <span class="hljs-keyword">mkdir</span> tf-compartment
</code></pre><p>Copy the provider.tf file from the tf-provider directory to this directory (tf-compartment). Once you have that in place, let's create the <strong>compartment.tf</strong> file &amp; define the parameters. Add the following code in your file.</p>
<pre><code>resource <span class="hljs-string">"oci_identity_compartment"</span> <span class="hljs-string">"tf-compartment"</span> {
    compartment_id <span class="hljs-operator">=</span> <span class="hljs-string">"&lt;tenancy-ocid&gt;"</span>
    description <span class="hljs-operator">=</span> <span class="hljs-string">"Compartment for Terraform resources."</span>
    name <span class="hljs-operator">=</span> <span class="hljs-string">"&lt;your-compartment-name&gt;"</span>
}
</code></pre><h2 id="heading-defining-policies-on-oci">Defining Policies on OCI</h2>
<p>Let's add a policy on our OCI tenant.</p>
<ol>
<li>Navigate to <strong>Identity &amp; Security &gt; Policies</strong></li>
<li>Choose a Compartment if you have one or select the root compartment for now</li>
<li>Click <strong>Create Policy</strong> &amp; click <strong>Show manual editor</strong></li>
<li>Paste the following policy &amp; click <strong>Create</strong></li>
</ol>
<pre><code>allow group <span class="hljs-operator">&lt;</span>the<span class="hljs-operator">-</span>group<span class="hljs-operator">-</span>your<span class="hljs-operator">-</span>username<span class="hljs-operator">-</span>belongs<span class="hljs-operator">&gt;</span> to manage compartments in tenancy
</code></pre><h1 id="heading-creating-the-compartment">Creating the Compartment</h1>
<h2 id="heading-initialize">Initialize</h2>
<p>First, let's initialize Terraform within our working directory, <strong>tf-compartment</strong></p>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><p>You'll get the following output</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646795246805/bSdsqGIGm.PNG" alt="terraform init.PNG" /></p>
<h2 id="heading-plan">Plan</h2>
<p>Once, we've initialized Terraform, let's plan our deployment.</p>
<pre><code>$ terraform plan
</code></pre><p>You'll get an output like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646796529586/QOKyWMjw5.PNG" alt="terraform plan.PNG" /></p>
<h2 id="heading-apply">Apply</h2>
<p>Once we're good with our plan, let's proceed with creating the compartment by issuing the following command</p>
<pre><code>$ terraform apply
</code></pre><p>You'll get an output like these:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646797080616/U-i45kJM9.PNG" alt="terraform apply1.PNG" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646797086106/QsrA28wky.PNG" alt="terraform apply2.PNG" />
Now, let's verify the creation in our OCI tenant</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646797170589/XPWQZXdiD.PNG" alt="terraform compartment oci.PNG" /></p>
<p>There you go. Our compartment has been successfully created on OCI</p>
<h1 id="heading-provisioning-a-compute-instance-in-an-existing-vcn">Provisioning a Compute Instance in an Existing VCN</h1>
<p>Now, let's attempt to provision a compute instance in our compartment, <strong>vickterraform2</strong>. This compute instance will be provisioned into an existing Virtual Cloud Network, <strong>vickvcn1</strong>, in the OCI tenant</p>
<h2 id="heading-generating-ssh-keys">Generating SSH Keys</h2>
<p>I'll be generating SSH keys which will be used to connect to the compute instance which I'll be creating later</p>
<pre><code>$ ssh<span class="hljs-operator">-</span>keygen <span class="hljs-operator">-</span>t rsa <span class="hljs-operator">-</span>N <span class="hljs-string">""</span> <span class="hljs-operator">-</span>b <span class="hljs-number">2048</span> <span class="hljs-operator">-</span>C <span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>ssh<span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span> <span class="hljs-operator">-</span>f <span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>ssh<span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>
</code></pre><p>This will generate a public &amp; private key pair for you. You would get something like this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646875354340/XUeJJcijD.PNG" alt="ssh key gen.PNG" /></p>
<h2 id="heading-gather-important-information">Gather Important Information</h2>
<p>Before we begin creating the scripts, let's gather the important information that we'll be using in our scripts</p>
<ul>
<li><strong>Compartment Name</strong></li>
<li><strong>Compartment ID</strong></li>
<li><strong>Subnet ID</strong></li>
<li><strong>Source ID</strong></li>
<li><strong>Shape</strong></li>
<li><strong>Path of your SSH public key</strong></li>
<li><strong>Path of your SSH private key</strong></li>
</ul>

<h3 id="heading-getting-the-source-id">Getting the Source ID</h3>
<p>The Source ID refers to the ID of the source image of your compute &amp; this depends on what image (Ubuntu, CentOS, Oracle Linux, Windows, etc.) you would like to provision</p>
<p>To get the Source ID:</p>
<ol>
<li>Identify your region. Mine is <strong>us-ashburn-1</strong></li>
<li>Refer here: <a target="_blank" href="https://docs.oracle.com/en-us/iaas/images/image/527d4395-8bd4-4b28-88e4-ac242ff45da8/">Image Release Notes</a></li>
<li>For this deployment, I'll be using an <strong>Ubuntu 20.04</strong> image &amp; this is my Source ID to the image according to my region: <strong>ocid1.image.oc1.iad.aaaaaaaaos5ofuq26nipxcybznimsjnhyw3jf7mrq2r3kgpsf6zqbtqei25q</strong></li>
</ol>
<h3 id="heading-getting-the-shape">Getting the Shape</h3>
<p>The shape refers to the size of the compute instance which defines the allocation of CPUs &amp; memory</p>
<p>To get the shape:</p>
<ol>
<li>Refer here: <a target="_blank" href="https://docs.oracle.com/en-us/iaas/Content/Compute/References/computeshapes.htm#vmshapes__vm-standard">VM Standard Shapes</a></li>
<li>I'll be using a <strong>VM.Standard2.1</strong> shape</li>
</ol>
<h2 id="heading-add-policies-to-oci">Add Policies to OCI</h2>
<p>Let's add the following policy in <strong>Identity &amp; Security &gt; Identity &gt; Policies</strong> under your compartment</p>
<pre><code>allow group <span class="hljs-operator">&lt;</span>the<span class="hljs-operator">-</span>group<span class="hljs-operator">-</span>your<span class="hljs-operator">-</span>username<span class="hljs-operator">-</span>belongs<span class="hljs-operator">&gt;</span> to manage all<span class="hljs-operator">-</span>resources in compartment <span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>compartment<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>
</code></pre><h2 id="heading-creating-the-scripts">Creating the Scripts</h2>
<p>Let's setup a new working directory for this called 'tf-compute'</p>
<pre><code>$ <span class="hljs-keyword">mkdir</span> tf-compute
</code></pre><p>Copy your 'provider.tf' file into this directory</p>
<pre><code>$ cp ../tf<span class="hljs-operator">-</span>provider<span class="hljs-operator">/</span>provider.tf .
</code></pre><p>Let's also copy the 'availability-domains.tf' file which we created in the initial setup into this directory</p>
<pre><code>cp ../tf<span class="hljs-operator">-</span>provider<span class="hljs-operator">/</span>availability<span class="hljs-operator">-</span>domains.tf .
</code></pre><p>The 'availability-domains.tf' has the following code</p>
<pre><code><span class="hljs-attribute">data</span> <span class="hljs-string">"oci_identity_availability_domains"</span> <span class="hljs-string">"ads"</span> {
  <span class="hljs-attribute">compartment_id</span> = <span class="hljs-string">"&lt;tenancy-ocid&gt;"</span>
}
</code></pre><p>Let's also create an 'outputs.tf' file in the 'tf-compute' directory</p>
<pre><code>output <span class="hljs-string">"name-of-first-availability-domain"</span> {
  value <span class="hljs-operator">=</span> data.oci_identity_availability_domains.ads.availability_domains[<span class="hljs-number">0</span>].<span class="hljs-built_in">name</span>
}
</code></pre><p>Now, we have the following files in our tf-compute directory</p>
<ul>
<li>provider.tf</li>
<li>availability-domains.tf</li>
<li>outputs.tf</li>
</ul>

<p>Let's initialize &gt; plan &gt; apply our Terraform scripts</p>
<pre><code>$ terraform init
$ terraform plan
$ terraform apply
</code></pre><p>Once you've hit the terraform apply, you'll be provided with an output of your availability domain</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646878417831/nqPaCsoCb.PNG" alt="terraform apply3.PNG" /></p>
<h3 id="heading-declare-the-compute-resource">Declare the Compute Resource</h3>
<p>Now that we're ready to provision the compute instance, let's create a 'compute.tf' file &amp; add the following code into the file</p>
<pre><code><span class="hljs-attribute">resource</span> <span class="hljs-string">"oci_core_instance"</span> <span class="hljs-string">"ubuntu_instance"</span> {
    <span class="hljs-comment"># Required</span>
    <span class="hljs-attribute">availability_domain</span> = data.oci_identity_availability_domains.ads.availability_domains[<span class="hljs-number">0</span>].name
    compartment_id = <span class="hljs-string">"&lt;compartment-ocid&gt;"</span>
    shape = <span class="hljs-string">"VM.Standard2.1"</span>
    source_details {
        <span class="hljs-attribute">source_id</span> = <span class="hljs-string">"&lt;source-ocid&gt;"</span>
        source_type = <span class="hljs-string">"image"</span>
    }

    <span class="hljs-comment"># Optional</span>
    display_name = <span class="hljs-string">"&lt;your-ubuntu-instance-name&gt;"</span>
    create_vnic_details {
        <span class="hljs-attribute">assign_public_ip</span> = <span class="hljs-literal">true</span>
        subnet_id = <span class="hljs-string">"&lt;subnet-ocid&gt;"</span>
    }
    metadata = {
        <span class="hljs-attribute">ssh_authorized_keys</span> = file(<span class="hljs-string">"&lt;ssh-public-key-path&gt;"</span>)
    } 
    preserve_boot_volume = <span class="hljs-literal">false</span>
}
</code></pre><p>This is my completed file</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646878881954/mFHP3HC3-.PNG" alt="compute tf.PNG" /></p>
<p>Now, let's run our scripts</p>
<pre><code>$ terraform init
$ terraform plan
$ terraform apply
</code></pre><p>And, we have successfully created our Ubuntu server via Terraform. Also, let's verify this on the OCI console</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646882211194/_9qxA3-G9.PNG" alt="create instance.PNG" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646882261692/dKozCMS6o.PNG" alt="vick ubuntu.PNG" /></p>
<p>Let's also try connecting to this server</p>
<pre><code>$ ssh <span class="hljs-operator">-</span>i <span class="hljs-operator">&lt;</span>ssh<span class="hljs-operator">-</span><span class="hljs-keyword">private</span><span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>path<span class="hljs-operator">&gt;</span> ubuntu@<span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span><span class="hljs-keyword">public</span><span class="hljs-operator">-</span>ip<span class="hljs-operator">-</span><span class="hljs-keyword">address</span><span class="hljs-operator">&gt;</span>
</code></pre><p>And there you go. We've successfully accessed the Ubuntu server</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646882490252/ppm2ynrwn.PNG" alt="vick ubuntu1.PNG" /></p>
<p>Now that I've tested the deployment &amp; it's working, I will proceed to delete this compute instance</p>
<pre><code>$ terraform destroy
</code></pre><p>Simultaneously on the console, the instance is getting terminated</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646884000855/zguam76JB.PNG" alt="instance terminating.PNG" /></p>
<p>Once the instance is completely terminated, you will get the following output</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646884060275/QS_9DqMLV.PNG" alt="instance terminated.PNG" /></p>
<h1 id="heading-creating-a-new-virtual-cloud-network-vcn">Creating a New Virtual Cloud Network (VCN)</h1>
<p>In this section,  I will demonstrate the creation of a new Virtual Cloud Network (VCN) &amp; its associated components such as subnets, gateways, security lists &amp; more</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646884971080/qXyUc-YAj.png" alt="creating a vcn.png" /></p>
<h2 id="heading-gather-important-information">Gather Important Information</h2>
<p>Before we begin, let's gather the important information that we'll be using in our scripts</p>
<ul>
<li><strong>Compartment Name</strong></li>
<li><strong>Compartment ID</strong></li>
<li><strong>Region</strong></li>
</ul>

<h2 id="heading-create-a-working-directory">Create a Working Directory</h2>
<p>Let's create a new working directory for this demo &amp; let's name it 'tf-vcn'</p>
<pre><code>$ <span class="hljs-keyword">mkdir</span> tf-vcn
</code></pre><p>Copy the 'provider-tf' file from the 'tf-provider' directory into this directory</p>
<pre><code>cp ../tf<span class="hljs-operator">-</span>provider<span class="hljs-operator">/</span>provider.tf .
</code></pre><h2 id="heading-declaring-the-vcn-configuration">Declaring the VCN Configuration</h2>
<p>Now, let's create a file called 'vcn-module.tf' &amp; insert the following code into it</p>
<pre><code><span class="hljs-comment"># Source from https://registry.terraform.io/modules/oracle-terraform-modules/vcn/oci/</span>
<span class="hljs-built_in">module</span> <span class="hljs-string">"vcn"</span>{
  source  = <span class="hljs-string">"oracle-terraform-modules/vcn/oci"</span>
  version = <span class="hljs-string">"3.1.0"</span>
  <span class="hljs-comment"># insert the 5 required variables here</span>

  <span class="hljs-comment"># Required Inputs</span>
  compartment_id = <span class="hljs-string">"&lt;compartment-ocid&gt;"</span>
  region = <span class="hljs-string">"&lt;region-identifier&gt;"</span>

  internet_gateway_route_rules = <span class="hljs-literal">null</span>
  local_peering_gateways = <span class="hljs-literal">null</span>
  nat_gateway_route_rules = <span class="hljs-literal">null</span>

  <span class="hljs-comment"># Optional Inputs</span>
  vcn_name = <span class="hljs-string">"vcn-module"</span>
  vcn_dns_label = <span class="hljs-string">"vcnmodule"</span>
  vcn_cidrs = [<span class="hljs-string">"10.0.0.0/16"</span>]

  create_internet_gateway = <span class="hljs-literal">true</span>
  create_nat_gateway = <span class="hljs-literal">true</span>
  create_service_gateway = <span class="hljs-literal">true</span>  
}
</code></pre><p>Here's a sample of my code</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646919835663/aIs_Tt-Cg.PNG" alt="vcn module.PNG" /></p>
<p>Let's also create an 'outputs.tf' file &amp; insert the following code to get the information of the VCN once we run the scripts</p>
<pre><code><span class="hljs-comment"># Outputs for the vcn module</span>

<span class="hljs-attribute">output</span> <span class="hljs-string">"vcn_id"</span> {
  <span class="hljs-attribute">description</span> = <span class="hljs-string">"OCID of the VCN that is created"</span>
  value = module.vcn.vcn_id
}
output <span class="hljs-string">"id-for-route-table-that-includes-the-internet-gateway"</span> {
  <span class="hljs-attribute">description</span> = <span class="hljs-string">"OCID of the internet-route table. This route table has an internet gateway to be used for public subnets"</span>
  value = module.vcn.ig_route_id
}
output <span class="hljs-string">"nat-gateway-id"</span> {
  <span class="hljs-attribute">description</span> = <span class="hljs-string">"OCID for NAT gateway"</span>
  value = module.vcn.nat_gateway_id
}
output <span class="hljs-string">"id-for-for-route-table-that-includes-the-nat-gateway"</span> {
  <span class="hljs-attribute">description</span> = <span class="hljs-string">"OCID of the nat-route table - This route table has a nat gateway to be used for private subnets. This route table also has a service gateway."</span>
  value = module.vcn.nat_route_id
}
</code></pre><h2 id="heading-creating-the-vcn">Creating the VCN</h2>
<p>Now that we have the required scripts configured, let's create the VCN</p>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><pre><code>$ terraform plan
</code></pre><pre><code>$ terraform apply
</code></pre><p>And there you go. We've successfully created the VCN &amp; the gateways</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646920332013/BEAz6_mmo.PNG" alt="vcn created.PNG" /></p>
<p>Let's also verify this on the OCI console</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646920435351/4T3tZuS4t.PNG" alt="vcn oci console.PNG" />
Notice that we don't have any subnets in our VCN yet. We'll be creating this later</p>
<h2 id="heading-customizing-the-vcn">Customizing the VCN</h2>
<p>Before we jump on to create subnets, I would like to define security lists for my subnets</p>
<h3 id="heading-creating-a-security-list-for-the-private-subnet">Creating a Security List for the Private Subnet</h3>
<p>Let's create a file called 'private-security-list.tf' &amp; add the following code into it</p>
<pre><code><span class="hljs-comment"># Source from https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_security_list</span>

<span class="hljs-attribute">resource</span> <span class="hljs-string">"oci_core_security_list"</span> <span class="hljs-string">"private-security-list"</span>{

<span class="hljs-comment"># Required</span>
  <span class="hljs-attribute">compartment_id</span> = <span class="hljs-string">"&lt;compartment-ocid&gt;"</span>
  vcn_id = module.vcn.vcn_id

<span class="hljs-comment"># Optional</span>
  display_name = <span class="hljs-string">"security-list-for-private-subnet"</span>
}
</code></pre><p>Let's also add an egress rule to this security list by adding the following code into our file</p>
<pre><code>
  egress_security_rules {
      stateless <span class="hljs-operator">=</span> <span class="hljs-literal">false</span>
      destination <span class="hljs-operator">=</span> <span class="hljs-string">"0.0.0.0/0"</span>
      destination_type <span class="hljs-operator">=</span> <span class="hljs-string">"CIDR_BLOCK"</span>
      protocol <span class="hljs-operator">=</span> <span class="hljs-string">"all"</span> 
  }
</code></pre><p>Here's a sample of my code
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646921603122/0zwRS61bL.PNG" alt="SL private subnet.PNG" /></p>
<p>Also, let's add the following code into the 'outputs.tf' file</p>
<pre><code># Outputs <span class="hljs-keyword">for</span> <span class="hljs-keyword">private</span> security <span class="hljs-built_in">list</span>

output <span class="hljs-string">"private-security-list-name"</span> {
  value = oci_core_security_list.<span class="hljs-keyword">private</span>-security-<span class="hljs-built_in">list</span>.display_name
}
output <span class="hljs-string">"private-security-list-OCID"</span> {
  value = oci_core_security_list.<span class="hljs-keyword">private</span>-security-<span class="hljs-built_in">list</span>.id
}
</code></pre><p>Once we have created our scripts, let's run the creation of the security list for our private subnet</p>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><pre><code>$ terraform plan
</code></pre><pre><code>$ terraform apply
</code></pre><p>And we've successfully created our security list along with its egress rule</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646922257025/pUae3yci_.PNG" alt="SL created.PNG" /></p>
<p>Now that's successful, let's also create ingress rules for our security lists. In the 'private-security-list.tf', let's add the following code into it</p>
<pre><code>ingress_security_rules { 
      stateless = <span class="hljs-keyword">false</span>
      source = "10.0.0.0/16"
      source_type = "CIDR_BLOCK"
      # <span class="hljs-keyword">Get</span> protocol numbers <span class="hljs-keyword">from</span> https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml TCP <span class="hljs-keyword">is</span> <span class="hljs-number">6</span>
      protocol = "6"
      tcp_options { 
          min = <span class="hljs-number">22</span>
          max = <span class="hljs-number">22</span>
      }
    }
  ingress_security_rules { 
      stateless = <span class="hljs-keyword">false</span>
      source = "0.0.0.0/0"
      source_type = "CIDR_BLOCK"
      # <span class="hljs-keyword">Get</span> protocol numbers <span class="hljs-keyword">from</span> https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml ICMP <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>  
      protocol = "1"

      # <span class="hljs-keyword">For</span> ICMP <span class="hljs-keyword">type</span> <span class="hljs-keyword">and</span> code see: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
      icmp_options {
        <span class="hljs-keyword">type</span> = <span class="hljs-number">3</span>
        code = <span class="hljs-number">4</span>
      } 
    }   

  ingress_security_rules { 
      stateless = <span class="hljs-keyword">false</span>
      source = "10.0.0.0/16"
      source_type = "CIDR_BLOCK"
      # <span class="hljs-keyword">Get</span> protocol numbers <span class="hljs-keyword">from</span> https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml ICMP <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>  
      protocol = "1"

      # <span class="hljs-keyword">For</span> ICMP <span class="hljs-keyword">type</span> <span class="hljs-keyword">and</span> code see: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
      icmp_options {
        <span class="hljs-keyword">type</span> = <span class="hljs-number">3</span>
      } 
    }
</code></pre><p>Once again, let's run our scripts</p>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><pre><code>$ terraform plan
</code></pre><pre><code>$ terraform apply
</code></pre><p>Now that it has successfully ran, we are able to see the ingress &amp; egress rules created for the security list for the private subnet</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646922977169/JnrolDyPu.PNG" alt="SL Ingress.PNG" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646922985360/i7sfnv2JH.PNG" alt="SL Egress.PNG" /></p>
<h3 id="heading-creating-a-security-list-for-the-public-subnet">Creating a Security List for the Public Subnet</h3>
<p>Now, let's replicate the above operations for our public subnet. Let's copy the file 'private-security-list.tf' to a new file called 'public-security-list.tf' &amp; let's modify the parameters</p>
<pre><code>$ cp <span class="hljs-keyword">private</span><span class="hljs-operator">-</span>security<span class="hljs-operator">-</span>list.tf <span class="hljs-keyword">public</span><span class="hljs-operator">-</span>security<span class="hljs-operator">-</span>list.tf
</code></pre><p>Let's change the code <strong>private-security-list</strong> in the resource block to <strong>public-security-list</strong> &amp; change the display_name from <strong>security-list-for-private-subnet</strong> to <strong>security-list-for-public-subnet</strong></p>
<p>We'll maintain the egress rule. However, for the ingress rule let's change the <strong>source = "10.0.0.0/16"</strong> to <strong>source = "0.0.0.0/0"</strong></p>
<p>Your code should look like this</p>
<pre><code>
ingress_security_rules { 
      stateless = <span class="hljs-keyword">false</span>
      source = "0.0.0.0/0"
      source_type = "CIDR_BLOCK"
      # <span class="hljs-keyword">Get</span> protocol numbers <span class="hljs-keyword">from</span> https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml TCP <span class="hljs-keyword">is</span> <span class="hljs-number">6</span>
      protocol = "6"
      tcp_options { 
          min = <span class="hljs-number">22</span>
          max = <span class="hljs-number">22</span>
      }
    }
  ingress_security_rules { 
      stateless = <span class="hljs-keyword">false</span>
      source = "0.0.0.0/0"
      source_type = "CIDR_BLOCK"
      # <span class="hljs-keyword">Get</span> protocol numbers <span class="hljs-keyword">from</span> https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml ICMP <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>  
      protocol = "1"

      # <span class="hljs-keyword">For</span> ICMP <span class="hljs-keyword">type</span> <span class="hljs-keyword">and</span> code see: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
      icmp_options {
        <span class="hljs-keyword">type</span> = <span class="hljs-number">3</span>
        code = <span class="hljs-number">4</span>
      } 
    }   

  ingress_security_rules { 
      stateless = <span class="hljs-keyword">false</span>
      source = "10.0.0.0/16"
      source_type = "CIDR_BLOCK"
      # <span class="hljs-keyword">Get</span> protocol numbers <span class="hljs-keyword">from</span> https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml ICMP <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>  
      protocol = "1"

      # <span class="hljs-keyword">For</span> ICMP <span class="hljs-keyword">type</span> <span class="hljs-keyword">and</span> code see: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
      icmp_options {
        <span class="hljs-keyword">type</span> = <span class="hljs-number">3</span>
      } 
    }
</code></pre><p>Let's also add the following code to the 'outputs.tf' file</p>
<pre><code>
# Outputs <span class="hljs-keyword">for</span> <span class="hljs-built_in">public</span> <span class="hljs-keyword">security</span> list

output "public-security-list-name" {
  <span class="hljs-keyword">value</span> = oci_core_security_list.<span class="hljs-built_in">public</span>-<span class="hljs-keyword">security</span>-list.display_name
}
output "public-security-list-OCID" {
  <span class="hljs-keyword">value</span> = oci_core_security_list.<span class="hljs-built_in">public</span>-<span class="hljs-keyword">security</span>-list.id
}
</code></pre><p>Now, let's run our scripts</p>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><pre><code>$ terraform plan
</code></pre><pre><code>$ terraform apply
</code></pre><p>Now, we are able to see on the console that the security list &amp; its ingress &amp; egress rules have been created</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646923985128/LsqbuPTEj.PNG" alt="SL public ingress.PNG" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646923994150/O4UA8_UEt.PNG" alt="SL public egress.PNG" /></p>
<h2 id="heading-creating-the-private-subnet">Creating the Private Subnet</h2>
<p>We are not done yet as we have not created the subnets for our VCN. Let's start by creating a private subnet</p>
<p>Let's create a file called 'private-subnet.tf' &amp; add the following code to it</p>
<pre><code><span class="hljs-comment"># Source from https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_subnet</span>

resource <span class="hljs-string">"oci_core_subnet"</span> <span class="hljs-string">"vcn-private-subnet"</span>{

  <span class="hljs-comment"># Required</span>
  compartment_id = <span class="hljs-string">"&lt;compartment-ocid&gt;"</span>
  vcn_id = module.vcn.vcn_id
  cidr_block = <span class="hljs-string">"10.0.1.0/24"</span>

  <span class="hljs-comment"># Optional</span>
  <span class="hljs-comment"># Caution: For the route table id, use module.vcn.nat_route_id.</span>
  <span class="hljs-comment"># Do not use module.vcn.nat_gateway_id, because it is the OCID for the gateway and not the route table.</span>
  route_table_id = module.vcn.nat_route_id
  security_list_ids = [oci_core_security_list.<span class="hljs-keyword">private</span>-security-<span class="hljs-keyword">list</span>.id]
  display_name = <span class="hljs-string">"private-subnet"</span>
}
</code></pre><p>Let's also add the following to the 'outputs.tf' file</p>
<pre><code>
<span class="hljs-meta"># Outputs for private subnet</span>

output <span class="hljs-string">"private-subnet-name"</span> {
  <span class="hljs-keyword">value</span> = oci_core_subnet.vcn-<span class="hljs-keyword">private</span>-subnet.display_name
}
output <span class="hljs-string">"private-subnet-OCID"</span> {
  <span class="hljs-keyword">value</span> = oci_core_subnet.vcn-<span class="hljs-keyword">private</span>-subnet.id
}
</code></pre><p>Now, let's run our scripts</p>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><pre><code>$ terraform plan
</code></pre><pre><code>$ terraform apply
</code></pre><p>And there you go. We've created our private subnet with a CIDR block of 10.0.1.0/24</p>
<h2 id="heading-creating-the-public-subnet">Creating the Public Subnet</h2>
<p>Let's do the above for the public subnet. To begin, let's create a file called 'public-subnet.tf' &amp; add the following code</p>
<pre><code><span class="hljs-comment"># Source from https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_subnet</span>

resource <span class="hljs-string">"oci_core_subnet"</span> <span class="hljs-string">"vcn-public-subnet"</span>{

  <span class="hljs-comment"># Required</span>
  compartment_id = <span class="hljs-string">"&lt;compartment-ocid&gt;"</span>
  vcn_id = module.vcn.vcn_id
  cidr_block = <span class="hljs-string">"10.0.0.0/24"</span>

  <span class="hljs-comment"># Optional</span>
  route_table_id = module.vcn.ig_route_id
  security_list_ids = [oci_core_security_list.<span class="hljs-keyword">public</span>-security-<span class="hljs-keyword">list</span>.id]
  display_name = <span class="hljs-string">"public-subnet"</span>
}
</code></pre><p>And, add the following code to the 'outputs.tf' file</p>
<pre><code>
# Outputs <span class="hljs-keyword">for</span> <span class="hljs-built_in">public</span> subnet

output "public-subnet-name" {
  <span class="hljs-keyword">value</span> = oci_core_subnet.vcn-<span class="hljs-built_in">public</span>-subnet.display_name
}
output "public-subnet-OCID" {
  <span class="hljs-keyword">value</span> = oci_core_subnet.vcn-<span class="hljs-built_in">public</span>-subnet.id
}
</code></pre><p>Now, let's run our scripts</p>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><pre><code>$ terraform plan
</code></pre><pre><code>$ terraform apply
</code></pre><p>And now, we have successfully created our public subnet with a CIDR block of 10.0.0.0/24</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646924706325/2KVPSg88f.PNG" alt="subnets.PNG" /></p>
<h1 id="heading-summary">Summary</h1>
<p>This sums Part 2 of this blog. In Part 2, we've created the following</p>
<ul>
<li>A compartment</li>
<li>A Ubuntu 20.04 compute instance</li>
<li>A Virtual Cloud Network (VCN)</li>
<li>Security List for Private Subnet with Ingress &amp; Egress Rules</li>
<li>Security List for Public Subnet with Ingress &amp; Egress Rules</li>
<li>A Private Subnet</li>
<li>A Public Subnet</li>
</ul>

<p>In Part 3, I will be covering how we can incorporate the above in a single Terraform script &amp; provision an infrastructure on OCI. Stay tuned.</p>
]]></content:encoded></item><item><title><![CDATA[Deploying Workloads on Oracle Cloud Infrastructure (OCI) via Terraform - PART 1]]></title><description><![CDATA[What is Terraform?
Terraform is an infrastructure as code (IAC)  tool that lets you define both cloud & on-prem resources in human-readable configuration files that you can version, reuse, and share. The concept of Terraform is to allow users to prov...]]></description><link>https://vicknesh.cloud/deploying-workloads-on-oracle-cloud-infrastructure-oci-via-terraform-part-1</link><guid isPermaLink="true">https://vicknesh.cloud/deploying-workloads-on-oracle-cloud-infrastructure-oci-via-terraform-part-1</guid><category><![CDATA[Terraform]]></category><category><![CDATA[infrastructure]]></category><category><![CDATA[code]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Oracle]]></category><dc:creator><![CDATA[Dr. J Vickneshwaran]]></dc:creator><pubDate>Mon, 07 Mar 2022 17:05:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1646672491483/2W1BiuFLy.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-what-is-terraform">What is Terraform?</h1>
<p>Terraform is an<strong> infrastructure as code (IAC) </strong> tool that lets you define both cloud &amp; on-prem resources in human-readable configuration files that you can version, reuse, and share. The concept of Terraform is to allow users to provision huge &amp; complex infrastructure &amp; workloads in an automated fashion by defining the parameters in a <strong>".tf" file,</strong> instead of manually provisioning them which takes alot of effort &amp; time.</p>
<p>Terraform creates &amp; manages resources on cloud platforms <strong>(such as OCI)</strong> &amp; other services through their application programming interfaces (APIs). Providers enable Terraform to work with virtually any platform or service with an accessible API.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646669347233/lHvBkVY5F.png" alt="intro-terraform-apis.png" /> Image credits: terraform.io</p>
<p>Terraform execution involves three stages:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646669375667/1L8wsRoL7.png" alt="image-79.png" /> Image credits: freecodecamp.org</p>
<ul>
<li><strong>Write -</strong> This is where you write a “.tf” file to define the resources that you're provisioning to a provider (Eg: AWS, Azure, OCI, GCP, etc.)</li>
<li><strong>Plan -</strong> Terraform will create an execution plan outlining the infrastructure that you want to create, update or destroy based on your environment &amp; the “.tf” file that you've defined</li>
<li><strong>Apply -</strong> This is when Terraform executes the plan based on the parameters defined in your “.tf” file</li>
</ul>


<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646669500940/EyOUpyIqH.png" alt="intro-terraform-workflow.png" />  Image credits: terraform.io</p>
<h1 id="heading-working-with-terraform-on-oci">Working with Terraform on OCI</h1>
<p>In this section, I'll be documenting the process of configuring Terraform &amp; the creation of resources on OCI.</p>
<h2 id="heading-setting-up-terraform">Setting Up Terraform</h2>
<h3 id="heading-terraform-installation">Terraform Installation</h3>
<p>Firstly, we need to install Terraform in our environment. I have a Linux (Ubuntu) Windows Subsystem for Linux (WSL) on my Windows 10 machine which allows me to run a Linux environment directly on Windows without needing a virtual machine or dual boot setup. To learn more on WSL, refer here: <a target="_blank" href="https://docs.microsoft.com/en-us/windows/wsl/about">WSL</a></p>
<p>For Ubuntu/Debian, do the following:</p>
<p><br /></p>
<pre><code>$ curl <span class="hljs-operator">-</span>fsSL https:<span class="hljs-comment">//apt.releases.hashicorp.com/gpg | sudo apt-key add -</span>

$ sudo apt<span class="hljs-operator">-</span>add<span class="hljs-operator">-</span>repository <span class="hljs-string">"deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"</span>

$ sudo apt<span class="hljs-operator">-</span>get update <span class="hljs-operator">&amp;</span><span class="hljs-operator">&amp;</span> sudo apt<span class="hljs-operator">-</span>get install terraform
</code></pre><p><br />
For CentOS/RHEL, do the following:</p>
<pre><code>$ sudo yum install <span class="hljs-operator">-</span>y yum<span class="hljs-operator">-</span>utils

$ sudo yum<span class="hljs-operator">-</span>config<span class="hljs-operator">-</span>manager <span class="hljs-operator">-</span><span class="hljs-operator">-</span>add<span class="hljs-operator">-</span>repo 

$ sudo yum <span class="hljs-operator">-</span>y install terraform
</code></pre><h4 id="heading-creating-rsa-keys">Creating RSA Keys</h4>
<p>Once Terraform installed, we need to generate RSA keys to allow API signing into the OCI tenant.</p>
<p>On your terminal, create an .oci directory in the root folder.</p>
<pre><code>$ <span class="hljs-keyword">mkdir</span> $HOME/.oci
</code></pre><p>Generate a 2048-bit private key in PEM format.</p>
<pre><code>$ openssl genrsa <span class="hljs-operator">-</span>out $HOME<span class="hljs-operator">/</span>.oci/<span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>rsa<span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>.pem <span class="hljs-number">2048</span>
</code></pre><p>Modify the permission of your PEM file (private key) so that only you can read &amp; write the file.</p>
<pre><code>$ chmod <span class="hljs-number">600</span> $HOME<span class="hljs-operator">/</span>.oci/<span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>rsa<span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>.pem
</code></pre><p>Generate a public key (also in PEM format).</p>
<pre><code>$ openssl rsa <span class="hljs-operator">-</span>pubout <span class="hljs-operator">-</span>in $HOME<span class="hljs-operator">/</span>.oci/<span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>rsa<span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>.pem <span class="hljs-operator">-</span>out $HOME<span class="hljs-operator">/</span>.oci/<span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>rsa<span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>_public.pem
</code></pre><p>View your public key &amp; copy it's contents. Include ‘BEGIN PUBLIC KEY’ &amp; ‘END PUBLIC KEY’.</p>
<pre><code>$ cat $HOME<span class="hljs-operator">/</span>.oci/<span class="hljs-operator">&lt;</span>your<span class="hljs-operator">-</span>rsa<span class="hljs-operator">-</span>key<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>_public.pem
</code></pre><pre><code><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>BEGIN PUBLIC KEY<span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>

xxxxxxxxxxxxxxxxxxxxxxxxxxx

xxxxxxxxxxxxxxxxxxxxxxxxxxx

xxxxxxxxxxxxxxxxxxxxxxxxxxx

xxxxxxxxxxxxxxxx

<span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>END PUBLIC KEY<span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>
</code></pre><p>Add the public key to your user account on the OCI portal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646670201542/ixYNf8HgG.PNG" alt="Profile.PNG" /></p>
<ul>
<li>Click your profile</li>
<li>Click <strong>API Keys</strong></li>
<li>Click <strong>Add Public Key</strong></li>
<li>Select <strong>Paste Public Keys</strong></li>
<li>Paste your public key into the field, include the lines with 'BEGIN PUBLIC KEY' &amp; 'END PUBLIC KEY'</li>
<li>Click <strong>Add</strong></li>
</ul>

<h3 id="heading-define-policies-on-oci">Define Policies on OCI</h3>
<p>You need to define policies to provide permissions for your user(s) &amp; group(s) to read &amp; manage resources in your tenancy.</p>
<ol>
<li>Navigate to <strong>Identity &amp; Security &gt; Users</strong>. Create your user (Eg: terraformuser)</li>
<li>Navigate to <strong>Identity &amp; Security &gt; Groups</strong>. Create your group (Eg: terraformgroup) &amp; add your user to the group</li>
<li>Navigate to <strong>Identity &amp; Security &gt; Policies</strong></li>
<li>Choose a Compartment if you have one or select the root compartment for now (We'll be creating a Compartment later as well, in Part 2)</li>
<li>Click <strong>Create Policy</strong> &amp; click <strong>Show manual editor</strong></li>
<li>Paste the following policy &amp; click <strong>Create</strong></li>
</ol>
<pre><code>allow group <span class="hljs-operator">&lt;</span>the<span class="hljs-operator">-</span>group<span class="hljs-operator">-</span>your<span class="hljs-operator">-</span>username<span class="hljs-operator">-</span>belongs<span class="hljs-operator">&gt;</span> to read all<span class="hljs-operator">-</span>resources in tenancy
</code></pre><h3 id="heading-gather-required-information">Gather Required Information</h3>
<p>We will need to collect the following information to authenticate our Terraform scripts. Collect them from here:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646671393176/q_IKE4jgw.PNG" alt="Profile1.PNG" /></p>
<ol>
<li><strong>Tenancy OCID:</strong> Below your profile, click Tenance: &amp; copy the OCID</li>
<li><strong>User OCID:</strong> Click on your profile &amp; copy the OCID</li>
<li><strong>Fingerprint:</strong> In your profile, click API Keys &amp; copy the fingerprint associated with your RSA public key. The format is xx:xx:xx:…..:xx</li>
<li><strong>Region:</strong> From the top navigation bar, locate your region &amp; find your region's  from <a target="_blank" href="https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm">Regions &amp; Availability Domains</a>. Eg: us-ashburn-1</li>
</ol>
<p>Also, collect the following information from your environment (Linux, in my case).</p>
<ol>
<li><strong>Private Key Path:</strong> Eg: $HOME/.oci/.pem</li>
</ol>
<h3 id="heading-creating-your-scripts">Creating Your Scripts</h3>
<p>Next, we need to create scripts (.tf files) to allow Terraform to authenticate &amp; fetch data from the OCI tenant.</p>
<h4 id="heading-add-api-key-based-authentication">Add API Key-Based Authentication</h4>
<p>In your $HOME directory (your root directory), create a directory called ‘tf-provider’ &amp; change to that directory.</p>
<pre><code>$ mkdir tf-provider

$ cd tf-provider
</code></pre><p>Create a file called ‘provider.tf’ using your preferred text editor (vi/vim/nano).
Add the following code into your file. Replace the field brackets with the information gathered earlier. Retain the quotations around the string values. Save the file.</p>
<pre><code>provider <span class="hljs-string">"oci"</span> {

tenancy_ocid = <span class="hljs-string">"&lt;tenancy-ocid&gt;"</span>

user_ocid = <span class="hljs-string">"&lt;user-ocid&gt;"</span>

private_key_path = <span class="hljs-string">"&lt;rsa-private-key-path&gt;"</span>

fingerprint = <span class="hljs-string">"&lt;fingerprint&gt;"</span>

region = <span class="hljs-string">"&lt;region-identifier&gt;"</span>

}
</code></pre><h4 id="heading-add-data-source">Add Data Source</h4>
<p>In this section, you create a .tf file to fetch a list of availability domains in your tenancy.</p>
<ol>
<li>In the tf-provider directory, create a file called 'availability-domains.tf'</li>
<li>Add the following code &amp; save.</li>
</ol>
<pre><code>data “oci_identity_availability_domains” “ads” {

compartment_id <span class="hljs-operator">=</span> “<span class="hljs-operator">&lt;</span>tenancy<span class="hljs-operator">-</span>ocid<span class="hljs-operator">&gt;</span>”

}
</code></pre><h3 id="heading-run-your-scripts">Run Your Scripts</h3>
<p>In this section, we run the Terraform script by the workflow, <strong>Initialize &gt; Plan &gt; Apply</strong></p>
<h4 id="heading-initialize">Initialize</h4>
<ol>
<li>Initialize a working directory in the tf-provider directory.</li>
</ol>
<pre><code>$ terraform <span class="hljs-keyword">init</span>
</code></pre><p>Example output:</p>
<pre><code>Initializing the backend...

Initializing provider plugins...

<span class="hljs-operator">-</span> Finding latest version of hashicorp<span class="hljs-operator">/</span>oci...

<span class="hljs-operator">-</span> Installing hashicorp<span class="hljs-operator">/</span>oci vx.x.x...

<span class="hljs-operator">-</span> Installed hashicorp<span class="hljs-operator">/</span>oci vx.x.x (signed by HashiCorp)

Terraform has been successfully initialized<span class="hljs-operator">!</span>
</code></pre><h4 id="heading-plan">Plan</h4>
<ol>
<li>Now, we create an execution plan to check whether the changes shown in the plan match our expectations, without changing the real resource.</li>
</ol>
<pre><code>$ terraform plan
</code></pre><p>Example output:</p>
<pre><code>Changes to Outputs:

  <span class="hljs-operator">+</span> all<span class="hljs-operator">-</span>availability<span class="hljs-operator">-</span>domains<span class="hljs-operator">-</span>in<span class="hljs-operator">-</span>your<span class="hljs-operator">-</span>tenancy <span class="hljs-operator">=</span> [

      <span class="hljs-operator">+</span> {

          <span class="hljs-operator">+</span> compartment_id <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.tenancy.oc1..xxx"</span>

          <span class="hljs-operator">+</span> id             <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.availabilitydomain.xxx"</span>

          <span class="hljs-operator">+</span> name           <span class="hljs-operator">=</span> <span class="hljs-string">"QnsC:US-ASHBURN-AD-1"</span>

        },

      <span class="hljs-operator">+</span> {

          <span class="hljs-operator">+</span> compartment_id <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.tenancy.oc1..xxx"</span>

          <span class="hljs-operator">+</span> id             <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.availabilitydomain.xxx"</span>

          <span class="hljs-operator">+</span> name           <span class="hljs-operator">=</span> <span class="hljs-string">"QnsC:US-ASHBURN-AD-2"</span>

        },

      <span class="hljs-operator">+</span> {

          <span class="hljs-operator">+</span> compartment_id <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.tenancy.oc1..xxx"</span>

          <span class="hljs-operator">+</span> id             <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.availabilitydomain.xxx"</span>

          <span class="hljs-operator">+</span> name           <span class="hljs-operator">=</span> <span class="hljs-string">"QnsC:US-ASHBURN-AD-3"</span>

        },

    ]

You can apply <span class="hljs-built_in">this</span> plan to save these <span class="hljs-keyword">new</span> output values to the Terraform state, without changing any real infrastructure.
</code></pre><h4 id="heading-apply">Apply</h4>
<p>Now, we run the Terraform scripts. Enter ‘yes’ when prompted.</p>
<pre><code>$ terraform apply
</code></pre><p>Example output:</p>
<pre><code>Apply complete<span class="hljs-operator">!</span> Resources: <span class="hljs-number">0</span> added, <span class="hljs-number">0</span> changed, <span class="hljs-number">0</span> destroyed.

Outputs:

all<span class="hljs-operator">-</span>availability<span class="hljs-operator">-</span>domains<span class="hljs-operator">-</span>in<span class="hljs-operator">-</span>your<span class="hljs-operator">-</span>tenancy <span class="hljs-operator">=</span> tolist([

  {

    <span class="hljs-string">"compartment_id"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.tenancy.xxx"</span>

    <span class="hljs-string">"id"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.availabilitydomain.xxx"</span>

    <span class="hljs-string">"name"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"QnsC:US-ASHBURN-AD-1"</span>

  },

  {

    <span class="hljs-string">"compartment_id"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.tenancy.xxx"</span>

    <span class="hljs-string">"id"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.availabilitydomain.xxx"</span>

    <span class="hljs-string">"name"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"QnsC:US-ASHBURN-AD-2"</span>

  },

  {

    <span class="hljs-string">"compartment_id"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.tenancy.xxx"</span>

    <span class="hljs-string">"id"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"ocid1.availabilitydomain.xxx"</span>

    <span class="hljs-string">"name"</span> <span class="hljs-operator">=</span> <span class="hljs-string">"QnsC:US-ASHBURN-AD-3"</span>

  },

])
</code></pre><p>We have successfully authenticated our OCI tenant with our Terraform provider scripts.</p>
<h1 id="heading-summary">Summary</h1>
<p>To summarize Part 1, we have done the following:</p>
<ul>
<li>Installed Terraform</li>
<li>Created .tf scripts</li>
<li>Executed the workflows, Initialize &gt; Plan &gt; Apply</li>
<li>Authenticated our OCI tenant with the Terraform provider scripts</li>
</ul>

<p>In <a target="_blank" href="https://vicknesh.cloud/deploying-workloads-on-oracle-compute-infrastructure-oci-via-terraform-part-2">Part 2</a>, I will document steps to provision resources (compartments, compute instances, etc.) in our OCI tenant via Terraform scripts.</p>
<p>I hope this has been beneficial to you. I'll see you in <a target="_blank" href="https://vicknesh.cloud/deploying-workloads-on-oracle-compute-infrastructure-oci-via-terraform-part-2">Part 2</a>. Stay tuned &amp; have a nice day.</p>
]]></content:encoded></item><item><title><![CDATA[Securing Your Database with Oracle Data Safe]]></title><description><![CDATA[Introduction
Data is an organization's most critical asset which if not protected, becomes a huge liability. Databases containing sensitive data, such as personally identifiable information (PII), personal financial information, and personal healthca...]]></description><link>https://vicknesh.cloud/securing-your-database-with-oracle-data-safe</link><guid isPermaLink="true">https://vicknesh.cloud/securing-your-database-with-oracle-data-safe</guid><category><![CDATA[Oracle]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Databases]]></category><category><![CDATA[Security]]></category><category><![CDATA[data]]></category><dc:creator><![CDATA[Dr. J Vickneshwaran]]></dc:creator><pubDate>Sat, 26 Feb 2022 15:55:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1645884336636/wPoi7n3Rq.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>Data is an organization's most critical asset which if not protected, becomes a huge liability. Databases containing sensitive data, such as personally identifiable information (PII), personal financial information, and personal healthcare information, are vulnerable to external &amp; even internal threats looking to steal data for financial, strategic, or personal gain, or simply to cause business disruption.</p>
<p>In terms of having ownership of data, organizations are required to be compliant in Data Protection Laws. The following are a few laws you may be familiar with.</p>
<ul>
<li>General Data Protection Regulation (GDPR)</li>
<li>Payment Card Industry's Data Security Standard (PCI DSS)</li>
<li>Sarbanes Oxley (SOX)</li>
<li>Health Insurance Portability &amp; Accountability Act (HIPAA)</li>
</ul>

<p>In addition to the above, there are also other global &amp; country-specific laws which addresses data protection.</p>
<p>Attackers are constantly looking at ways of gaining illegitimate access into enterprise systems by exploiting vulnerabilities in user credentials, applications &amp; configurations of databases.</p>
<p>How do you manage against a legion of attackers who have all the infrastructure, the tools, &amp; the time, when you don’t? Oracle provides top-in-class security for the computing infrastructure of its cloud databases, including encryption by default, separation of duty, and proactive security patching. But organizations need to further secure their databases by understanding their own data, their own users &amp; their configurations.</p>
<h3 id="heading-what-is-oracle-data-safe">What is Oracle Data Safe?</h3>
<p><img src="https://www.4iapps.com/wp-content/uploads/2020/09/Oracle-Data-Safe.png" alt="Reinforce your Oracle Database Security with Oracle Data Safe" />
Image credits: <a target="_blank" href="https://www.4iapps.com/reinforce-your-oracle-database-security-with-oracle-data-safe/">4iapps.com</a></p>
<p>Oracle Data Safe offers a protection mechanism for Oracle databases which helps organizations to:</p>
<ul>
<li>understand the sensitivity of data</li>
<li>evaluate risks to data</li>
<li>mask sensitive data</li>
<li>implement &amp; monitor security controls</li>
<li>assess user security</li>
<li>monitor user activity</li>
<li>address data security compliance requirements</li>
</ul>

<h4 id="heading-oracle-data-safe-features">Oracle Data Safe Features</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645882018511/AfurJHHjQ.png" alt="Screenshot 2022-02-26 at 9.25.44 PM.png" /></p>
<ul>
<li><strong>Security Assessment</strong> allows organizations to assess the security of their database configurations. It analyzes database configurations, user accounts, and security controls, and then reports the findings with recommendations for remediation activities that follow best practices to reduce or mitigate risk.</li>
<li><strong>User Assessment</strong> looks into the security assessments of your database users &amp; identify high risk users. It reviews information about your users in the data dictionary on your target databases &amp; calculates a risk score for each user. For an instance, it examines the user types, how users are authenticated, the password policies assigned to each user &amp; how long it has been since each user has changed their password. It also provides a direct link to audit records related to each user. With this information, organizations can then deploy appropriate security controls and policies.</li>
<li><strong>Data Discovery</strong> helps organizations to identify sensitive data in its databases. Data Discovery can be instructed to search for a particular kind of sensitive data &amp; it inspects the actual data in the database &amp; its data dictionary &amp; then provisions a list of sensitive columns. By default, Data Discovery can search for a wide variety of sensitive data pertaining to identification, biographic, IT, financial, healthcare, employment, and academic information.</li>
<li><strong>Data Masking</strong> is a mechanism for you to mask sensitive data so that the data is safe for non-production purposes. For an instance, organizations are often required to create copies of their production data to support development and test activities. Simply copying the production data exposes sensitive data to new users. To avoid a security risk, you can use Data Masking to replace the sensitive data with realistic, but fictitious data.</li>
<li><strong>Activity Auditing</strong> allows security admins to audit user activity on databases which also allows them to monitor database usage.</li>
<li><strong>Alerts</strong> keep you informed of unusual database activities as they happen.
</li>
</ul>

<h4 id="heading-what-databases-can-i-protect-with-oracle-data-safe">What Databases can I Protect with Oracle Data Safe?</h4>
<p>Oracle Data Safe allows you to protect a variety of Oracle databases which includes Autonomous Databases &amp; DB systems (Bare Metal, Virtual Machine, and Exadata), on-premises Oracle Databases, and Oracle Databases on compute instances in both Oracle Cloud Infrastructure (OCI) and non-Oracle cloud environments.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645884722266/2hkYs-i7e.png" alt="Screenshot 2022-02-26 at 10.11.38 PM.png" />
Image credits: <a target="_blank" href="https://docs.oracle.com/en/cloud/paas/data-safe/admds/oracle-data-safe-architecture.html#GUID-26EA04FF-4CD6-49A8-9B01-14A7222D081F">Oracle Data Safe Architecture</a></p>
<h3 id="heading-oracle-data-safe-in-action">Oracle Data Safe in Action</h3>
<iframe width="560" height="315" src="https://www.youtube.com/embed/jzY7aKw0Fms"></iframe>

<p>I hope this was insightful. Thank you for reading &amp; I shall share more write ups in my next blog post.</p>
]]></content:encoded></item><item><title><![CDATA[Data Ownership]]></title><description><![CDATA[Data ownership refers to who has legal ownership of the data. In the cloud computing perspective, roles are assumed to handle data ownership responsibilities.
Data Owner
Refers to the that has collected or created the data. From an organization persp...]]></description><link>https://vicknesh.cloud/data-ownership</link><guid isPermaLink="true">https://vicknesh.cloud/data-ownership</guid><category><![CDATA[data]]></category><category><![CDATA[Security]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Cloud Computing]]></category><dc:creator><![CDATA[Dr. J Vickneshwaran]]></dc:creator><pubDate>Fri, 25 Feb 2022 15:32:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/BfrQnKBulYQ/upload/v1645802575734/X41EE2uII.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Data ownership refers to who has legal ownership of the data. In the cloud computing perspective, roles are assumed to handle data ownership responsibilities.</p>
<p><strong>Data Owner</strong></p>
<p>Refers to the that has collected or created the data. From an organization perspective, data ownership is assigned to specific individuals who have rights &amp; responsibilities of the data. This may include Department Heads or Business Unit Managers whom have collected or created a dataset. From a cloud computing perspective, the customer is the owner of the data</p>
<p><strong>Data Custodian</strong></p>
<p>Refers to a person or entity that is given the mandate to maintain &amp; administer the data. 
The data custodian is also responsible of administering adequate security controls &amp; processes as directed by the data owner. An example of a data custodian is a database administrator.</p>
<p><strong>Data Processor</strong></p>
<p>Refers to a person or organization who manipulates, stores or moves data on behalf of the data owner. Data processing may include copying, printing, destroying &amp; utilizing. From an international law perspective, the cloud provider is a data processor.</p>
]]></content:encoded></item></channel></rss>