setup
Interactive setup wizard — walks through OCI configuration with guided questions
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Interactive setup wizard — walks through OCI configuration with guided questions
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Scaffold a new OCI Terraform module following project conventions
Open or close a TCP/UDP port on the instance — updates security list and iptables
Deploy or update OCI infrastructure — runs plan and apply
Manage SSH access to the OCI instance — open, connect, or close
Show current state of OCI infrastructure — IPs, resources, drift
| name | setup |
| description | Interactive setup wizard — walks through OCI configuration with guided questions |
| allowed-tools | Bash, Read, Write, Edit, Grep, Glob, AskUserQuestion |
Walk the user through configuring the OCI Always Free tier infrastructure step by step. Ask questions using AskUserQuestion to guide choices, then generate .env (secrets) and oci-prod.auto.tfvars (config).
Before checking local tools, ask the user if they already have an Oracle Cloud account:
If they don't have an account, walk them through creating one:
If they already have an account, ask if it's been upgraded to Pay As You Go. If not, recommend upgrading:
Check that oci CLI is installed (command -v oci). If not, tell the user to install it:
brew install oci-clibash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"oci setup config to create ~/.oci/configoci setup config completes, remind them to upload the generated API public key (printed at the end of setup, usually at ~/.oci/oci_api_key_public.pem) to their OCI profile:
oci setup config)~/.oci/configCheck that ~/.oci/config exists. If not, tell the user to run oci setup config and upload the generated public key to their OCI profile under Identity > Users > API Keys.
Check that tofu or terraform is installed (command -v tofu || command -v terraform). If not, suggest brew install opentofu.
Check for an SSH public key in ~/.ssh/ (look for id_ed25519.pub, id_rsa.pub, id_ecdsa.pub). If none found, tell the user to generate one with ssh-keygen -t ed25519 and wait for them to do so.
If any prerequisite is missing, stop and help the user fix it before continuing. Do not proceed with partial prerequisites.
Parse ~/.oci/config for the [DEFAULT] profile to extract tenancy, user, and region. Show these to the user and confirm they look correct.
Query the availability domain:
oci iam availability-domain list --query 'data[0].name' --raw-output
If this fails, the OCI CLI config is likely broken — help the user debug.
Read the SSH public key file content.
Show the user a summary of discovered values:
Ask the user the following questions using AskUserQuestion. Group related questions together where possible (up to 4 per call).
Question group 1 — Access mode and email:
Alert email: Ask for their email address for budget and monitoring alerts. This is optional — if provided, budget alerts are automatically created and monitoring alerts can be enabled. If left blank, no alerts are configured.
Public or private mode: Ask whether the instance should be publicly accessible.
Question group 2 — Optional modules and storage:
MySQL: Ask whether to enable MySQL HeatWave.
Object Storage: Ask whether to enable S3-compatible Object Storage.
Storage layout: Ask how they want to split their 200 GB free storage.
/data. Data survives instance recreation.Question group 3 — Monitoring (only if alert email was provided):
Skip this group if no alert email was provided — monitoring requires an email.
Idle detection alerts: Ask whether to enable reclaim-prevention alerts. Explain that Oracle reclaims Always Free instances that are idle for 7 days (CPU < 20%, memory < 20%, network < 20%). These alarms warn after ~4 days of low utilization.
High utilization alerts: Ask whether to enable alerts when CPU or memory exceed 90%.
Question group 4 — Ports (only if public mode was selected):
TCP ports: Ask which TCP ports to open. Provide options:
UDP ports: Ask if they need any UDP ports open.
Question group 5 — SSH access:
curl -4 -s https://ifconfig.me and set ssh_source_cidr to <ip>/32 in the tfvars. This opens port 22 from that single IP only.ssh_source_cidr empty. They can open it later with just ssh-allow.Question group 6 — Remote state backend:
Ask about remote state backend upfront so the full plan is known before generating any files. This is important because:
applyPresent options:
backend "oci" exists in Terraform 1.12+ but is not yet available in OpenTofu, so we use the S3-compatible API instead.Store the user's choice — it will be executed in Phase 6 (after .env and tfvars are generated but before init/plan).
Question group 7 — Object storage details (only if object storage was enabled):
Skip this group if object storage was not enabled.
Auto-tiering: Ask whether to enable automatic tiering.
Archive lifecycle: Ask if they want old objects automatically moved to Archive tier.
Run ./generate-env.sh to create .env with random secrets. The script generates all secrets internally — Claude never sees the values.
Check if .env already exists by running test -f .env && echo exists || echo missing.
If .env already exists — check for existing Terraform state before offering regeneration:
test -f terraform/environments/oci-prod/terraform.tfstate && echo "STATE_EXISTS" || echo "NO_STATE"
ls terraform/environments/oci-prod/.terraform/ 2>/dev/null && echo "INIT_EXISTS" || echo "NO_INIT"
If state exists (local or initialized): Default to keeping the existing .env. Warn the user:
"Your
.envalready exists and you have existing Terraform state encrypted with its passphrase. Regenerating.envwould create a new passphrase, making your existing state unreadable. I'll keep your current.env."
Only offer regeneration if the user explicitly asks, and warn them it will require destroying or migrating existing state first.
If MySQL is being newly enabled and .env may lack TF_VAR_mysql_admin_password, tell the user to add it manually:
"You're enabling MySQL but your existing
.envmay not have a MySQL password. Add one manually:echo 'TF_VAR_mysql_admin_password="'$(openssl rand -base64 24)'"' >> .env"
If no state exists: Safe to regenerate. Ask if they want to regenerate (this backs up the old one first). If yes, run with --force. If no, skip to Phase 5.
If .env does not exist (fresh setup): Run the script via Bash with the appropriate flags:
./generate-env.sh --mysql # first time, MySQL enabled
./generate-env.sh --no-mysql # first time, MySQL disabled
The --mysql / --no-mysql flag is determined by whether MySQL was enabled in Phase 3.
CRITICAL: Never read, cat, source, or inspect .env contents. A hook blocks this — the secrets must never appear in the conversation.
Tell the user: "Your .env file has been generated with random secrets. Back it up — losing the passphrase means losing access to your Terraform state. The file is gitignored and loaded automatically by just recipes."
Check if terraform/environments/oci-prod/oci-prod.auto.tfvars already exists. If so, ask whether to overwrite or abort.
Generate oci-prod.auto.tfvars with the collected values. Only include non-default values to keep the file clean. Always include:
compartment_ociduser_ocidavailability_domainssh_public_keyConditionally include (only when different from defaults):
alert_email (only if provided)enable_public_access (only if false)additional_tcp_ports (only if not [80, 443])additional_udp_ports (only if not empty)ssh_source_cidr (only if user chose to whitelist their IP)enable_mysql (only if true)enable_object_storage (only if true)object_storage_auto_tiering (only if false and object storage enabled)enable_block_volume (only if false)boot_volume_size_gb (only if not 50)enable_idle_alerts (only if true)enable_high_utilization_alerts (only if true)object_storage_archive_enabled (only if true and object storage enabled)object_storage_archive_days (only if archive enabled)Use the same format as oci-prod.auto.tfvars.example with section headers and comments explaining each value.
Write the file using the Write tool.
Execute the remote state backend choice from Phase 3, Question group 6. This must happen BEFORE init so state goes directly to the remote backend on first run.
If the user chose OCI Object Storage:
This requires an S3-compatible bucket and Customer Secret Key credentials. Run the CLI commands directly — don't just show them.
Create the state bucket (must exist before backend config). Run via Bash:
oci os bucket create --name terraform-state --compartment-id <compartment_ocid>
If the bucket already exists, oci os bucket get --name terraform-state will confirm it.
Get the namespace (needed for the S3 endpoint URL). Run via Bash:
oci os ns get --query 'data' --raw-output
Store the namespace value — it's needed for the backend endpoint URL.
The user must create S3 credentials manually in the OCI Console (these can't be created via CLI):
.env themselves:
echo 'AWS_ACCESS_KEY_ID="<their_access_key>"' >> .env
echo 'AWS_SECRET_ACCESS_KEY="<their_secret_key>"' >> .env
Do NOT read .env after writing. The user pastes their own values.Update the backend block in main.tf using the Edit tool. Uncomment and fill in the existing S3 backend block with the discovered namespace and region:
backend "s3" {
bucket = "terraform-state"
key = "oci-prod/terraform.tfstate"
region = "<region>"
endpoints = { s3 = "https://<namespace>.compat.objectstorage.<region>.oraclecloud.com" }
skip_region_validation = true
skip_credentials_validation = true
skip_requesting_account_id = true
skip_metadata_api_check = true
use_path_style = true
}
Proceed to Phase 7 — just init will configure the remote backend and send state directly there.
If the user chose HCP Terraform:
tofu loginmain.tf with a cloud {} block (use Edit tool):
cloud {
organization = "<their-org>"
workspaces {
name = "oci-prod"
}
}
just init will configure the backend.If the user chose "Skip for now": Proceed directly to Phase 7.
Run init and plan so the user can see what will be created:
Run just init via Bash. If it fails, help the user debug (common issues: missing OCI config, bad credentials, network errors). If a remote backend was configured in Phase 6, init will set it up now.
Run just plan via Bash. Show the user a summary of what will be created/changed/destroyed.
After init and plan succeed, deploy the infrastructure:
Ask the user if they'd like to proceed with just apply-auto to deploy now, or do it later.
just apply-auto via Bash. Show the summary output after apply completes.just apply later when ready.If the user deployed with enable_object_storage = true AND chose OCI Object Storage for remote state in Phase 6, run just s3-creds-to-env via Bash after apply completes. This extracts the Terraform-managed S3 credentials and writes them to .env — Claude never sees the credential values. This is a convenience step: the user already created manual S3 credentials in Phase 6 for the state backend, but this captures the Terraform-managed credentials too (which may be useful for other S3 operations).
Show the user what to do after deployment:
Connect to the instance:
just ssh to connect directlyjust ssh-allow first to open SSH from their current IP, then just sshjust ssh-revoke/data on first boot via cloud-initIf MySQL enabled: just mysql-tunnel for MySQL access
Remind them to back up .env — losing the passphrase means losing access to Terraform state.
tofu for all commands (not terraform) per project convention.TF_VAR_state_passphrase, TF_VAR_mysql_admin_password) go in .env — never in .auto.tfvars or committed files. The .env file is gitignored and loaded automatically by just via set dotenv-load..env contents. A PreToolUse hook (.claude/hooks/protect-env.sh) blocks access. All secret generation is handled by ./generate-env.sh — Claude calls it but never sees the values.oci-prod.auto.tfvars.example.