-
Notifications
You must be signed in to change notification settings - Fork 1
GitHub Copilot Agent Mode
This doc is to write down the testing result of using GitHub Copilot Agent Mode, to analyze a Java project to generate the azure.yaml
which describes the metadata of the project.
This doc will use the following target scenarios:
- Single project with Azure dependency
- Single project with non-Azure dependency (like MySQL or Kafka)
- Multiple projects with parent pom, with Azure dependency, and a project depends on other projects
- Multiple projects without parent pom, with Azure dependency, and a project depends on other projects
Scenario | Testing Result | Used Project |
---|---|---|
Single project with Azure dependency | ✅ can detect resources, apps ❗️not good at binding envs | Java App Using Cosmos DB |
Single project with non-Azure dependency (Kafka) | ✅ can detect resources, apps ❗️not good at binding envs | Java App Using Kafka |
Single project with non-Azure dependency (MySQL) | ✅ can detect resources, apps | Java App Using Kafka |
Multiple projects with parent pom, with Azure dependency, and a project depends on other projects | ❌ can detect resources, apps, and relationships | PetClinic Microservices |
Multiple projects without parent pom, with Azure dependency, and a project depends on other projects | ✅ can detect resources, apps, but not relationships | Java backend + Vue Frontend |
- VS Code Insiders (Version: 1.97.0-insider), and GHCP Edit Agent Mode with Claude 3.5 Sonnet.
You are an expert on Java and Azure. I am asking you to analyze this project and generate an azure.yaml. This azure.yaml will describe this project.
The metadata includes:
- What language is this project written in?
- What services are used in this project (such as MySQL that can run on Azure, Azure services like Azure Cosmos DB or Azure Service Bus)?
- Which hosting platform to deploy this project (like Azure Container Apps, App Service)?
- Dependency information between the apps and the resources, like which app uses which resource, or which app is going to call other apps. The relationship should be defined under `uses`.
- Whether the application is a web application, if so, which port should be used and if not then it should not have any port specified.
- Which environment variables to set to the application that indicates the binding information between the app and the resource? If a Spring Cloud Azure library has been found, define the environment variables that is used in the Spring Cloud Azure library.
- If database resources are found being used in the application, please figure out the databases/tables/containers should be defined.
- If messaging resources like Service Bus and Event Hubs are found being used in the application, please figure out the topic/queue/subscription names used.
- There could be several special projects, like Spring Eureka Server, Spring Config Server, Spring Boot Admin, Spring Cloud Gateway, etc. Please figure out the special projects and define the metadata for them.
In this case, I want to deploy this project to Azure Container Apps together with resources that can be provisioned on Azure. Please ignore monitoring services for now.
An example of the azure.yaml would be like:
"""
name:
sample-app
services:
web:
project: ./web/react-fluent
dist: dist
language: js
api:
project: ./api
language: java
resources:
cosmos:
type: azure.cosmosdb
eventhubs:
type: azure.eventhubs
servicebus:
type: azure.servicebus
topics:
- name: topic1
subscription:
- name: sub1
queues:
- name: queue1
mysql:
type: azure.mysql
redis:
type: azure.redis
web:
type: azure.containerapps
uses:
- cosmos-db
- eventhubs
- servicebus
- mysql
- redis
"""
The schema of the `azure.yaml` is:
"""
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/alpha/azure.yaml.json",
"type": "object",
"required": [
"name"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 2,
"title": "Name of the application"
},
"resourceGroup": {
"type": "string",
"minLength": 3,
"maxLength": 64,
"title": "Name of the Azure resource group",
"description": "When specified will override the resource group name used for infrastructure provisioning. Supports environment variable substitution."
},
"metadata": {
"type": "object",
"properties": {
"template": {
"type": "string",
"title": "Identifier of the template from which the application was created. Optional.",
"examples": [
"[email protected]"
]
}
}
},
"infra": {
"type": "object",
"title": "The infrastructure configuration used for the application",
"description": "Optional. Provides additional configuration for Azure infrastructure provisioning.",
"additionalProperties": false,
"required": [
"provider"
],
"properties": {
"provider": {
"type": "string",
"title": "Type of infrastructure provisioning provider",
"description": "Optional. The infrastructure provisioning provider used to provision the Azure resources for the application. (Default: bicep)",
"enum": [
"bicep",
"terraform"
]
},
"path": {
"type": "string",
"title": "Path to the location that contains Azure provisioning templates",
"description": "Optional. The relative folder path to the Azure provisioning templates for the specified provider. (Default: infra)"
},
"module": {
"type": "string",
"title": "Name of the default module within the Azure provisioning templates",
"description": "Optional. The name of the Azure provisioning module used when provisioning resources. (Default: main)"
},
"deploymentStacks": {
"$ref": "#/definitions/deploymentStacksConfig"
}
},
"allOf": [
{
"if": {
"not": {
"properties": {
"provider": {
"const": "bicep"
}
}
}
},
"then": {
"properties": {
"deploymentStacks": false
}
}
}
]
},
"services": {
"type": "object",
"title": "Definition of services that comprise the application",
"minProperties": 1,
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"required": [
"host"
],
"properties": {
"resourceGroup": {
"type": "string",
"title": "Name of the Azure resource group that contains the resource",
"description": "By default, the CLI will discover the Azure resource within the default resource group. When specified, the CLI will instead find the Azure resource within the specified resource group. Supports environment variable substitution."
},
"resourceName": {
"type": "string",
"title": "Name of the Azure resource that implements the service",
"description": "By default, the CLI will discover the Azure resource with tag 'azd-service-name' set to the current service's name. When specified, the CLI will instead find the Azure resource with the matching resource name. Supports environment variable substitution."
},
"project": {
"type": "string",
"title": "Path to the service source code directory"
},
"image": {
"type": "string",
"title": "Optional. The source image to be used for the container image instead of building from source. Supports environment variable substitution.",
"description": "If omitted, container image will be built from source specified in the 'project' property. Setting both 'project' and 'image' is invalid."
},
"host": {
"type": "string",
"title": "Required. The type of Azure resource used for service implementation",
"description": "The Azure service that will be used as the target for deployment operations for the service.",
"enum": [
"appservice",
"containerapp",
"function",
"springapp",
"staticwebapp",
"aks",
"ai.endpoint"
]
},
"language": {
"type": "string",
"title": "Service implementation language",
"enum": [
"dotnet",
"csharp",
"fsharp",
"py",
"python",
"js",
"ts",
"java"
]
},
"module": {
"type": "string",
"title": "(DEPRECATED) Path of the infrastructure module used to deploy the service relative to the root infra folder",
"description": "If omitted, the CLI will assume the module name is the same as the service name. This property will be deprecated in a future release."
},
"dist": {
"type": "string",
"title": "Relative path to service deployment artifacts"
},
"docker": {
"$ref": "#/definitions/docker"
},
"k8s": {
"$ref": "#/definitions/aksOptions"
},
"config": {
"type": "object",
"additionalProperties": true
},
"hooks": {
"type": "object",
"title": "Service level hooks",
"description": "Hooks should match `service` event names prefixed with `pre` or `post` depending on when the script should execute. When specifying paths they should be relative to the service path.",
"additionalProperties": false,
"properties": {
"predeploy": {
"title": "pre deploy hook",
"description": "Runs before the service is deployed to Azure",
"$ref": "#/definitions/hooks"
},
"postdeploy": {
"title": "post deploy hook",
"description": "Runs after the service is deployed to Azure",
"$ref": "#/definitions/hooks"
},
"prerestore": {
"title": "pre restore hook",
"description": "Runs before the service dependencies are restored",
"$ref": "#/definitions/hooks"
},
"postrestore": {
"title": "post restore hook",
"description": "Runs after the service dependencies are restored",
"$ref": "#/definitions/hooks"
},
"prebuild": {
"title": "pre build hook",
"description": "Runs before the service is built",
"$ref": "#/definitions/hooks"
},
"postbuild": {
"title": "post build hook",
"description": "Runs after the service is built",
"$ref": "#/definitions/hooks"
},
"prepackage": {
"title": "pre package hook",
"description": "Runs before the service is deployment package is created",
"$ref": "#/definitions/hooks"
},
"postpackage": {
"title": "post package hook",
"description": "Runs after the service is deployment package is created",
"$ref": "#/definitions/hooks"
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"host": {
"const": "containerapp"
}
}
},
"then": {
"anyOf": [
{
"required": [
"image"
],
"properties": {
"language": false
},
"not": {
"required": [
"project"
]
}
},
{
"required": [
"project"
],
"not": {
"required": [
"image"
]
}
}
]
}
},
{
"if": {
"not": {
"properties": {
"host": {
"const": "containerapp"
}
}
}
},
"then": {
"properties": {
"image": false
}
}
},
{
"if": {
"not": {
"properties": {
"host": {
"enum": [
"containerapp",
"aks",
"ai.endpoint"
]
}
}
}
},
"then": {
"required": [
"project",
"language"
],
"properties": {
"docker": false
}
}
},
{
"if": {
"properties": {
"host": {
"const": "ai.endpoint"
}
}
},
"then": {
"required": [
"config"
],
"properties": {
"config": {
"$ref": "#/definitions/aiEndpointConfig",
"title": "The Azure AI endpoint configuration.",
"description": "Required. Provides additional configuration for Azure AI online endpoint deployment."
}
}
}
},
{
"if": {
"not": {
"properties": {
"host": {
"enum": [
"aks"
]
}
}
}
},
"then": {
"properties": {
"k8s": false
}
}
},
{
"if": {
"properties": {
"language": {
"const": "java"
}
}
},
"then": {
"properties": {
"dist": {
"type": "string",
"description": "Optional. The path to the directory containing a single Java archive file (.jar/.ear/.war), or the path to the specific Java archive file to be included in the deployment artifact. If omitted, the CLI will detect the output directory based on the build system in-use. For maven, the default output directory 'target' is assumed."
}
}
}
},
{
"properties": {
"dist": {
"type": "string",
"description": "Optional. The CLI will use files under this path to create the deployment artifact (ZIP file). If omitted, all files under service project directory will be included."
}
}
}
]
}
},
"resources": {
"type": "object",
"additionalProperties": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"type": "string",
"title": "Type of resource",
"description": "The type of resource to be created. (Example: db.postgres)",
"enum": [
"db.postgres",
"db.mysql",
"db.redis",
"db.mongo",
"ai.openai.model",
"host.containerapp",
"messaging.eventhubs",
"messaging.servicebus",
"storage"
]
},
"uses": {
"type": "array",
"title": "Other resources that this resource uses",
"items": {
"type": "string"
},
"uniqueItems": true
}
},
"allOf": [
{ "if": { "properties": { "type": { "const": "host.containerapp" }}}, "then": { "$ref": "#/definitions/containerAppResource" } },
{ "if": { "properties": { "type": { "const": "ai.openai.model" }}}, "then": { "$ref": "#/definitions/aiModelResource" } },
{ "if": { "properties": { "type": { "const": "db.postgres" }}}, "then": { "$ref": "#/definitions/resource"} },
{ "if": { "properties": { "type": { "const": "db.mysql" }}}, "then": { "$ref": "#/definitions/resource"} },
{ "if": { "properties": { "type": { "const": "db.redis" }}}, "then": { "$ref": "#/definitions/resource"} },
{ "if": { "properties": { "type": { "const": "db.mongo" }}}, "then": { "$ref": "#/definitions/resource"} },
{ "if": { "properties": { "type": { "const": "messaging.eventhubs" }}}, "then": { "$ref": "#/definitions/eventHubsResource" } },
{ "if": { "properties": { "type": { "const": "messaging.servicebus" }}}, "then": { "$ref": "#/definitions/serviceBusResource" } },
{ "if": { "properties": { "type": { "const": "storage" }}}, "then": { "$ref": "#/definitions/storageAccountResource"} }
]
}
},
"pipeline": {
"type": "object",
"title": "Definition of continuous integration pipeline",
"properties": {
"provider": {
"type": "string",
"title": "Type of pipeline provider",
"description": "Optional. The pipeline provider to be used for continuous integration. (Default: github)",
"enum": [
"github",
"azdo"
]
}
}
},
"hooks": {
"type": "object",
"title": "Command level hooks",
"description": "Hooks should match `azd` command names prefixed with `pre` or `post` depending on when the script should execute. When specifying paths they should be relative to the project path.",
"additionalProperties": false,
"properties": {
"preprovision": {
"title": "pre provision hook",
"description": "Runs before the `provision` command",
"$ref": "#/definitions/hooks"
},
"postprovision": {
"title": "post provision hook",
"description": "Runs after the `provision` command",
"$ref": "#/definitions/hooks"
},
"preinfracreate": {
"title": "pre infra create hook",
"description": "Runs before the `infra create` or `provision` commands",
"$ref": "#/definitions/hooks"
},
"postinfracreate": {
"title": "post infra create hook",
"description": "Runs after the `infra create` or `provision` commands",
"$ref": "#/definitions/hooks"
},
"preinfradelete": {
"title": "pre infra delete hook",
"description": "Runs before the `infra delete` or `down` commands",
"$ref": "#/definitions/hooks"
},
"postinfradelete": {
"title": "post infra delete hook",
"description": "Runs after the `infra delete` or `down` commands",
"$ref": "#/definitions/hooks"
},
"predown": {
"title": "pre down hook",
"description": "Runs before the `infra delete` or `down` commands",
"$ref": "#/definitions/hooks"
},
"postdown": {
"title": "post down hook",
"description": "Runs after the `infra delete` or `down` commands",
"$ref": "#/definitions/hooks"
},
"preup": {
"title": "pre up hook",
"description": "Runs before the `up` command",
"$ref": "#/definitions/hooks"
},
"postup": {
"title": "post up hook",
"description": "Runs after the `up` command",
"$ref": "#/definitions/hooks"
},
"prepackage": {
"title": "pre package hook",
"description": "Runs before the `package` command",
"$ref": "#/definitions/hooks"
},
"postpackage": {
"title": "post package hook",
"description": "Runs after the `package` command",
"$ref": "#/definitions/hooks"
},
"predeploy": {
"title": "pre deploy hook",
"description": "Runs before the `deploy` command",
"$ref": "#/definitions/hooks"
},
"postdeploy": {
"title": "post deploy hook",
"description": "Runs after the `deploy` command",
"$ref": "#/definitions/hooks"
},
"prerestore": {
"title": "pre restore hook",
"description": "Runs before the `restore` command",
"$ref": "#/definitions/hooks"
},
"postrestore": {
"title": "post restore hook",
"description": "Runs after the `restore` command",
"$ref": "#/definitions/hooks"
}
}
},
"requiredVersions": {
"type": "object",
"additionalProperties": false,
"description": "Optional. Provides additional configuration for required versions of `azd` and extensions.",
"properties": {
"azd": {
"type": "string",
"title": "A range of supported versions of `azd` for this project",
"description": "A range of supported versions of `azd` for this project. If the version of `azd` is outside this range, the project will fail to load. Optional (allows all versions if absent).",
"examples": [
">= 0.6.0-beta.3"
]
},
"extensions": {
"type": "object",
"title": "A map of required extensions and version constraints for this project.",
"description": "A map of required extensions and version constraints for this project. Supports semver constraints. If version is omitted the latest version will be installed.",
"additionalProperties": {
"type": "string",
"examples": [
"latest",
">=1.0.0",
"~2.0.0",
"=3.1.2",
">= 1.0.0 < 2.0.0"
]
}
}
}
},
"state": {
"type": "object",
"title": "The state configuration used for the project.",
"description": "Optional. Provides additional configuration for state management.",
"additionalProperties": false,
"properties": {
"remote": {
"type": "object",
"additionalProperties": false,
"title": "The remote state configuration.",
"description": "Optional. Provides additional configuration for remote state management such as Azure Blob Storage.",
"required": [
"backend"
],
"properties": {
"backend": {
"type": "string",
"title": "The remote state backend type.",
"description": "Optional. The remote state backend type. (Default: AzureBlobStorage)",
"default": "AzureBlobStorage",
"enum": [
"AzureBlobStorage"
]
},
"config": {
"type": "object",
"additionalProperties": true
}
},
"allOf": [
{
"if": {
"properties": {
"backend": {
"const": "AzureBlobStorage"
}
}
},
"then": {
"required": [
"config"
],
"properties": {
"config": {
"$ref": "#/definitions/azureBlobStorageConfig"
}
}
}
}
]
}
}
},
"platform": {
"type": "object",
"title": "The platform configuration used for the project.",
"description": "Optional. Provides additional configuration for platform specific features such as Azure Dev Center.",
"additionalProperties": false,
"required": [
"type"
],
"properties": {
"type": {
"type": "string",
"title": "The platform type.",
"description": "Required. The platform type. (Example: devcenter)",
"enum": [
"devcenter"
]
},
"config": {
"type": "object",
"additionalProperties": true
}
},
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "devcenter"
}
}
},
"then": {
"properties": {
"config": {
"$ref": "#/definitions/azureDevCenterConfig"
}
}
}
}
]
},
"workflows": {
"type": "object",
"title": "The workflows configuration used for the project.",
"description": "Optional. Provides additional configuration for workflows such as override azd up behavior.",
"additionalProperties": false,
"properties": {
"up": {
"title": "The up workflow configuration",
"description": "When specified will override the default behavior for the azd up workflow. Common use cases include changing the order of the provision, package and deploy commands.",
"$ref": "#/definitions/workflow"
}
}
}
},
"definitions": {
"hooks": {
"anyOf": [
{
"$ref": "#/definitions/hook"
},
{
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/hook"
}
}
]
},
"hook": {
"type": "object",
"additionalProperties": false,
"properties": {
"shell": {
"type": "string",
"title": "Type of shell to execute scripts",
"description": "Optional. The type of shell to use for the hook. (Default: sh)",
"enum": [
"sh",
"pwsh"
],
"default": "sh"
},
"run": {
"type": "string",
"title": "Required. The inline script or relative path of your scripts from the project or service path",
"description": "When specifying an inline script you also must specify the `shell` to use. This is automatically inferred when using paths."
},
"continueOnError": {
"type": "boolean",
"default": false,
"title": "Whether or not a script error will halt the azd command",
"description": "Optional. When set to true will continue to run the command even after a script error has occurred. (Default: false)"
},
"interactive": {
"type": "boolean",
"default": false,
"title": "Whether the script will run in interactive mode",
"description": "Optional. When set to true will bind the script to stdin, stdout & stderr of the running console. (Default: false)"
},
"windows": {
"title": "The hook configuration used for Windows environments",
"description": "When specified overrides the hook configuration when executed in Windows environments",
"default": null,
"$ref": "#/definitions/hook"
},
"posix": {
"title": "The hook configuration used for POSIX (Linux & MacOS) environments",
"description": "When specified overrides the hook configuration when executed in POSIX environments",
"default": null,
"$ref": "#/definitions/hook"
}
},
"if": {
"not": {
"anyOf": [
{
"required": [
"windows"
]
},
{
"required": [
"posix"
]
}
]
}
},
"then": {
"required": [
"run"
]
}
},
"docker": {
"type": "object",
"description": "This is only applicable when `host` is `containerapp` or `aks`",
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"title": "The path to the Dockerfile",
"description": "Path to the Dockerfile is relative to your service",
"default": "./Dockerfile"
},
"context": {
"type": "string",
"title": "The docker build context",
"description": "When specified overrides the default context",
"default": "."
},
"platform": {
"type": "string",
"title": "The platform target",
"default": "amd64"
},
"registry": {
"type": "string",
"title": "Optional. The container registry to push the image to.",
"description": "If omitted, will default to value of AZURE_CONTAINER_REGISTRY_ENDPOINT environment variable. Supports environment variable substitution."
},
"image": {
"type": "string",
"title": "Optional. The name that will be applied to the built container image.",
"description": "If omitted, will default to the '{appName}/{serviceName}-{environmentName}'. Supports environment variable substitution."
},
"tag": {
"type": "string",
"title": "The tag that will be applied to the built container image.",
"description": "If omitted, will default to 'azd-deploy-{unix time (seconds)}'. Supports environment variable substitution. For example, to generate unique tags for a given release: myapp/myimage:${DOCKER_IMAGE_TAG}"
},
"buildArgs": {
"type": "array",
"title": "Optional. Build arguments to pass to the docker build command",
"description": "Build arguments to pass to the docker build command.",
"items": {
"type": "string"
}
},
"remoteBuild": {
"type": "boolean",
"title": "Optional. Whether to build the image remotely",
"description": "If set to true, the image will be built remotely using the Azure Container Registry remote build feature. If set to false, the image will be built locally using Docker."
}
}
},
"aksOptions": {
"type": "object",
"title": "Optional. The Azure Kubernetes Service (AKS) configuration options",
"additionalProperties": false,
"properties": {
"deploymentPath": {
"type": "string",
"title": "Optional. The relative path from the service path to the k8s deployment manifests. (Default: manifests)",
"description": "When set it will override the default deployment path location for k8s deployment manifests.",
"default": "manifests"
},
"namespace": {
"type": "string",
"title": "Optional. The k8s namespace of the deployed resources. (Default: Project name)",
"description": "When specified a new k8s namespace will be created if it does not already exist"
},
"deployment": {
"type": "object",
"title": "Optional. The k8s deployment configuration",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"title": "Optional. The name of the k8s deployment resource to use during deployment. (Default: Service name)",
"description": "Used during deployment to ensure if the k8s deployment rollout has been completed. If not set will search for a deployment resource in the same namespace that contains the service name."
}
}
},
"service": {
"type": "object",
"title": "Optional. The k8s service configuration",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"title": "Optional. The name of the k8s service resource to use as the default service endpoint. (Default: Service name)",
"description": "Used when determining endpoints for the default service resource. If not set will search for a deployment resource in the same namespace that contains the service name."
}
}
},
"ingress": {
"type": "object",
"title": "Optional. The k8s ingress configuration",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"title": "Optional. The name of the k8s ingress resource to use as the default service endpoint. (Default: Service name)",
"description": "Used when determining endpoints for the default ingress resource. If not set will search for a deployment resource in the same namespace that contains the service name."
},
"relativePath": {
"type": "string",
"title": "Optional. The relative path to the service from the root of your ingress controller.",
"description": "When set will be appended to the root of your ingress resource path."
}
}
},
"helm": {
"type": "object",
"title": "Optional. The helm configuration",
"additionalProperties": false,
"properties": {
"repositories": {
"type": "array",
"title": "Optional. The helm repositories to add",
"description": "When set will add the helm repositories to the helm client.",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"url"
],
"properties": {
"name": {
"type": "string",
"title": "The name of the helm repository",
"description": "The name of the helm repository to add."
},
"url": {
"type": "string",
"title": "The url of the helm repository",
"description": "The url of the helm repository to add."
}
}
}
},
"releases": {
"type": "array",
"title": "Optional. The helm releases to install",
"description": "When set will install the helm releases to the k8s cluster.",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"chart"
],
"properties": {
"name": {
"type": "string",
"title": "The name of the helm release",
"description": "The name of the helm release to install."
},
"chart": {
"type": "string",
"title": "The name of the helm chart",
"description": "The name of the helm chart to install."
},
"version": {
"type": "string",
"title": "The version of the helm chart",
"description": "The version of the helm chart to install."
},
"namespace": {
"type": "string",
"title": "Optional. The k8s namespace to install the helm chart",
"description": "When set will install the helm chart to the specified namespace. Defaults to the service namespace."
},
"values": {
"type": "string",
"title": "Optional. Relative path from service to a values.yaml to pass to the helm chart",
"description": "When set will pass the values to the helm chart."
}
}
}
}
}
},
"kustomize": {
"type": "object",
"title": "Optional. The kustomize configuration",
"additionalProperties": false,
"properties": {
"dir": {
"type": "string",
"title": "Optional. The relative path to the kustomize directory.",
"description": "When set will use the kustomize directory to deploy to the k8s cluster. Supports environment variable substitution."
},
"edits": {
"type": "array",
"title": "Optional. The kustomize edits to apply before deployment.",
"description": "When set will apply the edits to the kustomize directory before deployment. Supports environment variable substitution.",
"items": {
"type": "string"
}
},
"env": {
"type": "object",
"title": "Optional. The environment key/value pairs used to generate a .env file.",
"description": "When set will generate a .env file in the kustomize directory. Values support environment variable substitution.",
"additionalProperties": {
"type": [
"string",
"boolean",
"number"
]
}
}
}
}
}
},
"azureBlobStorageConfig": {
"type": "object",
"title": "The Azure Blob Storage remote state backend configuration.",
"description": "Optional. Provides additional configuration for remote state management such as Azure Blob Storage.",
"additionalProperties": false,
"required": [
"accountName"
],
"properties": {
"accountName": {
"type": "string",
"title": "The Azure Storage account name.",
"description": "Required. The Azure Storage account name."
},
"containerName": {
"type": "string",
"title": "The Azure Storage container name.",
"description": "Optional. The Azure Storage container name. Defaults to project name if not specified."
},
"endpoint": {
"type": "string",
"title": "The Azure Storage endpoint.",
"description": "Optional. The Azure Storage endpoint. (Default: blob.core.windows.net)"
}
}
},
"azureDevCenterConfig": {
"type": "object",
"title": "The dev center configuration used for the project.",
"description": "Optional. Provides additional project configuration for Azure Dev Center integration.",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"title": "The name of the Azure Dev Center",
"description": "Optional. Used as the default dev center for this project."
},
"project": {
"type": "string",
"title": "The name of the Azure Dev Center project.",
"description": "Optional. Used as the default dev center project for this project."
},
"catalog": {
"type": "string",
"title": "The name of the Azure Dev Center catalog.",
"description": "Optional. Used as the default dev center catalog for this project."
},
"environmentDefinition": {
"type": "string",
"title": "The name of the Dev Center catalog environment definition.",
"description": "Optional. Used as the default dev center environment definition for this project."
},
"environmentType": {
"type": "string",
"title": "The Dev Center project environment type used for the deployment environment.",
"description": "Optional. Used as the default environment type for this project."
}
}
},
"workflow": {
"anyOf": [
{
"type": "object",
"additionalProperties": false,
"required": [
"steps"
],
"properties": {
"steps": {
"type": "array",
"title": "The steps to execute in the workflow",
"description": "The steps to execute in the workflow. (Example: provision, package, deploy)",
"minItems": 1,
"items": {
"type": "object",
"$ref": "#/definitions/workflowStep"
}
}
}
},
{
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/workflowStep"
}
}
]
},
"workflowStep": {
"properties": {
"azd": {
"title": "The azd command command configuration",
"description": "The azd command configuration to execute. (Example: up)",
"$ref": "#/definitions/azdCommand"
}
}
},
"azdCommand": {
"anyOf": [
{
"type": "string",
"title": "The azd command to execute",
"description": "The name and args of the azd command to execute. (Example: deploy --all)"
},
{
"type": "object",
"additionalProperties": false,
"required": [
"args"
],
"properties": {
"args": {
"type": "array",
"title": "The arguments or flags to pass to the azd command",
"description": "The arguments to pass to the azd command. (Example: --all)",
"minItems": 1
}
}
}
]
},
"aiComponentConfig": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Name of the AI component.",
"description": "Optional. When omitted AZD will generate a name based on the component type and the service name. Supports environment variable substitution."
},
"path": {
"type": "string",
"title": "Path to the AI component configuration file or path.",
"description": "Required. The path to the AI component configuration file or path to the AI component source code."
},
"overrides": {
"type": "object",
"title": "A map of key value pairs used to override the AI component configuration.",
"description": "Optional. Supports environment variable substitution.",
"additionalProperties": {
"type": "string"
}
}
},
"required": [
"path"
]
},
"aiDeploymentConfig": {
"allOf": [
{
"$ref": "#/definitions/aiComponentConfig"
},
{
"type": "object",
"properties": {
"environment": {
"type": "object",
"title": "A map of key/value pairs to set as environment variables for the deployment.",
"description": "Optional. Values support OS & AZD environment variable substitution.",
"additionalProperties": {
"type": "string"
}
}
}
}
]
},
"aiEndpointConfig": {
"type": "object",
"additionalProperties": false,
"properties": {
"workspace": {
"type": "string",
"title": "The name of the AI Studio project workspace.",
"description": "Optional. When omitted AZD will use the value specified in the 'AZUREAI_PROJECT_NAME' environment variable. Supports environment variable substitution."
},
"flow": {
"$ref": "#/definitions/aiComponentConfig",
"title": "The Azure AI Studio Prompt Flow configuration.",
"description": "Optional. When omitted a prompt flow will be not created."
},
"environment": {
"$ref": "#/definitions/aiComponentConfig",
"title": "The Azure AI Studio custom environment configuration.",
"description": "Optional. When omitted a custom environment will not be created."
},
"model": {
"$ref": "#/definitions/aiComponentConfig",
"title": "The Azure AI Studio model configuration.",
"description": "Optional. When omitted a model will not be created."
},
"deployment": {
"$ref": "#/definitions/aiDeploymentConfig",
"title": "The Azure AI Studio online endpoint deployment configuration.",
"description": "Required. A new online endpoint deployment will be created and traffic will automatically to shifted to the new deployment upon successful completion."
}
},
"required": [
"deployment"
]
},
"deploymentStacksConfig": {
"type": "object",
"title": "The deployment stack configuration used for the project.",
"additionalProperties": false,
"oneOf": [
{
"required": [
"actionOnUnmanage"
]
},
{
"required": [
"denySettings"
]
}
],
"properties": {
"actionOnUnmanage": {
"type": "object",
"title": "The action to take when when resources become unmanaged",
"description": "Defines the behavior of resources that are no longer managed after the Deployment stack is updated or deleted. Defaults to 'delete' for all resource scopes.",
"required": [
"resourceGroups",
"resources"
],
"properties": {
"resourceGroups": {
"type": "string",
"title": "Required. The action on unmanage setting for resource groups",
"description": "Specifies an action for a newly unmanaged resource. Delete will attempt to delete the resource from Azure. Detach will leave the resource in it's current state.",
"default": "delete",
"enum": [
"delete",
"detach"
]
},
"resources": {
"type": "string",
"title": "Required. The action on unmanage setting for resources",
"description": "Specifies an action for a newly unmanaged resource. Delete will attempt to delete the resource from Azure. Detach will leave the resource in it's current state.",
"default": "delete",
"enum": [
"delete",
"detach"
]
}
}
},
"denySettings": {
"type": "object",
"title": "The deny settings for the deployment stack",
"description": "Defines how resources deployed by the stack are locked. Defaults to 'none'.",
"required": [
"mode"
],
"properties": {
"mode": {
"type": "string",
"title": "Required. Mode that defines denied actions.",
"default": "none",
"enum": [
"none",
"denyDelete",
"denyWriteAndDelete"
]
},
"applyToChildScopes": {
"type": "boolean",
"title": "Whether the deny settings apply to child scopes.",
"description": "DenySettings will be applied to child resource scopes of every managed resource with a deny assignment."
},
"excludedActions": {
"type": "array",
"title": "List of role-based management operations that are excluded from the denySettings."
},
"excludedPrincipals": {
"type": "array",
"title": "List of Entra ID principal IDs excluded from the lock. Up to 5 principals are permitted."
}
}
}
}
},
"resource": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"title": "Type of resource",
"description": "The type of resource to be created. (Example: db.postgres)",
"enum": [
"db.postgres",
"db.redis",
"db.mongo",
"host.containerapp",
"ai.openai.model"
]
},
"uses": {
"type": "array",
"title": "Other resources that this resource uses",
"items": {
"type": "string"
},
"uniqueItems": true
}
}
},
"containerAppResource": {
"type": "object",
"description": "A Docker-based container app.",
"additionalProperties": false,
"required": [
"port"
],
"properties": {
"type": true,
"uses": true,
"port": {
"type": "integer",
"title": "Port that the container app listens on",
"description": "Optional. The port that the container app listens on. (Default: 80)"
},
"env": {
"type": "array",
"title": "Environment variables to set for the container app",
"items": {
"type": "object",
"required": [
"name"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"title": "Name of the environment variable"
},
"value": {
"type": "string",
"title": "Value of the environment variable. Supports environment variable substitution."
},
"secret": {
"type": "string",
"title": "Secret value of the environment variable. Supports environment variable substitution."
}
}
}
}
}
},
"aiModelResource": {
"type": "object",
"description": "A deployed, ready-to-use AI model.",
"additionalProperties": false,
"required": [
"model"
],
"properties": {
"type": true,
"uses": true,
"model": {
"type": "object",
"description": "The underlying AI model.",
"additionalProperties": false,
"required": [
"name",
"version"
],
"properties": {
"name": {
"type": "string",
"title": "The name of the AI model.",
"description": "Required. The name of the AI model."
},
"version": {
"type": "string",
"title": "The version of the AI model.",
"description": "Required. The version of the AI model."
}
}
}
}
},
"eventHubsResource": {
"type": "object",
"description": "An Azure Event Hubs namespace.",
"additionalProperties": false,
"properties": {
"type": true,
"uses": true,
"hubs": {
"type": "array",
"title": "Hubs to create in the Event Hubs namespace",
"additionalProperties": false,
"items": {
"type": "string"
},
"uniqueItems": true
}
}
},
"serviceBusResource": {
"type": "object",
"description": "An Azure Service Bus namespace.",
"additionalProperties": false,
"properties": {
"type": true,
"uses": true,
"queues": {
"type": "array",
"title": "Queues to create in the Service Bus namespace",
"additionalProperties": false,
"items": {
"type": "string"
},
"uniqueItems": true
},
"topics": {
"type": "array",
"title": "Topics to create in the Service Bus namespace",
"additionalProperties": false,
"items": {
"type": "string"
},
"uniqueItems": true
}
}
},
"storageAccountResource": {
"type": "object",
"description": "A deployed, ready-to-use Azure Storage Account.",
"additionalProperties": false,
"properties": {
"type": true,
"uses": true,
"containers": {
"type": "array",
"title": "Azure Storage Account container names.",
"description": "The container names of Azure Storage Account.",
"items": {
"type": "string",
"title": "Azure Storage Account container name",
"description": "The container name of Azure Storage Account."
}
}
}
}
}
}
"""
https://github.com/rujche/samples/tree/azd-enhancement-for-cosmos-db
The output azure.yaml
can detect the app and resource:
name: spring-sample-app
services:
api:
language: java
project: .
host: containerapp
docker:
context: .
dockerfile: Dockerfile
bindings:
- port: 8080
env:
COSMOS_DATABASE: sample
# Spring Cloud Azure environment variables
AZURE_COSMOS_ENDPOINT: ${resources.cosmos.outputs.endpoint}
AZURE_COSMOS_DATABASE: ${resources.cosmos.outputs.database}
AZURE_COSMOS_KEY: ${resources.cosmos.outputs.key}
# Default Azure authentication variables
AZURE_CLIENT_ID: ${azure.credentials.clientId}
AZURE_TENANT_ID: ${azure.credentials.tenantId}
AZURE_CLIENT_SECRET: ${azure.credentials.clientSecret}
uses:
- cosmos
resources:
cosmos:
type: azure.cosmos
properties:
database: sample
containers:
- name: users
partitionKey: /lastName
https://github.com/haoozhang/Spring-Cloud-Stream-Kafka-Application
The output azure.yaml
can detect the app and resource
name: spring-cloud-stream-kafka
services:
app:
language: java
project: .
docker:
context: .
dockerfile: Dockerfile
host: containerapp
env:
SPRING_CLOUD_STREAM_KAFKA_BINDER_BROKERS: ${eventhubs.properties.fqdn}:9093
SPRING_CLOUD_AZURE_EVENTHUBS_CONNECTION_STRING: ${eventhubs.connectionString}
resources:
eventhubs:
type: azure.eventhubs
properties:
kafka-enabled: true
topics:
- name: sample-topic
partitionCount: 1
containerapp:
type: azure.containerapps
properties:
cpu: 1
memory: 2Gi
targetPort: 8080
uses:
- eventhubs
The output azure.yaml
can detect the resource:
name: spring-petclinic
services:
api:
project: .
language: java
docker:
context: .
dockerfile: Dockerfile
host: containerapp
resources:
mysql:
type: azure.mysql.flexibleserver
properties:
databases:
- name: petclinic
api:
type: azure.containerapps
properties:
ingress:
external: true
targetPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: mysql
- name: SPRING_DATASOURCE_URL
secretRef: mysql-connection-string
uses:
- mysql
https://github.com/azure-javaee/spring-petclinic-microservices/tree/sjad
The output of the azure.yaml
is not accurate (for example the applicationinsights uses the other projects)
name: spring-petclinic-microservices
services:
config-server:
project: ./spring-petclinic-config-server
language: java
host: containerapp
docker:
context: .
dockerfile: docker/Dockerfile
env:
- name: "CONFIG_SERVER_URL"
value: "http://config-server"
- name: "PORT"
value: "8888"
discovery-server:
project: ./spring-petclinic-discovery-server
language: java
host: containerapp
docker:
context: .
dockerfile: docker/Dockerfile
env:
- name: "CONFIG_SERVER_URL"
value: "http://config-server:8888"
- name: "PORT"
value: "8761"
uses:
- config-server
api-gateway:
project: ./spring-petclinic-api-gateway
language: java
host: containerapp
docker:
context: .
dockerfile: docker/Dockerfile
env:
- name: "CONFIG_SERVER_URL"
value: "http://config-server:8888"
- name: "PORT"
value: "8080"
uses:
- config-server
- discovery-server
- customers-service
- vets-service
- visits-service
customers-service:
project: ./spring-petclinic-customers-service
language: java
host: containerapp
docker:
context: .
dockerfile: docker/Dockerfile
env:
- name: "CONFIG_SERVER_URL"
value: "http://config-server:8888"
- name: "SPRING_PROFILES_ACTIVE"
value: "mysql"
- name: "SPRING_CLOUD_AZURE_MYSQL_DATABASE_NAME"
value: "petclinic"
uses:
- config-server
- discovery-server
- mysql
vets-service:
project: ./spring-petclinic-vets-service
language: java
host: containerapp
docker:
context: .
dockerfile: docker/Dockerfile
env:
- name: "CONFIG_SERVER_URL"
value: "http://config-server:8888"
- name: "SPRING_PROFILES_ACTIVE"
value: "mysql"
- name: "SPRING_CLOUD_AZURE_MYSQL_DATABASE_NAME"
value: "petclinic"
uses:
- config-server
- discovery-server
- mysql
visits-service:
project: ./spring-petclinic-visits-service
language: java
host: containerapp
docker:
context: .
dockerfile: docker/Dockerfile
env:
- name: "CONFIG_SERVER_URL"
value: "http://config-server:8888"
- name: "SPRING_PROFILES_ACTIVE"
value: "mysql"
- name: "SPRING_CLOUD_AZURE_MYSQL_DATABASE_NAME"
value: "petclinic"
uses:
- config-server
- discovery-server
- mysql
admin-server:
project: ./spring-petclinic-admin-server
language: java
host: containerapp
docker:
context: .
dockerfile: docker/Dockerfile
env:
- name: "CONFIG_SERVER_URL"
value: "http://config-server:8888"
- name: "PORT"
value: "9090"
uses:
- config-server
- discovery-server
resources:
mysql:
type: azure.mysql
databases:
- name: petclinic
tables:
- owners
- pets
- types
- vets
- specialties
- vet_specialties
- visits
https://github.com/rujche/todo-java-mongo-aca/tree/azd-enhancement-for-mongo
The output of the azure.yaml
is accurate:
name: todo-java-mongo-aca
metadata:
template: [email protected]
services:
api:
project: ./src/api
language: java
host: containerapp
docker:
context: ./src/api
dockerfile: Dockerfile
web:
project: ./src/web
language: js
host: containerapp
docker:
context: ./src/web
dockerfile: Dockerfile
resources:
database:
type: azure.cosmos.mongodb
properties:
databaseName: todo
keyvault:
type: azure.keyvault
applicationinsights:
type: azure.monitor.applicationinsights
api-container-app:
type: azure.containerapps
properties:
project: api
targetPort: 3100
uses:
- database
- keyvault
- applicationinsights
web-container-app:
type: azure.containerapps
properties:
project: web
uses:
- api-container-app
- applicationinsights