OCI Command Line Interface (CLI) Basics

The OCI Command Line Interface (CLI), is a Python-based command line interpreter, that lets you interact with the Oracle Cloud Infrastructure.

Installing the CLI on your laptop can be done with the installer script pulled from Github, or you can install it manually, following the steps in the documentation.

Once installed, you need to configure the tool to connect to your OCI account. for this, you need to gather the following items and place them in the tool’s configuration file:

  • Region
  • Tenancy OCID
  • User OCID
  • User fingerprint
  • The path to the private RSA key file (PEM format) which matches the fingerprint above

If your user does not yet have a fingerprint, you will need to go through the process of creating a key pair and fingerprint and upload the public key to your user account. The instructions can be found in the OCI documentation.

The configuration file gets created in ~/.oci/config with the setup config command, which will prompt you for the above values.

$ oci setup config


Once everything is configured correctly you can run a few commands to try out the client. The basic syntax is:

$ oci    

Some of the available services are:

  • Core (Networking, Compute, Block Volume, etc.)
  • Database
  • IAM
  • Load Balancing
  • Object Storage

For a full list of services, consult the official documentation, as it may change.

The types are subsets of the services. So for the core service compute, you have image, instance, shape, etc.

Following the type is the action: Create, delete, list, etc.

Many actions will require further options like compartment ID or a specific resource ID. If you forget to include an option, the tool’s error message will tell you which one.

To list all the compartments in your tenancy use:

$ oci iam compartment list

The result will be a JSON document with the compartments and their details. You could pipe the output to grep in order to just show the names for example.

$ oci iam compartment list | grep name

It may also be advisable to use the –all option if the resultset is large:

$ oci iam compartment list --all | grep name

To list the available shapes for a compartment use (compartment OCID shortened for the example):

$ oci compute image list --compartment-id ocid1.compartment.oc1..xyz | grep display-name

Options may optionally be enclosed in quotes.


Help and Hints

If you are unsure about the commands, the OCI CLI is pretty good about providing help and hints. By simply typing in parts of a command, the tool will try to let you know what options you have and what’s missing.

So if you simply type oci, the help will pop up, and a list of commands that can follow the command oci.

The if you type oci <command>, it will further assist you with hints:

$ oci iam

A complete list of the available commands is provided in the OCI CLI Command Reference.


Some, more complex operations, require the input to be provided in JSON format. To find out the exact JSON format you need, the OCI CLI provides the –generate-param-json-input option. This will generate an example that you can use as a basis. Save this example and edit copies of it to more easily define the options you need for your desired operation.


Let’s add a rule to an existing security list. So let’s find out which options we need to update a security list by asking the OCI CLI:

$ oci network security-list update
Usage: oci network security-list update [OPTIONS]

Error: Missing option(s) --security-list-id.

The error tells us we need the OCID of the security list. So let’s get a list of the security lists:

$ oci network security-list list
Usage: oci network security-list list [OPTIONS]

Error: Missing option(s) --compartment-id, --vcn-id.

So to get a list of the security lists, we need to tell OCI the compartment and VCN OCIDs.


$ oci iam compartment list
	"data": [{
		"compartment-id": "ocid1.tenancy.oc1..xyz",
		"defined-tags": {},
		"description": "Sample Compartment",
		"freeform-tags": {},
		"id": "ocid1.compartment.oc1..xyz",
		"inactive-status": null,
		"lifecycle-state": "ACTIVE",
		"name": "SAMPLE"


From the JSON output copy the OCID for the compartment you want, then find the compartment’s VCNs.

$ oci network vcn list --compartment-id ocid1.compartment.oc1..xyz
	"data": [{
		"cidr-block": "",
		"compartment-id": "ocid1.compartment.oc1..xyz",
		"default-dhcp-options-id": "ocid1.dhcpoptions.oc1.eu-frankfurt-1.xyz",
		"default-route-table-id": "ocid1.routetable.oc1.eu-frankfurt-1.xyz",
		"default-security-list-id": "ocid1.securitylist.oc1.eu-frankfurt-1.xyz",
		"defined-tags": {},
		"display-name": "VCN-Sample",
		"dns-label": "vcnsamp",
		"freeform-tags": {},
		"id": "ocid1.vcn.oc1.eu-frankfurt-1.xyz",
		"lifecycle-state": "AVAILABLE",
		"time-created": "2018-03-20T17:25:39.080000+00:00",
		"vcn-domain-name": "vcneuf.oraclevcn.com"

The “id” element has the VCN’s OCID. Let’s copy that so we can list the security lists for the VCN:

$ oci network security-list list \
   --vcn-id ocid1.vcn.oc1.eu-frankfurt-1.xyz \
   --compartment-id ocid1.compartment.oc1..xyz
	"data": [{
		"compartment-id": "ocid1.compartment.oc1..xyz",
		"defined-tags": {},
		"display-name": "Sample Seclist",
		"egress-security-rules": [{
			"destination": "",
			"icmp-options": null,
			"is-stateless": null,
			"protocol": "6",
			"tcp-options": {
				"destination-port-range": {
					"max": 80,
					"min": 80
				"source-port-range": null
			"udp-options": null
               "id": "ocid1.securitylist.oc1.eu-frankfurt-1.xyz"

Here we see our security list named Sample Seclist. Now we can copy the “id” from the JSON. This is what we need to do add a rule to the list.

Now let’s generate the sample JSON for the security list update:

$ oci network security-list update --generate-param-json-input ingress-security-rules

Copy the resulting JSON to a text editor and make the necessary changes.

As the example is fairly large, you may remove unnecessary items. Just make sure to have valid JSON at the end. You can easily validate your JSON at jsoncompare.com. This site also lets you minimize your JSON so you can easily include it on the command line.

Here is an example that updates the ingress rule of my security list to allow port 443 in.

	"isStateless": true,
	"protocol": "6",
	"source": "",
	"tcpOptions": {
		"destinationPortRange": {
			"max": 443,
			"min": 443

Now minify this and append it to the update command on the command line:

$ oci network security-list update \
--security-list-id ocid1.securitylist.oc1.eu-frankfurt-1.xyz \
--ingress-security-rules '[{"isStateless":true,"protocol":"6","source":"","tcpOptions":{"destinationPortRange":{"max":443,"min":443}}}]'



While the OCI CLI may seem a bit daunting at first, once you get a hang of it, it’s not so bad. It can be used to quickly provision or change resources, without having to navigate through the web console.

An alternative to the CLI is the REST API, which allows you pretty much to do the same things using REST commands. More on that a little later.