Skip to content

How to update the azure.yaml schema

Rujun Chen edited this page Dec 3, 2024 · 1 revision

Background

When generating the project config file azure.yaml during azd init, AZD always associates the yaml schema by inserting the # yaml-language-server: $schema=XXX on the top line, so that user can leverage the ability provided by yaml language server for validation, auto-completion, and hover support.

We have been enhancing the java analyzer to support more resource types. Also, the customer is allowed to manually edit the azure.yaml file when the auto-generated one by azd init does not meet the requirement. So, the following sections will guide how to update the azure.yaml schema.

Concepts

The azure.yaml schema is defined under the azure-dev/schemas, divided by the main and alpha version. Currently we usually update the alpha version first.

Due to the azure.yaml is generated by serializing the struct ProjectConfig, the schema exactly follows the definition of the struct ProjectConfig.

Specifically, for the resources section of the azure.yaml file, it will inline the properties when marshaling into yaml, instead of being nested under a key. You can find more details in ResourceConfig. For example, the following shows the effect of marshaled yaml for the MySQL resource,

ResourceConfig {
    Type: MySQL
    Uses: svc1, svc2
    Props: {
        DatabaseName: testmysql
        AuthType: USER_ASSIGNED_MANAGED_IDENTITY
    }
}

---

mysql:
  type: db.mysql
  uses:
    - svc1
    - svc2
  databaseName: testmysql
  authType: USER_ASSIGNED_MANAGED_IDENTITY

The azure.yaml schema usually supports the data types: string, boolean, integer, array, object.

  • When the property is an enum, it should specify the possible candidate values.
    "authType": {
        "type": "string",
        "title": "Authentication Type",
        "description": "The type of authentication used for the Service Bus.",
        "enum": [
            "USER_ASSIGNED_MANAGED_IDENTITY",
            "CONNECTION_STRING"
        ]
    }
  • When the property is an array, it should specify the type of elements.
  • When the property is an struct, it should be specified as object.
    type CosmosDBProps struct {
        Containers   []CosmosDBContainerProps `yaml:"containers,omitempty"`
        DatabaseName string                   `yaml:"databaseName,omitempty"`
    }
    type CosmosDBContainerProps struct {
        ContainerName     string   `yaml:"containerName,omitempty"`
        PartitionKeyPaths []string `yaml:"partitionKeyPaths,omitempty"`
    }
    
    "containers": {
        "type": "array",
        "title": "Azure Cosmos database containers",
        "description": "A list of containers in the Azure CosmosDB database.",
        "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "containerName": {
                    "type": "string",
                    "title": "Container Name",
                    "description": "The name of the container."
                },
                "partitionKeyPaths": {
                    "type": "array",
                    "title": "Partition Key Paths",
                    "description": "A list of partition key paths for the container.",
                    "items": {
                        "type": "string"
                    }
                }
            }
        }
    }
  • When the schema allows extra fields except the explicitly defined properties, should use additionalProperties.
  • When need some restricts for the schema, use the allOf or anyOf on which specify the conditional expression.

Example

Let's say that we have the following resource declaration for cosmos DB.

type CosmosDBProps struct {
	Containers   []CosmosDBContainerProps `yaml:"containers,omitempty"`
	DatabaseName string                   `yaml:"databaseName,omitempty"`
}

type CosmosDBContainerProps struct {
	ContainerName     string   `yaml:"containerName,omitempty"`
	PartitionKeyPaths []string `yaml:"partitionKeyPaths,omitempty"`
}

Based on the above explanation, the schema should look like this.

"cosmosDbResource": {
    "type": "object",  # because CosmosDBProps  is struct
    "additionalProperties": false,  # not allow other extra fields
    "properties": {
        "databaseName": {  # DatabaseName property
            "type": "string",
            "title": "The name of Azure Cosmos DB resource",
            "description": "The name of Azure resource."
        },
        "containers": {  # Containers property
            "type": "array",  # it's an array
            "title": "Azure Cosmos database containers",
            "description": "A list of containers in the Azure CosmosDB database.",
            "items": {
                "type": "object",  # the element of the array is a struct, so object here
                "additionalProperties": false,  # not allow other extra fields
                "properties": {
                    "containerName": {  # ContainerName property
                        "type": "string",
                        "title": "Container Name",
                        "description": "The name of the container."
                    },
                    "partitionKeyPaths": {  # PartitionKeyPaths property
                        "type": "array",  # it's an array
                        "title": "Partition Key Paths",
                        "description": "A list of partition key paths for the container.",
                        "items": {
                            "type": "string"  # the array element is string type
                        }
                    }
                }
            }
        }
    }
}

Validation

The # yaml-language-server: $schema=XXX can refer to the relative path, so you can modify the azure.yaml.json locally and then refer to it in the azure.yaml to verify if it's correct. If all normal, it will not show any errors with red underline. Else, it will show any detected errors. For example, image

image