{"id":51001873,"url":"https://github.com/iblai/infra-cli","last_synced_at":"2026-06-26T20:00:27.439Z","repository":{"id":345615299,"uuid":"1177191585","full_name":"iblai/infra-cli","owner":"iblai","description":"Interactive CLI for provisioning the ibl.ai platform on AWS with Terraform and configuring servers with Ansible. Supports bootstrapping any existing server.","archived":false,"fork":false,"pushed_at":"2026-06-20T14:04:03.000Z","size":938,"stargazers_count":11,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-20T15:37:54.121Z","etag":null,"topics":["ai-infrastructure","ansible","automation","aws","cli","cloud","deployment","devops","iac","ibl-ai","infrastructure","infrastructure-as-code","platform-engineering","provisioning","python","self-hosted","server-setup","terraform"],"latest_commit_sha":null,"homepage":"https://ibl.ai","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iblai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-09T19:36:29.000Z","updated_at":"2026-06-17T18:56:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/iblai/infra-cli","commit_stats":null,"previous_names":["iblai/iblai-infra-cli","iblai/infra-cli"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/iblai/infra-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iblai%2Finfra-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iblai%2Finfra-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iblai%2Finfra-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iblai%2Finfra-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iblai","download_url":"https://codeload.github.com/iblai/infra-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iblai%2Finfra-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34831250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-infrastructure","ansible","automation","aws","cli","cloud","deployment","devops","iac","ibl-ai","infrastructure","infrastructure-as-code","platform-engineering","provisioning","python","self-hosted","server-setup","terraform"],"created_at":"2026-06-20T15:30:43.116Z","updated_at":"2026-06-26T20:00:27.427Z","avatar_url":"https://github.com/iblai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"https://ibl.ai\"\u003e\u003cimg src=\"https://ibl.ai/images/iblai-logo.png\" alt=\"ibl.ai\" width=\"300\"\u003e\u003c/a\u003e\n\n# Infra CLI\n\nInteractive CLI for provisioning and configuring the [ibl.ai](https://ibl.ai) platform on AWS. Handles end-to-end infrastructure creation with Terraform and full application setup with Ansible. Can also bootstrap existing servers (any cloud or bare metal) without Terraform.\n\n[![AWS](https://img.shields.io/badge/AWS-FF9900?logo=amazonaws\u0026logoColor=white)](https://aws.amazon.com)\n[![Terraform](https://img.shields.io/badge/Terraform-7B42BC?logo=terraform\u0026logoColor=white)](https://www.terraform.io)\n[![Python 3.11+](https://img.shields.io/badge/Python-3.11+-3776AB?logo=python\u0026logoColor=white)](https://www.python.org)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n\u003c/div\u003e\n\n\u003e **Note:** This repository contains the installation and infrastructure provisioning guide. Access to the ibl.ai Docker images and platform codebase requires a license. To get started, reach out to our team at [ibl.ai/contact](https://ibl.ai/contact).\n\n---\n\n## Prerequisites\n\n- **Python 3.11+**\n- **[uv](https://docs.astral.sh/uv/)** (recommended) or pip\n- **[Terraform](https://developer.hashicorp.com/terraform/install)** installed and on PATH\n- **AWS account** with EC2, ELB, S3, ACM, Route53, IAM, and STS permissions\n- **SSH access** to the target EC2 instance (key is generated or provided during provisioning)\n\n### Dependencies installed automatically\n\nThe following are installed as Python package dependencies when you install iblai-infra-ops:\n\n- **ansible-core** (\u003e= 2.15) -- used by `iblai infra setup` to configure the server\n- **boto3** -- AWS SDK for authentication and resource management\n- **terraform** -- called as a subprocess (must be installed separately, see above)\n\n### What the Ansible setup installs on the target server\n\nThe setup phase installs and configures the following on the provisioned EC2 instance:\n\n- **[iblai-cli-ops](https://github.com/iblai/iblai-cli-ops)** -- the IBL platform management CLI, installed inside a pyenv virtualenv on the server. Required by every service launch. **Private repository — unauthenticated requests see a 404.**\n- **Docker Engine** with docker compose\n- **pyenv** with Python 3.11.8\n- **AWS CLI v2** for ECR authentication and S3 access\n\n## Install\n\nUsing [uv](https://docs.astral.sh/uv/) (recommended):\n\n```bash\n# Install uv if you don't have it\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Clone the repo\ngit clone git@github.com:iblai/iblai-infra-ops.git\ncd iblai-infra-ops\n\n# Create a virtual environment and install\nuv venv\nsource .venv/bin/activate\nuv pip install .\n```\n\nFor development:\n\n```bash\nuv pip install -e \".[dev]\"\n```\n\nUsing pip:\n\n```bash\npip install .\n```\n\n### Verify installation\n\n```bash\niblai --version\n```\n\nVerify Ansible is available (installed as a dependency):\n\n```bash\nansible-playbook --version\n```\n\nVerify Terraform is installed:\n\n```bash\nterraform --version\n```\n\n## Usage\n\nRun `iblai infra` to see all available commands and a getting-started guide.\n\n### 1. Check IAM permissions\n\nBefore provisioning, verify your AWS credentials have the required permissions:\n\n```bash\niblai infra permissions              # Show required IAM policy JSON\niblai infra permissions --check      # Dry-run verification against active credentials\n```\n\n### 2. Provision infrastructure\n\n```bash\niblai infra provision\n```\n\nInteractive wizard that walks you through:\n\n1. **AWS credentials** -- profile, access keys, or environment variables\n2. **Deployment topology** -- single-server, multi-server (N app servers + 1 services server), or call-server (standalone LiveKit)\n3. **Project \u0026 compute** -- name, environment (dev/staging/prod), instance type, volume size\n4. **Network \u0026 SSH** -- VPC CIDR, VPN IP for SSH access, SSH key setup\n5. **Domain \u0026 certificates** -- base domain, Route53 integration, certificate method (ACM, upload, or none)\n6. **WAF (optional)** -- single-server only; attach an AWS WAFv2 Web ACL to the ALB with admin-only allow rules for Swagger UI / edX Studio / `/admin/` / DM `/data` plus AWS managed rule groups. Default off. Skip here and add it later with `iblai infra waf enable \u003cname\u003e`.\n7. **Review** -- full summary before applying\n\nSizing guidance: single / multi-server require a **100 GB minimum** root volume. Picking a 32 GB-RAM instance prints a non-blocking heads-up suggesting 64 GB (e.g. `m5.4xlarge` / `r5.2xlarge`) when AI features will be enabled.\n\nTerraform runs with real-time progress showing each resource as it's created.\n\n### 3. Setup the platform\n\n```bash\niblai infra setup              # Set up an existing server (any provider, bare metal)\niblai infra setup \u003cname\u003e       # Set up a Terraform-provisioned environment by name\n```\n\nBoth paths run the same Ansible playbook. The difference is where the inputs come from:\n\n- **With a project name** -- auto-populates IP, domain, SSH key, and AWS credentials from the Terraform state\n- **Without a project name** -- prompts for server IP, SSH key, domain, image tags, and credentials interactively. No Terraform required.\n\nThe playbook runs sequential roles grouped by concern:\n\n| Phase | Roles | What it does |\n|---|---|---|\n| Host setup | `docker`, `awscli`, `python` | Docker Engine + compose, AWS CLI v2, pyenv + Python 3.11.8 |\n| Platform install | `ibl_cli_ops`, `ibl_platform` | Installs [iblai-prod-images](https://github.com/iblai/iblai-prod-images) (pins `iblai-cli-ops` + image versions); configures base domain, CORS, RBAC, gateway, defaults |\n| Core services | `ibl_dm`, `ibl_edx`, `ibl_spa` | Launches DM (Django + Postgres + Redis + Celery + Flowise + Langfuse), edX (LMS / CMS / MySQL / MongoDB / Elasticsearch / Forum), and the Auth / Mentor / Skills SPAs |\n| Finalization | `integrations`, `admin_setup`, `data_seeding`, `ibl_tenant_platform` | OAuth/OIDC setup, syncs edX with DM, creates super admin, seeds CSRF / flows / LLM registry / mentors / RBAC; launches a tenant `Platform` via `run_launch_steps` when `PLATFORM_NAME` is set to anything other than `main` |\n| Optional integrations | `smtp_config`, `stripe_config`, `google_sso_config`, `microsoft_sso_config` | Each role no-ops unless its trigger key (`SMTP_HOST` / `STRIPE_SECRET_KEY` / `GOOGLE_SSO_CLIENT_ID` / `MICROSOFT_SSO_CLIENT_ID`) is set |\n| Post-tasks | `ibl global-proxy reload` | Final nginx reload so any SSO-driven edX/SPA restarts are picked up before exit |\n\nThe setup wizard prompts for: target host + SSH key, base domain, tenant platform name (blank for `main` — `main` itself is reserved), `iblai-cli-ops` release tag, enable-AI toggle, OpenAI key, super admin credentials, GitHub PAT, and AWS credentials. Reserved usernames (e.g. `ibl_admin`) are rejected — the new default suggestion is `platform_admin`. Stripe billing UI and advertising are **off by default**; enable Stripe by passing `STRIPE_SECRET_KEY`.\n\n### 4. Non-interactive provision + setup (`.env` file)\n\nSkip the wizards. Same Terraform + same Ansible roles as the interactive flow, driven from a `.env` file. **Single-server only** (multi / call still use the wizard).\n\n```bash\n# Provision (Terraform) — fresh single-server, no AMI required\ncp .env.provision.example .env.provision \u0026\u0026 $EDITOR .env.provision\niblai infra provision-env -f .env.provision\n\n# Bootstrap (Ansible) — against the just-provisioned project\ncp .env.setup.example .env.setup \u0026\u0026 $EDITOR .env.setup\niblai infra setup-env \u003cproject-name\u003e -f .env.setup\n```\n\n**Free-standing server** (any cloud, no Terraform): omit the project name and add `TARGET_HOST`, `SSH_PRIVATE_KEY_PATH`, `BASE_DOMAIN`, `PROJECT_NAME` to `.env.setup`, then `iblai infra setup-env -f .env.setup`.\n\n**Schema:** `.env.provision.example` and `.env.setup.example` document every key inline (required vs. optional, defaults, integration triggers).\n\n**Security:** populated `.env` files are gitignored (`.env.*` blocked except `*.example`). The CLI never persists secrets to `state.json` — they ride `--extra-vars` into Ansible at run time only.\n\n### 5. Re-setup an existing environment\n\n```bash\niblai infra resetup \u003cname\u003e\n```\n\nRe-configures a previously set up environment with a new domain and fresh secrets. Prompts for the new base domain, CLI ops release tag, and credentials. Runs `ibl config rotate-secrets` to regenerate all secrets, syncs database passwords (PostgreSQL and MySQL), then restarts all services.\n\nUse this when you need to change the domain or rotate credentials on a running environment without reprovisioning the infrastructure.\n\n### 6. Manage optional features post-provision\n\nSome features (currently WAF; more to follow — SMTP, Stripe, SSO providers) can be turned on or off against an already-provisioned stack without re-running the wizard or destroying anything. Each feature gets its own subgroup under `iblai infra \u003cfeature\u003e`:\n\n```bash\niblai infra waf enable [\u003cname\u003e]              # interactive: prompts for admin IPs/CIDRs\niblai infra waf enable-env [\u003cname\u003e] -f .env  # non-interactive: reads WAF_ALLOWED_IPS\niblai infra waf disable \u003cname\u003e [--yes]       # removes Web ACL + IPSet; ALB stays intact\niblai infra waf status [\u003cname\u003e]              # table of all eligible stacks, or detail panel for one\n```\n\nRunning `enable` on a stack that already has WAF on prompts to update the allowlist (current IPs pre-filled for easy edit). Single-server only — multi-server / call-server / bootstrap projects are rejected with a clear error. Each toggle re-runs Terraform on the existing workspace; the original S3 bucket names and other resources are preserved.\n\n### 7. Launch from AMI\n\nOne-shot Terraform + Ansible from a pre-built AMI. Two equivalent entry points — `.env` for ergonomics, flags for CI/CD.\n\n```bash\n# .env-driven (review + confirm)\ncp .env.example .env \u0026\u0026 $EDITOR .env\niblai infra launch-env\n\n# Fully non-interactive (CI/CD pipelines)\niblai infra launch \\\n  --ami-id $AMI_ID --domain $DOMAIN --hosted-zone-id $HOSTED_ZONE_ID \\\n  --aws-key-id $AWS_ACCESS_KEY_ID --aws-secret-key $AWS_SECRET_ACCESS_KEY \\\n  --ssh-public-key \"$SSH_PUBLIC_KEY\" --ssh-key $SSH_KEY_PATH \\\n  --git-token $GIT_TOKEN --vpn-ip $VPN_IP \\\n  --admin-email $ADMIN_EMAIL --admin-password $ADMIN_PASSWORD\n```\n\n**Flow:** Terraform creates VPC / ALB / ACM / Route53 and launches EC2 from the AMI → Ansible sets the domain, rotates secrets, syncs DB passwords, restarts services, runs OAuth + admin + seeding → final `ibl global-proxy reload`.\n\nSee `iblai infra launch --help` for optional flags (instance type, volume size, region, `--platform-name`, SMTP / Stripe / SSO toggles, `--enable-ai`).\n\n### 8. Service update (image updates, CI/CD)\n\nUpdate container images and restart services on an existing server or a freshly launched AMI. No infrastructure provisioning, no secret rotation.\n\n**Update an existing server:**\n\n```bash\niblai infra service-update \\\n  --host 10.0.1.50 \\\n  --ssh-key ~/.ssh/key.pem \\\n  --git-token $GIT_TOKEN\n```\n\n**Launch from AMI + update + register in ALB target group:**\n\n```bash\niblai infra service-update \\\n  --ami-id $AMI_ID \\\n  --subnet-id $SUBNET_ID \\\n  --security-group-id $SECURITY_GROUP_ID \\\n  --target-group-arn $TARGET_GROUP_ARN \\\n  --key-pair-name $KEY_PAIR_NAME \\\n  --ssh-key ~/.ssh/key.pem \\\n  --git-token $GIT_TOKEN \\\n  --aws-key-id $AWS_ACCESS_KEY_ID \\\n  --aws-secret-key $AWS_SECRET_ACCESS_KEY\n```\n\nWhat it does: installs latest `iblai-prod-images` (new image versions) → edX stop/start → DM update → DM migrations → SPA restart → nginx restart.\n\n### 9. Manage environments\n\n```bash\niblai infra list                # List all managed environments\niblai infra status \u003cname\u003e       # Show infrastructure details and outputs\niblai infra auth                # Switch AWS credentials\niblai infra destroy \u003cname\u003e      # Tear down infrastructure or remove bootstrap project\n```\n\n## Authentication\n\nThe CLI always lets you choose how to authenticate -- it never silently auto-detects credentials. On first use, it walks you through authentication interactively.\n\nSupported methods:\n- **AWS profiles** from `~/.aws/config` and `~/.aws/credentials` (type to filter)\n- **Environment variables** (`AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`)\n- **Manual entry** -- access key + secret key (masked input)\n\nYour session is saved after authentication and reused across commands until you switch credentials or it expires.\n\n## Architecture\n\n### AWS Single Server\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://ibl.ai/architecture/aws-single.png\" alt=\"AWS Single Server Architecture\" width=\"800\"\u003e\n\u003c/div\u003e\n\n### AWS Multi Server\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://ibl.ai/architecture/aws-multi.png\" alt=\"AWS Multi Server Architecture\" width=\"800\"\u003e\n\u003c/div\u003e\n\n## What gets created\n\n### AWS Infrastructure (Terraform)\n\n- VPC with 2 public subnets across availability zones (10.0.0.0/16)\n- EC2 instance (Ubuntu 22.04) with encrypted EBS volume (AES-256)\n- Application Load Balancer with TLS 1.2/1.3 termination\n- ACM certificates (RSA 2048-bit, DNS-validated, auto-renewed)\n- Security groups (SSH restricted to VPN CIDR, HTTP/HTTPS from ALB only)\n- 3 S3 buckets with server-side encryption (backups, media, static)\n- Route53 hosted zone with 19 subdomain A-records\n- *Optional:* AWS WAFv2 Web ACL attached to the ALB with admin-IP allowlist, six AWS managed rule groups, and a path-traversal block (opt-in via the wizard or `iblai infra waf enable`)\n\n### Platform Services (Ansible)\n\n- **iblai-edx-pro** -- LMS, CMS, workers, MySQL 8.0, Redis, MongoDB, Elasticsearch, Forum, Notes, Meilisearch, SMTP relay, Caddy\n- **iblai-dm-pro** -- Django web, ASGI, Celery worker/beat, PostgreSQL 16, Redis, Flowise AI\n- **iblai-web-frontend** -- Auth, Mentor AI, Skills AI single-page applications\n- **Monitoring** -- Prometheus, Grafana, AlertManager, metric exporters\n- **Nginx** reverse proxy\n\n## Workspace\n\nAll Terraform state, SSH keys, and project configuration are stored at:\n\n```\n~/.iblai-infra/projects/\u003cproject-name\u003e/\n```\n\n## Development\n\n### Running tests\n\n```bash\nuv sync --extra dev\nuv run pytest tests/ -v\n```\n\nWith coverage:\n\n```bash\nuv run pytest tests/ --cov=iblai_infra --cov-report=term-missing\n```\n\n### Project structure\n\n```\niblai-infra-ops/\n├── src/iblai_infra/\n│   ├── cli.py                  # Typer CLI commands\n│   ├── app.py                  # Application logic\n│   ├── models.py               # Pydantic models\n│   ├── ui.py                   # Rich terminal UI\n│   ├── env_provision.py        # .env → InfraConfig (provision-env)\n│   ├── env_setup.py            # .env → SetupConfig  (setup-env)\n│   ├── prompts/                # Interactive questionary prompts\n│   ├── providers/              # AWS provider (STS, EC2, S3, WAFv2)\n│   ├── features/               # Post-provision feature toggles (`iblai infra \u003cfeature\u003e \u003caction\u003e`)\n│   │   └── waf.py              #   `iblai infra waf` — enable / enable-env / disable / status\n│   ├── terraform/              # Terraform runner + templates\n│   │   └── templates/aws/      # single-server (incl. optional waf.tf), multi-server, call-server\n│   └── ansible/                # Ansible runner + templates\n│       └── templates/single-server/\n│           ├── playbook.yml             # interactive setup + setup-env\n│           ├── launch_playbook.yml      # AMI launch + launch-env\n│           ├── service_update_playbook.yml\n│           └── roles/                   # ansible roles (see playbook table)\n├── tests/                      # 648 tests, ~2s\n├── docs/                       # Architecture diagrams\n└── pyproject.toml\n```\n\n## License\n\nReleased under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiblai%2Finfra-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiblai%2Finfra-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiblai%2Finfra-cli/lists"}