# Azure CLI reference and conceptual content guidelines
## General guidelines
General guidelines apply to both reference and conceptual content.
- Develop and test all code blocks in both a Bash and PowerShell environment. When commands have syntax differences between environments, create one example for Bash and another for PowerShell. For copyability, use different code blocks with a notation. Here is an example:
```azurecli-interactive
az command –-p1 written-for-Bash
```
```azurecli-interactive
# This same command can be run in PowerShell, but with a slight syntax difference
az command –-p1 written-for-PowerShell-showing-quoting-differences
```
For more information on syntax differences between Bash and PowerShell, see these articles:
- [Quoting issues with PowerShell](https://github.com/Azure/azure-cli/blob/dev/doc/quoting-issues-with-powershell.md)
- [Use quotation marks in Azure CLI parameters](https://learn.microsoft.com/cli/azure/use-cli-effectively#use-quotation-marks-in-parameters)
- Compare syntax of CMD, PowerShell and Bash in [Query command output using JMESPath](https://learn.microsoft.com/cli/azure/query-azure-cli?tabs=concepts%2Cbash)
- [Error handling for the Azure CLI in PowerShell](https://learn.microsoft.com/cli/azure/use-cli-effectively#use-quotation-marks-in-parameters#error-handling-for-azure-cli-in-powershell)
**Don't replicate code blocks for line break differences.** The new Azure CLI code block Copy button removes Bash and PowerShell line break characters. Only replicate code blocks for syntax differences.
## Conceptual content
### Minimum content
Minimum conceptual content for the Azure CLI is one conceptual article for every command group and subgroup that creates or adds a billable Azure resource. For example:
* The `az vm` group [create, list, auto-shutdown...] contains a command that creates a billable Azure resource. This command group must have at least one conceptual article.
* The `az vm aem` subgroup [delete, set, verify] helps to manage Azure resources, but it doesn't create a billable Azure service. A conceptual article is encouraged but not required.
Easily meet the conceptual content requirement by using one of these solutions:
* Copy an existing Azure portal article replacing Azure portal instructions with Azure CLI reference commands. After autogenerated reference content is published, use Azure AI studio to significantly shorten your development time. Using a conceptual tab for Portal, Azure CLI, and if applicable, Azure PowerShell, works well in this solution.
* When there aren't enough reference commands to replicate an entire Azure portal article, add a conceptual tab to an existing H2.
* Not preferred: Add an H2 to the bottom of an existing portal article with links to related Azure CLI reference content. This solution doesn't qualify as "conceptual content", but it's a start when you're pressed for time.
For code blocks containing only Azure CLI reference commands, use the **\```azurecli** or **\```azurecli-interactive** code block tags. These tags cause proper color formatting and the Copy button removes line breaks.
See [Azure CLI article guidelines](https://review.learn.microsoft.com/help/contribute/conventions-azure-cli) in the Contributor’s Guide for more detail. Review the [Azure CLI editor’s checklist](https://review.learn.microsoft.com/help/contribute/checklist-azure-cli?branch=main) before publishing conceptual docs containing Azure CLI content.
### Output code blocks
Provide **\```output** code blocks in JSON format for reference commands that create, update or add a resource. When developing scripts, customers often combine two or more create, read, update and delete operations. With no documentation about the format of the returned object, customers have no choice but to run each command one by one and analyze the response.
## Reference content
One purpose of autogenerated reference content is to decrease the number of Quickstarts and allow Microsoft content writers to use their abilities to teach a cross-service scenario or a job to be done. We aren't trying to eliminate Quickstarts. We do want the Azure CLI autogenerated content to be Best in Class!
Follow these guidelines when creating examples for in-line help, and consequently, for autogenerated reference content. Jump to the [reference checklists](#reference-checklists) for a quick review before publishing new reference content.
### TOC – Azure CLI
The [reference TOC in MicrosoftDocs/azure-docs-cli](https://github.com/MicrosoftDocs/azure-docs-cli/blob/main/latest/docs-ref-autogen/TOC.yml) is controlled by two files:
- Core references are mapped in [azure-cli/src/azure-cli/service_name.json](https://github.com/Azure/azure-cli/blob/dev/src/azure-cli/service_name.json).
- Extension references are mapped in [azure-cli-extensions/src/service_name.json](https://github.com/Azure/azure-cli-extensions/blob/main/src/service_name.json).
**Each time a reference TOC top-level name is changed, a redirect has to be created.** If you aren’t sure what service or product to place a new reference group in, contact Damien Caro (dcar@microsoft.com) or Delora Bradish (dbradish@microsoft.com). Follow these guidelines:
- Placement in the reference TOC should reflect _customer_ search terms and patterns.
- The reference TOC is organized by Azure service or product _without_ the “Azure” or “Microsoft” prefix.
- The reference TOC organization is intended to help our customers answer the question: “What Azure CLI commands are available to me when working with [an Azure product]?”. Therefore, not every Azure CLI reference group has its own top-level TOC node. The [Reference index A-Z](https://learn.microsoft.com/cli/azure/reference-index) already provides a list of reference groups.
### TOC – Azure service
Each Azure service that has supporting Azure CLI reference content needs a link to the autogenerated reference docs in their TOC. The `displayName` property is optional. Here is a `TOC.yml` example for Cosmos DB:
```yml
- name: Reference
items:
- name: Azure CLI
href: /cli/azure/service-page/database%20for%20cosmos%20db
displayName: az cosmosdb, cassandra, dts, gremlin, mongocluster
- name: Azure PowerShell
- href: /powershell/module/az.cosmosdb/#cosmos-db
```
### Descriptions
There are two Python properties for descriptions: **short-summary** and **long-summary**.
#### Short summary
In autogenerated reference content, short summaries show in reference tables. For an example, see the tables in [Reference Index A-Z](https://learn.microsoft.com/cli/azure/reference-index?) and [az account](https://learn.microsoft.com/cli/azure/account).
Short summaries also appear as the first sentence under an H1. For [az account](https://learn.microsoft.com/cli/azure/account) the short summary is "Manage Azure subscription information".
- The intent of the short summary is to provide information that cannot be immediately deduced from the reference command name. Ask yourself, "How is this description actually helpful?"
- The short summary is _a single sentence_ that describes the reference command.
- The short summary shouldn't exceed 200 characters.
- Write the short summary in active voice within _a single sentence_ that contains a noun, a verb and a direct object. Active voice has an understood "you".
#### Long summary
The long summary appears directly under the short summary sentence. Long summaries are rendered in paragraph format.
- The intent of the long summary is to provide additional tips and techniques to our customers.
- The long summary indicates what users can expect when running the command.
- The long summary is a paragraph but shouldn't exceed 2000 characters.
- Include additional information about what the command does and what customers should know. For example, “…The output includes credentials that you must protect…”
- The long summary property isn't the place for Quickstart or How-to guidance. **Keep the long summary focused on information _about_ the command, not how to use it.**
- Embed URLs in Python long summary source code judiciously. There isn't an automated process to fix broken links in Python files. For Python source code that becomes autogenerated reference content, follow these guidelines:
- Write the link with Markdown syntax. Example: \[article name](https://learn.microsoft.com/link). This is understandable within in-line help, and provides a formatted link in autogenerated content.
- Remove locale, such as `/en-us/`, from all links.
- Remove unnecessary monikers, such as `?view=azure-cli-latest`, from all links.
- Add `&preserve-view=true` to any URL that needs a moniker to support versioning. Example: `?view=azure-ml-py&preserve-view=true`.
**Failure to remove locale or `?view=azure-cli-latest` from links causes a build warning in MicrosoftDocs/azure-docs-cli.**
For an example of a long summary, see [az acr helm repo add](https://learn.microsoft.com/cli/azure/acr/helm/repo?#az-acr-helm-repo-add). The Python source code for `az acr helm repo add` is found in [/acr/_help.py](https://github.com/azure/azure-cli/blob/dev/src/azure-cli/azure/cli/command_modules/acr/_help.py):
```python
helps['acr helm repo add'] = """
type: command
short-summary: Add a helm chart repository from an Azure Container Registry through the Helm CLI.
long-summary: Helm must be installed on your machine.
examples:
- name: Add a helm chart repository from an Azure Container Registry to manage helm charts.
text: >
az acr helm repo add -n MyRegistry
"""
```
For more information on `_help.py` see [Azure CLI Help System](https://github.com/Azure/azure-cli/blob/dev/doc/authoring_help.md).
### Examples
Examples given in the reference documentation provide customers with information on how to use a given command and associated parameters. Examples are usually created in `_help.py` and published in [MicrosoftDocs/azure-docs-cli/latest/docs-ref-autogen](https://github.com/MicrosoftDocs/azure-docs-cli/tree/main/latest/docs-ref-autogen).
- Don’t assume a level of knowledge. Reference content is translated into many languages and customers have diverse technical skills. What is intuitive for one customer, is a frustrating roadblock for another.
- Give special attention to `az ... create` command examples. These are often revenue-generating and Microsoft loses the potential for a billable resource when a `create` or `add` command fails.
- Provide at least **two examples** for each reference command.
- One example should be the most common use case for the command.
- The second example should be a real-life example that includes an _advanced_ combination of filters.
- **Provide at least one example for every parameter.** A single example can use multiple parameters, but a parameter that doesn't appear within an example code block often shows no usage statistics in Azure CLI reporting.
- Bash examples should be formatted for readability using a line continuation character of a backslash (`\`). PowerShell examples should use a backtick for line continuation. ([Splatting](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_splatting) does not work with Azure CLI commands because CLI parameters use two dashes, `--`, not one, `-`). Your Python source code will look similar to this:
```python
helps['vm create'] = """
type: command
short-summary: Create a virtual machine.
examples:
- name: Simple example
- text: az vm create -name MyVm -group MyResourceGroup --image UbuntuServer
- name: Create a Debian11 VM with SSH key authentication and a public DNS entry, located on an existing virtual network and availability set.
text: |
az vm create --param1 MyParam1Value \\
--param2 MyParam2Value \\
--param3 MyParam3Value \\
- name: next example
text: |
```
- Create diverse, not repetitive examples.
```azurecli
# example
az vm create -n MyVm -g MyResourceGroup --image UbuntuSever
# repetitive
az vm create -n MyVm -g MyResourceGroup --image Debian11
# helpful and readable
az vm create --group MyResourceGroup \
--name MyVm \
--image /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.Compute/galleries/myGallery/images/myImage
# diverse and readable
az vm create --name MyVm \
--group MyResourceGroup \
--image Debian11 \
--vnet-name MyVnet
--subnet subnet1 \
--availability-set MyAvailabilitySet \
--public-ip-address-dns-name MyUniqueDnsName \
--ssh-key-values @key-file
```
- Not all examples can be shell agnostic due to the quoting differences between Bash and PowerShell. For examples that only run in Bash, provide a second example for PowerShell. If you are testing Bash scripts in PowerShell and getting errors, see [General guidelines](#general-guidelines) for links with information on quoting and error handling differences.
### Parameters used in examples
- Use Global Parameters in examples such as `--output` and `--query`, when needed for clarity. Showing customers how to store a value in a variable from a get/list operation is especially helpful when the `--query` syntax required isn't intuitive. Frustrations with `--query` are seen in many customer feedback forums. Let's work to change this!
- Avoid parameter abbreviations in examples. This requires the customer to look up abbreviations. Reference examples strive for clarity and readability, not reduced keystrokes.
- Avoid: `az vm create -h`
- Good: `az vm create --help`
- Provide real-world parameter values. Helpful examples don't expect the customer to figure out an actual value or format for the command.
- Don't use HTML tags (`<>`) around parameter values in Python source code that becomes autogenerated reference content. In `az someCommand --group --nextParameter ` both parameter values will render as a blank space. _In conceptual Markdown content only_, the use of `<>` within a code block is okay.
- Provide examples for complex parameters or those that require a particular format.
- Provide _additional examples_ for parameter groups. For example `az vm create --help` shows a group of **Authentication arguments**. Provide examples on how your parameter groups are used separately or together.
### Parameter help
The parameter help, usually located in `_params.py`, is an excellent opportunity to provide additional information to customers and help them avoid formatting errors! Think of the parameter help as a blank canvas and throw on it all the tips and technique paint you can. Parameter help is different than the command `short/long-summary` properties. To start, there is only one property and it is located in the `c.argument` line.
Here is example source code:
```python
c.argument('vmss', help='Name or ID of an existing virtual machine scale set that the virtual machine should be assigned to. None by default.')
c.argument('nsg', help='The name to use when creating a new Network Security Group (default) or referencing an existing one. Can also reference an existing NSG by ID or specify "" for none (\'""\' in Azure CLI using PowerShell or --% operator).', arg_group='Network')
```
> [!NOTE]
> For instructions on creating and formatting the `_params.py` file, see [Command Guidelines](https://github.com/Azure/azure-cli/blob/dev/doc/command_guidelines.md).
- Many of our GitHub issues and negative HaTS results come from misunderstood parameter usage or formats. You may feel you are "over explaining" but take time to build out the parameter help especially for `az ... create` or `az ... add` commands.
- Focus parameter help on information _about_ the parameter, not a Quickstart on how to _use_ the parameter.
- When possible, tell customers how to find the value for a parameter. Example: "Use `az account list-locations` to find available location values."
- Include the following information in the `help=` property for each parameter when applicable:
- **Description**. Be succinct but provide as much helpful information as you know.
- **Accepted values**.
- **Azure CLI default value**. Always provide default value information for true/false parameters.
- **Azure service default value**.
- Information about **parameter pairs**. Examples:
- "If p1 is used, you must also supply p2."
- "If p1 is used, you don't need to supply p2."
- "If p1 is used, you cannot supply p2."
- "P1 is optional if p2 has been provided."
- **Example value**.
- Give individual parameter examples in the parameter help. Don't rely on code block examples to provide all the information needed for parameter format options.
- Don't repeat exact values in parameter help that have already been provided in example code blocks. Redundancy doesn't add value.
- Don't expect the customer to know Bash, or to intuitively figure out parameter formats.
- If a parameter accepts multiple values, provide a multi-value string example. Is it comma delimited? Space delimited? Are there quotes around each value, the entire string, or no quotes at all?
- If a parameter "can be passed in as file or string", how would the contents of the file be formatted? What information is acceptable? What would a multi-value string look like?
- Create parameter groups for clarity. When there are a significant number of parameters for a single reference command, it is confusing for customers to understand what parameters are related. See the [az vm create](https://learn.microsoft.com/cli/azure/vm#az-vm-create) reference documentation for an example of a command with many parameters. Enter `az vm create --help` in a terminal and notice the groupings provided in the in-line help:
- Authentication Arguments
- Dedicated Host Arguments
- Managed Service Identity Arguments
- Marketplace Image Plan Arguments
- Monitor Arguments
- Network Arguments
- Storage Arguments
- Global Arguments
For example Python source code showing parameter groups, see [/vm/_params.py](https://github.com/Azure/azure-cli/blob/dev/src/azure-cli/azure/cli/command_modules/vm/_params.py).
## Reference checklists
Use these checklists for a quick review before publishing new reference content.
### TOC checklist
- Information has been added to `service-mapping.json`.
- A link has been added to **Reference** TOC node of the Azure service.
### Description checklist
- The `short-summary` is a single complete sentence in active voice.
- The `short-summary` provides useful information and isn't repetitive.
- The `long-summary` gives useful tips and tells customers what to expect when they run the command.
- Embedded URLs are in Markdown format.
- Embedded URLs don't contain locale or unnecessary monikers.
### Example checklist
- Examples have been tested in both Bash and PowerShell environments.
- At least two examples have been given for each command.
- Bash line continuation characters have been used for improved readability.
- HTML tags have not been used in examples.
### Parameter checklist
- Every parameter is included in at least one example.
- Get/list operation examples have been provided that show the use of the `--query` parameter.
- Parameter accepted values, default values (including for true/false), and example values have been created.
- Additional examples have been provided for parameter pairs and groups.