OCI #6 – Launching Compute instance using CLI

This recipe shows how to provision a new compute instance using Oracle Cloud Infrastructure CLI.

Before you start, you must install and configure Oracle Cloud Infrastructure CLI. See: CLI Setup recipe, if needed.

Target Infrastructure

In this short tutorial we are going to provision a new compute instance on Oracle Cloud Infrastructure. The instance will be a lightweight Linux-based virtual machine with just 1 OCPU (== 2 vCPUs) and 14GB memory. We will place the instance on a public subnet and assign an ephemeral public IP address. In this way, the virtual machine will be accessible from the Internet. To demonstrate it, we will enable web server, host a static page and open port 80. All steps will be performed with Oracle Cloud Infrastructure CLI.



Oracle Cloud Infrastructure resources are grouped together in Compartments. Every OCI CLI command must know the compartment in which it has to perform operations. Most often you will define a default compartment for CLI. You do it in ~/.oci/oci_cli_rc file. See: CLI Setup recipe, if needed.

This is the quickest way to display the name of the default Compartment that CLI is configured to work with:

oci iam compartment get --output table --query "data.{CompartmentName:\"name\"}"
| CompartmentName |
| Sandbox         |


Cloud-based compute instances that are spread across bare metal servers and numerous virtual machines require interconnectivity. Although cloud-computing networking, as seen by the user, is rather simplified and flattened especially when compared to the traditional on-premise topologies, you still need to design and roll out some networking configuration. In this way, you can decide which instances are accessible from the Internet while the others aren’t. You can group together the related instances in subnets and define security rules that allow the access on the selected ports.

Virtual Cloud Network

Virtual Cloud Network (VCN) is a software-defined network that provides a contiguous IPv4 address block, firewall and routing rules. VCN is subdivided into multiple, non-overlapping VCN subnets.

This is how you create a VCN using OCI CLI:

$ oci network vcn create --cidr-block --display-name demovcn --dns-label demovcn
  "data": {
    "cidr-block": "",
    "compartment-id": "ocid1.compartment.oc1..aaaaaaaavpjjlshvlm7nh6gxuhbsdzdbvhuiihenvyaqz6o4hrycscjtq75q",
    "default-dhcp-options-id": "ocid1.dhcpoptions.oc1.eu-frankfurt-1.aaaaaaaaklavzudx7vkb2pi42sx72zlws4mcsmgalbojbd2pqq7hvjhb2zfa",
    "default-route-table-id": "ocid1.routetable.oc1.eu-frankfurt-1.aaaaaaaamscrcftelrikngjckzje5fnqqoxbw7opmtdo55banhayrlajv75q",
    "default-security-list-id": "ocid1.securitylist.oc1.eu-frankfurt-1.aaaaaaaalq7jklywlm4qywy2smblsdcxqbadtk5asqdvkszqigs3uqnxhlna",
    "defined-tags": {},
    "display-name": "demovcn",
    "dns-label": "demovcn",
    "freeform-tags": {},
    "id": "ocid1.vcn.oc1.eu-frankfurt-1.aaaaaaaaazy45d63g6r7l7uvytioflhceuq6xu2fdjg6d6bptrhmckns6rhq",
    "lifecycle-state": "AVAILABLE",
    "time-created": "2018-10-22T21:51:26.228000+00:00",
    "vcn-domain-name": "demovcn.oraclevcn.com"
  "etag": "339cc316"
$ oci network vcn list --output table --query "data [*].{Name:\"display-name\", CIDR:\"cidr-block\", Domain:\"vcn-domain-name\"}"
| CIDR            | Domain                | Name    |
| | demovcn.oraclevcn.com | demovcn |

Internet Gateway

The traffic between instances in your VCN and the Internet goes through an Internet Gateway (IGW). An IGW exists in the context of your VCN. It can be disabled to immediately isolate your cloud resources from the Internet and then re-enabled when the problem is solved.

This is how you create a VCN Internet Gateway using OCI CLI. The first command queries for an OCID of the previously generated VCN and saves the result in a variable. The variable is used in the command that creates an IGW:

$ vcnOCID=`oci network vcn list --query "data [?\"display-name\"=='demovcn'].{OCID:\"id\"}" | grep OCID | awk -F'[\"|\"]' '{print $4}'`
$ echo $vcnOCID
$ oci network internet-gateway create --vcn-id $vcnOCID --display-name demoigw --is-enabled true > /dev/null



Compute instances must be launched within subnets. Before we create a subnet, we are going to prepare a Route Table and a Security List. Route Table will direct the outgoing traffic through the Internet Gateway, we’ve just created. Security List will contain Security Rules that define what kind of ingress and egress traffic is allowed for the subnet. You can think of Security Rules as an additional layer of a virtual firewall.

This is how you create a simple Route Table that directs the outgoing traffic to the Internet Gateway:

$ igwOCID=`oci network internet-gateway list --vcn-id $vcnOCID --query "data [?\"display-name\"=='demoigw'].{OCID:\"id\"}" | grep OCID | awk -F'[\"|\"]' '{print $4}'`
$ echo $igwOCID
$ oci network route-table create --vcn-id $vcnOCID --display-name publicrt --route-rules "[{\"cidrBlock\":\"\", \"networkEntityId\":\"$igwOCID\"}]" > /dev/null


This is how you create a Security List that allows the inbound traffic on ports 22 and 80 as well as any outbound traffic:

$ egress='[{"destination": "", "protocol": "all" }]'
$ ingress='[{"source": "", "protocol": "6", "tcpOptions": { "destinationPortRange": {"max": 22, "min": 22} } }, {"source": "", "protocol": "6", "tcpOptions": { "destinationPortRange": {"max": 80, "min": 80} } }]'
$ oci network security-list create --vcn-id $vcnOCID --display-name publicsl --egress-security-rules "$egress" --ingress-security-rules "$ingress" > /dev/null



This is how you create a subnet:

$ rtOCID=`oci network route-table list --vcn-id $vcnOCID --query "data [?\"display-name\"=='publicrt'].{OCID:\"id\"}" | grep OCID | awk -F'[\"|\"]' '{print $4}'`
$ echo $rtOCID
$ slOCID=`oci network security-list list --vcn-id $vcnOCID --query "data [?\"display-name\"=='publicsl'].{OCID:\"id\"}" | grep OCID | awk -F'[\"|\"]' '{print $4}'`
$ echo $slOCID
$ oci network subnet create --vcn-id $vcnOCID --display-name demosubnet --dns-label subnet  --cidr-block --prohibit-public-ip-on-vnic false --availability-domain "feDV:EU-FRANKFURT-1-AD-1" --route-table-id "$rtOCID" --security-list-ids "[\"$slOCID\"]" > /dev/null


Compute instance

There are two families of compute instances on Oracle Cloud Infrastructure:

  • Bare Metal Hosts
  • Virtual Machines

Bare Metal Hosts are powered by dedicated, single-tenant hardware with no hypervisor on board. They are very powerful and can provide a good foundation for large-scale enterprise computing. At the time of writing, the smallest bare metal server uses 36 OCPUs (== 72 vCPUs). Well… you do not always need such a mighty server, don’t you? Virtual machines, on the other hand, are powered by multi-tenant, hypervisor-managed servers. As a result, you can provision a lightweight virtual machine starting from just 1 OCPU (== 2 vCPUs). A Shape defines the profile of hardware resources of a compute instance. For example VM.Standard2.1 Shape delivers 1 OCPU and 15GB Memory.

An Image is a template that specifies the instance’s preinstalled software including the Operating System. It is used to initiate the boot volume that gets associated with the instance during provisioning. Oracle Cloud Infrastructure provides default images with various Operating Systems. You can create your own custom images, usually on top of the existing images. Let’s fetch the OCID of the newest CentOS 7 image and save it to a variable:

$ imageOCID=`oci compute image list --operating-system "CentOS" --operating-system-version 7 --sort-by TIMECREATED --query "data [0].{DisplayName:\"display-name\", OCID:\"id\"}" | grep OCID | awk -F'[\"|\"]' '{print $4}'`
$ echo $imageOCID

An instance has to exist within a subnet. Let’s fetch the OCID of the subnet, we’ve created, and save the OCID to a variable:

$ subnetOCID=`oci network subnet list --vcn-id $vcnOCID --query "data [?\"display-name\"=='demosubnet'].{OCID:\"id\"}" | grep OCID | awk -F'[\"|\"]' '{print $4}'`
$ echo $subnetOCID

A Linux-based compute instance requires an SSH public key to enable remote access. Please prepare a key pair before proceeding. See: SSH Keypair recipe, if needed. This guide assumes you store the public key in ~/.ssh/oci_id_rsa.pub

Oracle Cloud Infrastructure compute instances can use Cloud-Init user data to perform the initial configuration that takes place immediately after provisioning in an automated way. Let’s prepare a cloud-config file ~/cloud-init/michalsvm.cloud-config:

Now we are ready to launch the very first instance. This is how you do it using Oracle Cloud Infrastructure CLI:

oci compute instance launch --display-name michalsvm --availability-domain "feDV:EU-FRANKFURT-1-AD-1" --subnet-id "$subnetOCID" --private-ip --image-id "$imageOCID" --shape VM.Standard2.1 --ssh-authorized-keys-file ~/.ssh/oci_id_rsa.pub --user-data-file ~/cloud-init/michalsvm.cloud-config --wait-for-state RUNNING > /dev/null

It should take up to 1 or 2 minutes to complete the provisioning process. A mentioned before that our instance will get an ephemeral public IP address from the OCI public IPv4 address pool. Let’s find out the address our instance was given:

$ vmOCID=`oci compute instance list --display-name michalsvm --lifecycle-state RUNNING | grep \"id\" | awk -F'[\"|\"]' '{print $4}'`
$ echo $vmOCID
$ oci compute instance list-vnics --instance-id "$vmOCID" | grep public-ip | awk -F'[\"|\"]' '{print $4}'

You will still need to wait some additional seconds, until the boot process completes and SSH daemon starts accepting connections. This is how you connect to the machine:

$ ssh -i .ssh/oci_id_rsa opc@
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is SHA256:tKs9JT5ubEVtBuKdKqux5ckktcLPRBrwWvWsjUaec4Q.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '' (ECDSA) to the list of known hosts.


Finally let’s check if we can access the web server:


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s