Agent Skills: Oracle Cloud CI Integration

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/oraclecloud-ci-integration

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/oraclecloud-pack/skills/oraclecloud-ci-integration

Skill Files

Browse the full folder contents for oraclecloud-ci-integration.

Download Skill

Loading file tree…

plugins/saas-packs/oraclecloud-pack/skills/oraclecloud-ci-integration/SKILL.md

Skill Metadata

Name
oraclecloud-ci-integration
Description
|

Oracle Cloud CI Integration

Overview

Set up GitHub Actions workflows that authenticate to OCI, run Terraform plans, and execute tests against OCI services. The OCI Terraform provider has known bugs — notably ResourcePrincipal forcing the wrong region (#1761) — that require specific workarounds. This skill provides battle-tested CI patterns that avoid those pitfalls.

Purpose: Get a working CI pipeline that authenticates to OCI, runs Terraform safely, and tests OCI-dependent code without flaky failures.

Prerequisites

  • OCI tenancy with an API signing key configured in ~/.oci/config
  • Terraform >= 1.5 and the OCI provider (oracle/oci)
  • GitHub repository with Actions enabled
  • GitHub Secrets configured: OCI_USER_OCID, OCI_FINGERPRINT, OCI_TENANCY_OCID, OCI_REGION, OCI_PRIVATE_KEY (PEM contents, base64-encoded)
  • Python 3.8+ with pip install oci for SDK-based tests

Instructions

Step 1: Configure GitHub Secrets for OCI Auth

OCI API key authentication requires five values. Store them as GitHub repository secrets:

# Encode your private key for safe storage in GitHub Secrets
base64 -w 0 ~/.oci/oci_api_key.pem
# Copy output → GitHub Settings > Secrets > OCI_PRIVATE_KEY

The remaining secrets come from your ~/.oci/config file: user, fingerprint, tenancy, and region.

Step 2: GitHub Actions Workflow with Terraform

Create .github/workflows/oci-terraform.yml:

name: OCI Terraform
on:
  push:
    branches: [main]
  pull_request:

env:
  TF_VAR_tenancy_ocid: ${{ secrets.OCI_TENANCY_OCID }}
  TF_VAR_user_ocid: ${{ secrets.OCI_USER_OCID }}
  TF_VAR_fingerprint: ${{ secrets.OCI_FINGERPRINT }}
  TF_VAR_region: ${{ secrets.OCI_REGION }}

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Write OCI private key
        run: |
          echo "${{ secrets.OCI_PRIVATE_KEY }}" | base64 -d > /tmp/oci_key.pem
          chmod 600 /tmp/oci_key.pem

      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: "1.7.0"

      - name: Terraform Init
        run: terraform init

      - name: Terraform Plan
        run: terraform plan -out=tfplan
        env:
          TF_VAR_private_key_path: /tmp/oci_key.pem

Step 3: Terraform Provider Configuration

Configure the OCI provider with explicit region to avoid the ResourcePrincipal region bug (#1761):

terraform {
  required_providers {
    oci = {
      source  = "oracle/oci"
      version = ">= 5.0.0"
    }
  }
}

provider "oci" {
  tenancy_ocid = var.tenancy_ocid
  user_ocid    = var.user_ocid
  fingerprint  = var.fingerprint
  private_key_path = var.private_key_path
  # CRITICAL: Always set region explicitly.
  # ResourcePrincipal auth can force the wrong region (#1761).
  region       = var.region
}

variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" { default = "us-ashburn-1" }

Step 4: OCI CLI Commands in CI

For non-Terraform CI tasks, use the OCI CLI directly:

      - name: Install OCI CLI
        run: |
          pip install oci-cli
          mkdir -p ~/.oci
          echo "${{ secrets.OCI_PRIVATE_KEY }}" | base64 -d > ~/.oci/oci_api_key.pem
          chmod 600 ~/.oci/oci_api_key.pem
          cat > ~/.oci/config << EOF
          [DEFAULT]
          user=${{ secrets.OCI_USER_OCID }}
          fingerprint=${{ secrets.OCI_FINGERPRINT }}
          tenancy=${{ secrets.OCI_TENANCY_OCID }}
          region=${{ secrets.OCI_REGION }}
          key_file=~/.oci/oci_api_key.pem
          EOF

      - name: List compute instances
        run: oci compute instance list --compartment-id ${{ secrets.OCI_TENANCY_OCID }}

Step 5: Python SDK Tests with Mocks

Write testable OCI code by mocking the SDK clients:

import oci
from unittest.mock import MagicMock, patch

def list_instances(compartment_id: str) -> list:
    """List all compute instances in a compartment."""
    config = oci.config.from_file("~/.oci/config")
    client = oci.core.ComputeClient(config)
    response = client.list_instances(compartment_id=compartment_id)
    return response.data

@patch("oci.core.ComputeClient")
@patch("oci.config.from_file")
def test_list_instances(mock_config, mock_client_cls):
    mock_client = MagicMock()
    mock_client_cls.return_value = mock_client
    mock_client.list_instances.return_value.data = [
        MagicMock(display_name="web-server-1", lifecycle_state="RUNNING")
    ]
    instances = list_instances("ocid1.compartment.oc1..example")
    assert len(instances) == 1
    assert instances[0].display_name == "web-server-1"

Output

Successful completion produces:

  • A GitHub Actions workflow that authenticates to OCI using API key secrets
  • Terraform provider configuration with the explicit region workaround
  • OCI CLI setup steps for non-Terraform CI tasks
  • A test pattern using mocked OCI SDK clients for unit testing

Error Handling

| Error | Code | Cause | Solution | |-------|------|-------|----------| | NotAuthenticated | 401 | Bad API key or wrong fingerprint | Verify secrets match ~/.oci/config values exactly | | NotAuthorizedOrNotFound | 404 | IAM policy missing or wrong OCID | Add required IAM policy for the API key user | | Provider crash on plan | N/A | ResourcePrincipal region bug (#1761) | Always set region explicitly in provider block | | TooManyRequests | 429 | Rate limited (no Retry-After header) | Add retry logic with exponential backoff | | CERTIFICATE_VERIFY_FAILED | N/A | SSL cert issue in CI runner | Run pip install certifi and set REQUESTS_CA_BUNDLE | | Terraform init fails | N/A | Provider version mismatch | Pin provider version: version = ">= 5.0.0" |

Examples

Quick OCI auth test in CI:

# Verify OCI credentials work in a GitHub Actions step
pip install oci
python3 -c "
import oci
config = oci.config.from_file('~/.oci/config')
identity = oci.identity.IdentityClient(config)
user = identity.get_user(config['user']).data
print(f'Authenticated as: {user.name}')
"

Terraform plan with JSON output for PR comments:

terraform plan -out=tfplan
terraform show -json tfplan | python3 -c "
import sys, json
plan = json.load(sys.stdin)
changes = plan.get('resource_changes', [])
adds = sum(1 for c in changes if 'create' in c['change']['actions'])
dels = sum(1 for c in changes if 'delete' in c['change']['actions'])
print(f'Plan: +{adds} -{dels} resources')
"

Resources

Next Steps

After CI is working, proceed to oraclecloud-deploy-integration to set up container deployments via OKE or Container Instances, or see oraclecloud-observability to add monitoring to your CI-deployed infrastructure.