oraclecloud-multi-env-setup
Configure multi-environment OCI workflows with config profiles and compartment-per-environment patterns. Use when setting up dev/staging/prod separation, switching between OCI profiles, or preventing accidental production deployments. Trigger with "oraclecloud multi env setup", "oci profiles", "oci environments", "oci config profiles".
Best use case
oraclecloud-multi-env-setup is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Configure multi-environment OCI workflows with config profiles and compartment-per-environment patterns. Use when setting up dev/staging/prod separation, switching between OCI profiles, or preventing accidental production deployments. Trigger with "oraclecloud multi env setup", "oci profiles", "oci environments", "oci config profiles".
Teams using oraclecloud-multi-env-setup should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/oraclecloud-multi-env-setup/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How oraclecloud-multi-env-setup Compares
| Feature / Agent | oraclecloud-multi-env-setup | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Configure multi-environment OCI workflows with config profiles and compartment-per-environment patterns. Use when setting up dev/staging/prod separation, switching between OCI profiles, or preventing accidental production deployments. Trigger with "oraclecloud multi env setup", "oci profiles", "oci environments", "oci config profiles".
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
AI Agents for Coding
Browse AI agent skills for coding, debugging, testing, refactoring, code review, and developer workflows across Claude, Cursor, and Codex.
Best AI Skills for Claude
Explore the best AI skills for Claude and Claude Code across coding, research, workflow automation, documentation, and agent operations.
ChatGPT vs Claude for Agent Skills
Compare ChatGPT and Claude for AI agent skills across coding, writing, research, and reusable workflow execution.
SKILL.md Source
# Oracle Cloud Multi-Environment Setup
## Overview
OCI has no "accounts" like AWS — you use compartments plus OCI config profiles for dev/staging/prod separation. But profile switching is manual, compartment OCIDs are easy to confuse, and one wrong `--compartment-id` deploys to production. This skill sets up safe multi-environment workflows with named profiles, compartment aliasing, environment validation, and deployment guardrails.
**Purpose:** Configure safe, repeatable multi-environment OCI workflows that prevent accidental cross-environment operations.
## Prerequisites
- **OCI Python SDK** — `pip install oci`
- **OCI CLI** — installed and configured (`oci setup config`)
- **Separate API keys per environment** (recommended) or a single key with cross-compartment policies
- **Compartment OCIDs** for each environment (dev, staging, prod)
- Python 3.8+
## Instructions
### Step 1: Configure Multi-Profile ~/.oci/config
The OCI config file supports named profiles. Each profile can point to different tenancies, regions, or use different API keys:
```ini
# ~/.oci/config
[DEFAULT]
user=ocid1.user.oc1..exampleuniqueID
fingerprint=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
tenancy=ocid1.tenancy.oc1..exampleuniqueID
region=us-ashburn-1
key_file=~/.oci/oci_api_key.pem
[DEV]
user=ocid1.user.oc1..exampleuniqueID
fingerprint=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
tenancy=ocid1.tenancy.oc1..exampleuniqueID
region=us-ashburn-1
key_file=~/.oci/oci_api_key_dev.pem
[STAGING]
user=ocid1.user.oc1..exampleuniqueID
fingerprint=11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00
tenancy=ocid1.tenancy.oc1..exampleuniqueID
region=us-phoenix-1
key_file=~/.oci/oci_api_key_staging.pem
[PROD]
user=ocid1.user.oc1..exampleuniqueID
fingerprint=ff:ee:dd:cc:bb:aa:00:99:88:77:66:55:44:33:22:11
tenancy=ocid1.tenancy.oc1..exampleuniqueID
region=us-ashburn-1
key_file=~/.oci/oci_api_key_prod.pem
```
**Best practice:** Use different API key pairs per environment. If the dev key is compromised, prod is unaffected.
### Step 2: Create an Environment Configuration Module
Centralize compartment OCIDs and profile mappings to prevent OCID confusion:
```python
import oci
import os
# Environment configuration — single source of truth for OCIDs
ENVIRONMENTS = {
"dev": {
"profile": "DEV",
"compartment_id": "ocid1.compartment.oc1..dev_example",
"region": "us-ashburn-1",
"allow_destructive": True,
},
"staging": {
"profile": "STAGING",
"compartment_id": "ocid1.compartment.oc1..staging_example",
"region": "us-phoenix-1",
"allow_destructive": True,
},
"prod": {
"profile": "PROD",
"compartment_id": "ocid1.compartment.oc1..prod_example",
"region": "us-ashburn-1",
"allow_destructive": False, # Safety: block destructive ops
},
}
def get_oci_config(env_name):
"""Load OCI config for the specified environment.
Validates the environment name and returns a configured
OCI config dict ready for client construction.
"""
if env_name not in ENVIRONMENTS:
raise ValueError(
f"Unknown environment: {env_name}. "
f"Valid: {list(ENVIRONMENTS.keys())}"
)
env = ENVIRONMENTS[env_name]
config = oci.config.from_file("~/.oci/config", profile_name=env["profile"])
oci.config.validate_config(config)
return config, env
def get_compartment_id(env_name):
"""Get the compartment OCID for an environment."""
return ENVIRONMENTS[env_name]["compartment_id"]
def is_destructive_allowed(env_name):
"""Check if destructive operations are allowed in this environment."""
return ENVIRONMENTS[env_name]["allow_destructive"]
```
### Step 3: Build Safe Environment-Aware Clients
Wrap OCI clients with environment validation to prevent cross-environment mistakes:
```python
import oci
import sys
class OCIEnvironment:
"""Environment-aware OCI client factory with safety guardrails."""
def __init__(self, env_name):
self.env_name = env_name
self.config, self.env = get_oci_config(env_name)
self.compartment_id = self.env["compartment_id"]
# Verify we can authenticate
identity = oci.identity.IdentityClient(self.config)
user = identity.get_user(self.config["user"]).data
print(f"[{env_name.upper()}] Authenticated as {user.name} "
f"in {self.config['region']}")
def compute(self):
return oci.core.ComputeClient(self.config)
def network(self):
return oci.core.VirtualNetworkClient(self.config)
def storage(self):
return oci.object_storage.ObjectStorageClient(self.config)
def database(self):
return oci.database.DatabaseClient(self.config)
def safe_delete(self, operation, resource_name):
"""Execute a delete operation with environment safety checks."""
if not is_destructive_allowed(self.env_name):
print(f"BLOCKED: Destructive operation on {resource_name} "
f"not allowed in {self.env_name.upper()}")
print("Set allow_destructive=True in ENVIRONMENTS to override")
sys.exit(1)
print(f"WARNING: Deleting {resource_name} in {self.env_name.upper()}")
return operation()
# Usage
dev = OCIEnvironment("dev")
instances = dev.compute().list_instances(compartment_id=dev.compartment_id).data
print(f"Dev instances: {len(instances)}")
prod = OCIEnvironment("prod")
# prod.safe_delete(...) would be blocked by allow_destructive=False
```
### Step 4: CLI Profile Switching
Use profiles with the OCI CLI to target specific environments:
```bash
# List instances in dev
oci compute instance list --compartment-id ocid1.compartment.oc1..dev_example --profile DEV
# List instances in prod (read-only)
oci compute instance list --compartment-id ocid1.compartment.oc1..prod_example --profile PROD
# Set default profile via environment variable
export OCI_CLI_PROFILE=DEV
# Override per-command
OCI_CLI_PROFILE=PROD oci compute instance list --compartment-id ocid1.compartment.oc1..prod_example
```
**Shell aliases for safety:**
```bash
# Add to ~/.bashrc or ~/.zshrc
alias oci-dev='OCI_CLI_PROFILE=DEV oci'
alias oci-staging='OCI_CLI_PROFILE=STAGING oci'
alias oci-prod='OCI_CLI_PROFILE=PROD oci'
# Usage
oci-dev compute instance list --compartment-id ocid1.compartment.oc1..dev_example
oci-prod compute instance list --compartment-id ocid1.compartment.oc1..prod_example
```
### Step 5: Validate Config Before Operations
Always validate the config file and profile before running automation:
```python
import oci
def validate_all_profiles():
"""Validate all OCI config profiles are properly configured."""
profiles = ["DEFAULT", "DEV", "STAGING", "PROD"]
results = {}
for profile in profiles:
try:
config = oci.config.from_file("~/.oci/config", profile_name=profile)
oci.config.validate_config(config)
# Test authentication
identity = oci.identity.IdentityClient(config)
user = identity.get_user(config["user"]).data
results[profile] = f"OK — {user.name} in {config['region']}"
except oci.exceptions.ConfigFileNotFound:
results[profile] = "FAIL — config file not found"
except oci.exceptions.ProfileNotFound:
results[profile] = "FAIL — profile not found in config"
except oci.exceptions.ServiceError as e:
results[profile] = f"FAIL — {e.status}: {e.code}"
except Exception as e:
results[profile] = f"FAIL — {str(e)}"
print("OCI Profile Validation:")
for profile, status in results.items():
print(f" [{profile}] {status}")
return all("OK" in s for s in results.values())
validate_all_profiles()
```
### Step 6: Environment Variables for CI/CD
For CI/CD pipelines where config files are impractical, use environment variables:
```bash
# Set OCI config via environment variables (CI/CD pipelines)
export OCI_CLI_USER="ocid1.user.oc1..exampleuniqueID"
export OCI_CLI_FINGERPRINT="aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99"
export OCI_CLI_TENANCY="ocid1.tenancy.oc1..exampleuniqueID"
export OCI_CLI_REGION="us-ashburn-1"
export OCI_CLI_KEY_FILE="/path/to/key.pem"
# Or use key content directly:
export OCI_CLI_KEY_CONTENT="-----BEGIN RSA PRIVATE KEY-----\n..."
```
```python
import oci
# Python SDK reads from environment when no config file exists
config = oci.config.from_file() # Falls back to env vars if ~/.oci/config missing
# Or construct config dict directly for CI/CD
config = {
"user": os.environ["OCI_CLI_USER"],
"fingerprint": os.environ["OCI_CLI_FINGERPRINT"],
"tenancy": os.environ["OCI_CLI_TENANCY"],
"region": os.environ["OCI_CLI_REGION"],
"key_file": os.environ["OCI_CLI_KEY_FILE"],
}
oci.config.validate_config(config)
```
## Output
Successful completion produces:
- A `~/.oci/config` file with named profiles for each environment (DEV, STAGING, PROD)
- An environment configuration module mapping profiles to compartment OCIDs
- An environment-aware client factory with safety guardrails blocking destructive prod operations
- Shell aliases for safe CLI profile switching
- Validated authentication for all profiles
## Error Handling
| Error | Code | Cause | Solution |
|-------|------|-------|----------|
| ProfileNotFound | — | Wrong profile name in `from_file()` | Check `~/.oci/config` profile names match exactly (case-sensitive) |
| ConfigFileNotFound | — | Missing `~/.oci/config` | Run `oci setup config` or create the file manually |
| NotAuthenticated | 401 | Wrong key for the selected profile | Verify key_file path and fingerprint match the uploaded public key |
| NotAuthorizedOrNotFound | 404 | Profile's user lacks access to target compartment | Add IAM policies for the user/group in the target compartment |
| TooManyRequests | 429 | Rate limited | Back off; see `oraclecloud-rate-limits` |
| InternalError | 500 | OCI service error | Retry after 30s; check https://ocistatus.oraclecloud.com |
**Critical mistake:** Using the DEFAULT profile's compartment OCID with the PROD profile's credentials (or vice versa). The environment config module in Step 2 prevents this by coupling profile names to compartment OCIDs.
## Examples
**Quick profile test from the command line:**
```bash
# Test all profiles in one shot
for profile in DEFAULT DEV STAGING PROD; do
echo -n "[$profile] "
oci iam user get --user-id "$(oci iam user list --profile "$profile" --query 'data[0].id' --raw-output 2>/dev/null)" --profile "$profile" --query 'data.name' --raw-output 2>/dev/null || echo "FAILED"
done
```
**Check which profile is active:**
```python
import oci
import os
profile = os.environ.get("OCI_CLI_PROFILE", "DEFAULT")
config = oci.config.from_file("~/.oci/config", profile_name=profile)
print(f"Active profile: {profile}")
print(f"Region: {config['region']}")
print(f"Tenancy: {config['tenancy']}")
```
## Resources
- [OCI Config File](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm) — config file format and profile syntax
- [CLI Environment Variables](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/clienvironmentvariables.htm) — OCI_CLI_* variables
- [CLI Reference](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/cliconcepts.htm) — command-line interface guide
- [Python SDK Reference](https://docs.oracle.com/en-us/iaas/tools/python/latest/) — config loading and client construction
- [Compartment Management](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingcompartments.htm) — organizing resources by environment
## Next Steps
After environments are configured, see `oraclecloud-enterprise-rbac` for compartment hierarchy design with least-privilege policies, or `oraclecloud-deploy-integration` for CI/CD pipeline integration.Related Skills
windsurf-multi-env-setup
Configure Windsurf IDE and Cascade AI across team members and project environments. Use when onboarding teams to Windsurf, setting up per-project Cascade configuration, or managing Windsurf settings across development, staging, and production contexts. Trigger with phrases like "windsurf team setup", "windsurf environments", "windsurf multi-project", "windsurf team config", "cascade rules per env".
webflow-multi-env-setup
Configure Webflow across development, staging, and production environments with per-environment API tokens, site IDs, and secret management via Vault/AWS/GCP. Trigger with phrases like "webflow environments", "webflow staging", "webflow dev prod", "webflow environment setup", "webflow config by env".
vercel-multi-env-setup
Configure Vercel across development, preview, and production environments with scoped secrets. Use when setting up per-environment configuration, managing environment-specific variables, or implementing environment isolation on Vercel. Trigger with phrases like "vercel environments", "vercel staging", "vercel dev prod", "vercel environment setup", "vercel env scoping".
veeva-multi-env-setup
Veeva Vault multi env setup for enterprise operations. Use when implementing advanced Veeva Vault patterns. Trigger: "veeva multi env setup".
vastai-multi-env-setup
Configure Vast.ai GPU cloud across dev, staging, and production environments. Use when isolating GPU pools per team, managing API key separation by env, or implementing spending controls per deployment tier. Trigger with phrases like "vastai environments", "vastai staging", "vastai dev prod", "vastai multi-env".
supabase-multi-env-setup
Configure Supabase across development, staging, and production with separate projects, environment-specific secrets, and safe migration promotion. Use when setting up multi-environment deployments, isolating dev from prod data, configuring per-environment Supabase projects, or promoting migrations through environments. Trigger: "supabase environments", "supabase staging", "supabase dev prod", "supabase multi-project", "supabase env config", "database branching".
speak-multi-env-setup
Configure Speak across dev, staging, and production with separate API keys and mock modes. Use when implementing multi env setup, or managing Speak language learning platform operations. Trigger with phrases like "speak multi env setup", "speak multi env setup".
snowflake-multi-env-setup
Configure Snowflake across dev, staging, and production with account-level isolation, zero-copy clones, and environment-specific RBAC. Trigger with phrases like "snowflake environments", "snowflake staging", "snowflake dev prod", "snowflake clone", "snowflake environment setup".
windsurf-workspace-setup
Initialize Windsurf workspace with project-specific AI rules. Activate when users mention "create windsurfrules", "setup workspace", "configure project ai", "initialize windsurf workspace", or "migrate to windsurf". Handles workspace configuration and team standardization. Use when working with windsurf workspace setup functionality. Trigger with phrases like "windsurf workspace setup", "windsurf setup", "windsurf".
windsurf-multi-file-editing
Manage multi-file edits with Cascade coordination. Activate when users mention "multi-file edit", "edit multiple files", "cross-file changes", "refactor across files", or "batch modifications". Handles coordinated multi-file operations. Use when working with windsurf multi file editing functionality. Trigger with phrases like "windsurf multi file editing", "windsurf editing", "windsurf".
shopify-multi-env-setup
Configure Shopify apps across development, staging, and production environments with separate stores, API credentials, and app instances. Trigger with phrases like "shopify environments", "shopify staging", "shopify dev vs prod", "shopify multi-store", "shopify environment setup".
salesforce-multi-env-setup
Configure Salesforce across Developer, Sandbox, and Production environments with proper org management. Use when setting up multi-environment deployments, configuring per-environment credentials, or implementing sandbox-to-production promotion flows. Trigger with phrases like "salesforce environments", "salesforce sandbox", "salesforce dev prod", "salesforce org management", "salesforce sandbox types".