# apiops
`apiops` is a CLI tool for Azure API Management (APIM) configuration-as-code. Extract your APIM service configuration to local artifact files, publish those artifacts back to Azure, and scaffold CI/CD pipelines — all from the command line.
| | |
|---|---|
| **Source code** | [github.com/Azure/apiops-cli](https://github.com/Azure/apiops-cli) |
| **Issues** | [GitHub Issues](https://github.com/Azure/apiops-cli/issues) |
| **Architecture** | [docs/architecture.md](./docs/architecture.md) |
## Getting started
**Prerequisites:** An Azure subscription with an existing APIM resource, and Node.js ≥ 22.
```bash
npm install -g @azure-tools/apiops-cli
```
## Authentication
`apiops` uses [`@azure/identity`](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity) `DefaultAzureCredential` for authentication.
### Generated GitHub Actions workflows (`apiops init`)
Workflows scaffolded by `apiops init` authenticate via **OIDC (workload identity federation)** — no client secret is stored or needed. You do need an Azure AD (Microsoft Entra ID) application with federated credentials for your GitHub repository. `apiops init` generates two ways to set it up:
- **Guided setup with GitHub Copilot:** `apiops init` creates `.github/prompts/apiops-setup-workflow-identity.prompt.md`, a [prompt file](docs/guides/prompt-files.md) for [GitHub Copilot in VS Code](https://code.visualstudio.com/docs/copilot/overview). Open the repository in VS Code, open Copilot Chat (<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>I</kbd>), select **Agent** mode, type `/apiops-setup-workflow-identity`, and press Enter. Copilot then walks you through creating the app registration, federated credentials, and repository secrets step by step.
- **Manual setup:** follow the instructions in the generated `APIOPS-WORKFLOW-IDENTITY-SETUP.md`.
Required repository secrets: `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`
### Local CLI / other CI systems
When running `apiops` outside a GitHub Actions OIDC context you can supply credentials explicitly:
- **Environment variables:** `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID`
- **CLI flags:** `--client-id`, `--client-secret`, `--tenant-id`, `--subscription-id`
- **Managed Identity / Workload Identity:** Supported automatically via `DefaultAzureCredential` when running on Azure-hosted infrastructure (VMs, App Service, etc.) or in Azure Pipelines with workload identity federation configured.
## Commands
### `apiops extract`
Extract APIM service configuration to local artifact files.
| Flag | Default | Description |
|------|---------|-------------|
| `--resource-group <rg>` | *(required)* | Azure resource group |
| `--service-name <name>` | *(required)* | APIM service name |
| `--output <dir>` | `./apim-artifacts` | Output directory |
| `--filter <path>` | | Extract matching resources; supports wildcards and `!` exclusions |
| `--no-transitive` | | Skip transitive dependencies |
Filter files support exact names, wildcards, quoted `!`-prefixed exclusions, and the singleton `policies` key. See the [extract command filter reference](docs/commands/extract.md#filter-configuration) for all 17 filter keys and the [filtering guide](docs/guides/filtering-resources.md) for detailed examples.
```bash
apiops extract --help
# Basic extraction to the default output directory
apiops extract \
--resource-group <rg> \
--service-name <name> \
--output ./apim-artifacts
# Extract a filtered subset of resources
apiops extract \
--resource-group <rg> \
--service-name <name> \
--filter ./filter.yaml
# Authenticate explicitly with a service principal
apiops extract \
--resource-group <rg> \
--service-name <name> \
--client-id $AZURE_CLIENT_ID \
--client-secret $AZURE_CLIENT_SECRET \
--tenant-id $AZURE_TENANT_ID \
--subscription-id $AZURE_SUBSCRIPTION_ID
```
### `apiops publish`
Publish local artifact files to an Azure APIM service.
| Flag | Default | Description |
|------|---------|-------------|
| `--resource-group <rg>` | *(required)* | Azure resource group |
| `--service-name <name>` | *(required)* | APIM service name |
| `--source <dir>` | `./apim-artifacts` | Source artifacts directory |
| `--overrides <path>` | | Path to overrides file |
| `--filter <path>` | | Filter YAML file (same format as `extract`) |
| `--no-transitive` | | Publish only filter matches, without referenced dependencies |
| `--commit-id <sha>` | | Git commit SHA for incremental publish |
| `--dry-run` | | Preview changes without applying |
| `--delete-unmatched` | | Delete resources absent from artifacts, or removed by an incremental commit (mutually exclusive with `--filter`) |
```bash
apiops publish --help
# Preview changes without applying them
apiops publish \
--resource-group <rg> \
--service-name <name> \
--dry-run
# Publish and remove resources not present in the local artifacts
apiops publish \
--resource-group <rg> \
--service-name <name> \
--delete-unmatched
# Incremental publish for a specific commit
apiops publish \
--resource-group <rg> \
--service-name <name> \
--commit-id <sha>
# Publish a filtered subset; transitive dependencies are included by default
apiops publish \
--resource-group <rg> \
--service-name <name> \
--source ./apim-artifacts \
--filter ./filter.yaml
```
The publish filter uses the same YAML file and matching rules as `apiops extract --filter`.
Referenced named values, backends (including backend pool members), policy fragments, and version
sets are included automatically. Add `--no-transitive` to publish only the exact filter matches.
### `apiops init`
Scaffold a new APIM artifacts repository with CI/CD pipelines.
| Flag | Description |
|------|-------------|
| `--cli-package <path>` | Path to a local `.tgz` tarball |
| `--ci <platform>` | `github-actions` or `azure-devops` |
| `--artifact-dir <dir>` | Artifact directory path (default: `./apim-artifacts`) |
| `--environments <list>` | Comma-separated environments (e.g. `dev,prod`) |
| `--non-interactive` | Skip all prompts |
| `--force` | Overwrite existing files |
```bash
apiops init --help
apiops init \
--ci github-actions \
--environments dev,prod
```
### `apiops apic`
Back up and restore Azure API Center (`Microsoft.ApiCenter`) services. This command group is separate from the Azure API Management `extract` and `publish` commands.
| Command | Description |
|---------|-------------|
| `apiops apic extract` | Extract API Center configuration and API definition specifications to `./apic-artifacts` |
| `apiops apic publish` | Publish API Center artifacts and specifications to an API Center service |
```bash
# Back up an API Center service
apiops apic extract \
--resource-group <rg> \
--service-name <name>
# Preview a restore without applying changes
apiops apic publish \
--resource-group <rg> \
--service-name <name> \
--dry-run
```
See the [`apiops apic` command reference](docs/commands/apic.md) for flags, workspace extraction, and specification options.
## Global options
| Option | Default | Description |
|--------|---------|-------------|
| `--subscription-id <id>` | `AZURE_SUBSCRIPTION_ID` env var | Azure subscription ID |
| `--cloud <name>` | `public` | `public`, `china`, `usgov`, `germany` |
| `--log-level <level>` | `info` | `debug`, `info`, `warn`, `error` |
| `--format <type>` | `text` | `text` or `json` |
| `--client-id <id>` | `AZURE_CLIENT_ID` env var | Service principal client ID |
| `--client-secret <secret>` | `AZURE_CLIENT_SECRET` env var | Service principal secret |
| `--tenant-id <id>` | `AZURE_TENANT_ID` env var | Azure AD tenant ID |
## Guides
- [Environment overrides](docs/guides/environment-overrides.md) — per-environment property overrides (backend URLs, secrets, credentials)
- [Multi-environment publish to a single APIM instance](docs/guides/multi-environment-shared-apim.md) — publish dev/qa/prod to a shared APIM using name prefixes
## Changelog
See [CHANGELOG.md](./CHANGELOG.md) for release notes and the list of changes in each version. To see what has changed
since the version you have installed, compare tags on GitHub
(e.g. [`v0.2.1-alpha.0...main`](https://github.com/Azure/apiops-cli/compare/v0.2.1-alpha.0...main)).
## Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to build, test, debug, and submit changes.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Security
Please do not report security vulnerabilities through public GitHub issues. Instead, please follow the instructions in
our [SECURITY.md](./SECURITY.md).
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.
## License
[MIT](./LICENSE.md)