Python for Oracle Cloud Infrastructure (OCI)
I use Python with OCI because I want infra work to feel repeatable instead of “console clicking until it works.” The OCI console and CLI are fine, but Python is where I can package the boring parts: inventory, guardrails, and a clean summary.
My mental loop is simple:
- ASK: what is true right now?
- PLAN: what exactly am I about to touch?
- APPLY: do the smallest change possible
- VERIFY: confirm reality changed
- RECORD: print results so I have receipts
If a script skips “plan” or “verify,” it is basically a dare.
Setup (the normal way)
Section titled “Setup (the normal way)”Locally, I just reuse the same config the OCI CLI uses (~/.oci/config). That keeps things clean: no custom auth hacks, no mystery environment variables.
import ocicfg = oci.config.from_file()When code runs inside OCI (on a compute instance), I typically switch to instance principals so I am not shipping user keys around:
import ocisigner = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()compute = oci.core.ComputeClient({}, signer=signer)One small script I actually keep around
Section titled “One small script I actually keep around”This is the kind of thing I mean by “Python controls infra.” It is not a framework. It is a tiny tool that:
- lists instances in a compartment
- filters by a tag
- prints the plan
- optionally stops them (with a hard limit)
import oci
cfg = oci.config.from_file()cpt = "ocid1.compartment.oc1..REDACTED"
compute = oci.core.ComputeClient(cfg)inst = oci.pagination.list_call_get_all_results( compute.list_instances, compartment_id=cpt).data
targets = [i for i in inst if (i.freeform_tags or {}).get("env") == "staging"][:5]print("PLAN:", [t.display_name for t in targets])
DRY = Trueif not DRY: for t in targets: compute.instance_action(t.id, "STOP") print("STOP requested:", t.display_name)That is the whole vibe: selection is explicit, limit is enforced, dry-run is the default.
The guardrails that matter (more than fancy code)
Section titled “The guardrails that matter (more than fancy code)”- Dry-run first: print what you will touch before you touch it.
- Hard limits: scripts should have a brake pedal.
- Target by tags/compartments: never “whatever matches this name.”
- Verify: do not assume an API call means the system is now correct.
- Summaries over spam: I want “5 succeeded, 1 failed” with names, not 400 lines.
Why this works for me
Section titled “Why this works for me”OCI is not the hard part. The hard part is doing the same actions repeatedly without slowly inventing new mistakes. Python lets me take the steps I already trust and make them consistent: ask, plan, apply, verify, and keep receipts.