application-modeling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Radius Application Modeling

Radius 应用建模

Use this skill for all Radius-related tasks: authoring application Bicep, configuring environments with recipes, and creating custom resource types. This skill covers the full lifecycle from defining an app to deploying it on Kubernetes.
本技能适用于所有与Radius相关的任务:编写应用Bicep文件、使用Recipe配置环境、创建自定义资源类型。涵盖从定义应用到在Kubernetes上部署的完整生命周期。

Workflow

工作流程

  1. Read the platform constitution. Check for
    Platform-Engineering-Constitution.md
    in the repository root. Note approved cloud providers, compute platforms, and IaC tooling.
  2. Check current Radius state. Run
    rad workspace show
    ,
    rad environment list
    ,
    rad recipe list
    , and
    rad resource-type list
    .
  3. If asked to create an application definition, inspect the workspace first. Look for environment definitions, existing shared resources, container artifacts, and application code that implies required connections.
  4. Prompt only for missing values. Ask for OCI registry details, boolean choices without a safe default, and long free-text inputs such as AI prompts.
  5. Author or update the application Bicep, resource types, and/or environment configuration as needed.
  6. Validate against the constitution and test with
    rad run
    .
  1. 查阅平台规范文档。检查仓库根目录下的
    Platform-Engineering-Constitution.md
    ,记录已批准的云服务商、计算平台和IaC工具。
  2. 检查当前Radius状态。运行
    rad workspace show
    rad environment list
    rad recipe list
    rad resource-type list
    命令。
  3. 若需创建应用定义,先检查工作区。查看环境定义、现有共享资源、容器制品以及隐含所需连接的应用代码。
  4. 仅询问缺失的必要信息。询问OCI仓库详情、无安全默认值的布尔选项,以及长文本输入(如AI提示词)。
  5. 编写或更新应用Bicep文件、资源类型和/或环境配置(如有需要)。
  6. 验证是否符合平台规范,并使用
    rad run
    进行测试。

Interactive App Definition Flow

交互式应用定义流程

Use this flow when the user says things like
Create an application definition
,
Create app.bicep
, or
Scaffold a Radius application
.
当用户提出
创建应用定义
生成app.bicep
搭建Radius应用脚手架
等需求时,使用此流程。

Discovery Order

发现顺序

  1. Inspect environment-definition files first. Treat files such as
    env.bicep
    ,
    environment.bicep
    ,
    shared-resources.bicep
    , and similar workspace Bicep files as the primary source of truth for shared resources and environment names.
  2. Model shared resources from workspace files as
    existing
    in
    app.bicep
    .
    If PostgreSQL, blob storage, or other shared resources are declared in files like
    env.bicep
    or
    shared-resources.bicep
    , reference them with
    existing
    in the generated app definition even if they might not be deployed yet.
  3. Inspect the repository for container artifacts. Look for
    Dockerfile
    ,
    Containerfile
    , OCI build configs, or application folders that clearly map to a container workload.
  4. Choose the container resource type deliberately. Use
    Applications.Core/containers
    for straightforward single-container application workloads unless the repository explicitly needs recipe-based container features from
    Radius.Compute/containers
    .
  5. Infer container ports from workload files, not base-image defaults. Prefer explicit signals such as
    EXPOSE
    in
    Dockerfile
    ,
    listen
    directives in
    nginx.conf
    , or app server startup arguments over assumptions like nginx using port 80.
  6. Inspect the code for required connections. Search for connection names, SDK usage, or environment variables that imply dependencies such as PostgreSQL, blob storage, or AI agent endpoints.
  7. Inspect for AI-agent expectations. If the code expects an agent endpoint or agent-style integration, add a
    Radius.AI/agents
    resource.
  8. Wire connections by responsibility. Connect the AI agent to the data and knowledge resources it needs. Connect the application container only to the AI agent unless the code clearly shows the container itself must talk to other resources directly.
  1. 优先检查环境定义文件。将
    env.bicep
    environment.bicep
    shared-resources.bicep
    及类似工作区Bicep文件视为共享资源和环境名称的主要可信来源。
  2. 将工作区文件中的共享资源在
    app.bicep
    中标记为
    existing
    。若PostgreSQL、Blob存储或其他共享资源在
    env.bicep
    shared-resources.bicep
    等文件中已声明,即使尚未部署,也要在生成的应用定义中使用
    existing
    引用它们。
  3. 检查仓库中的容器制品。查找
    Dockerfile
    Containerfile
    、OCI构建配置或明确对应容器工作负载的应用文件夹。
  4. 谨慎选择容器资源类型。对于简单的单容器应用工作负载,默认使用
    Applications.Core/containers
    ,除非仓库明确依赖
    Radius.Compute/containers
    的Recipe容器特性。
  5. 从工作负载配置推断容器端口,而非基础镜像默认值。优先选择明确的配置信号,如
    Dockerfile
    中的
    EXPOSE
    指令、
    nginx.conf
    中的
    listen
    配置或应用服务器启动参数,而非假设基础镜像的默认端口(如nginx的80端口)。
  6. 检查代码中的必要连接。搜索连接名称、SDK使用情况或隐含依赖的环境变量,如PostgreSQL、Blob存储或AI Agent端点。
  7. 检查是否有AI Agent需求。若代码需要Agent端点或类Agent集成,添加
    Radius.AI/agents
    资源。
  8. 按职责建立连接。将AI Agent连接到其所需的数据和知识资源。除非代码明确显示容器需直接与其他资源通信,否则仅将应用容器连接到AI Agent。

Required Questions

必要询问项

Ask the user only when the value cannot be inferred safely:
  1. OCI registry host for the container image.
  2. Enable observability? Ask explicitly for
    Radius.AI/agents.enableObservability
    because it is boolean and should not be guessed.
  3. Prompt value for the AI agent.
仅当无法安全推断时,才向用户询问以下信息:
  1. 容器镜像的OCI仓库地址
  2. 是否启用可观测性? 针对
    Radius.AI/agents.enableObservability
    需明确询问,因为这是布尔值,不应默认猜测。
  3. AI Agent的提示词内容

Authoring Rules For This Flow

此流程的编写规则

  • Always create
    app.bicep
    when it does not already exist.
  • Always ensure
    bicepconfig.json
    includes the needed Radius extensions
    for every resource type used in the generated app.
  • Use
    existing
    resources
    for shared infrastructure already defined by the environment, especially PostgreSQL and blob storage when those are pre-provisioned.
  • Treat workspace Bicep files as authoritative for shared resources even when those resources are not deployed yet.
  • Add a container resource when the repository clearly contains a deployable application container.
  • Prefer
    Applications.Core/containers
    for simple frontend or service containers
    and only switch to
    Radius.Compute/containers
    when the repo clearly depends on recipe-based container behavior.
  • Do not connect the frontend container directly to shared data resources when an AI agent resource already encapsulates those integrations.
  • Infer the image repository name from the workload folder or existing repo conventions. If the repo contains
    src/web/Dockerfile
    , default the image repository to
    frontend-ui
    rather than a generic repository name.
  • Infer the container port from explicit workload configuration. Prefer
    EXPOSE
    , web-server config, or application startup args over generic defaults from the base image.
  • Prompt for the OCI registry instead of hardcoding one.
  • Prompt for AI observability instead of assuming
    true
    or
    false
    .
  • If the AI prompt is long or multi-line, do not inline it in the resource. Model it as
    param agentPrompt string
    and set
    prompt: agentPrompt
    .
  • If the AI prompt is short and single-line, it may be inlined unless the user prefers parameterization.
  • Prefer minimal app scaffolds that connect to existing shared resources rather than duplicating them.
  • app.bicep
    不存在时,必须创建该文件
  • 确保
    bicepconfig.json
    包含生成应用中使用的所有Radius扩展
  • 对环境中已定义的共享基础设施使用
    existing
    资源
    ,尤其是预配置的PostgreSQL和Blob存储。
  • 将工作区Bicep文件视为共享资源的可信来源,即使这些资源尚未部署。
  • 当仓库明确包含可部署的应用容器时,添加容器资源
  • 对于简单前端或服务容器,优先使用
    Applications.Core/containers
    ,仅当仓库明确依赖Recipe容器行为时,才切换为
    Radius.Compute/containers
  • 当AI Agent资源已封装集成时,不要将前端容器直接连接到共享数据资源
  • 从工作负载文件夹或现有仓库约定推断镜像仓库名称。若仓库包含
    src/web/Dockerfile
    ,默认将镜像仓库名称设为
    frontend-ui
    ,而非通用名称。
  • 从明确的工作负载配置推断容器端口。优先选择
    EXPOSE
    、Web服务器配置或应用启动参数,而非基础镜像的通用默认值。
  • 询问OCI仓库信息,而非硬编码
  • 询问AI可观测性设置,而非默认
    true
    false
  • 若AI提示词较长或为多行,不要将其内嵌到资源中。将其建模为
    param agentPrompt string
    ,并设置
    prompt: agentPrompt
  • 若AI提示词较短且为单行,可内嵌到资源中,除非用户偏好参数化。
  • 优先使用最小化应用脚手架,连接到现有共享资源而非重复创建。

Expected Output Shape

预期输出结构

The generated
app.bicep
should usually include:
  • An application resource.
  • Existing shared resources such as PostgreSQL and blob storage, when discovered from the environment definition.
  • A new application container resource, usually
    Applications.Core/containers
    for simple app workloads.
  • A new
    Radius.AI/agents
    resource when the code expects an AI agent.
  • Connections from the AI agent to PostgreSQL and blob storage when those resources are required.
  • A connection from the application container to the AI agent when the container is only a frontend or thin client.
  • Parameters for registry details and long free-text values.
See references/app-definition-flow.md for the canonical example and decision rules.
生成的
app.bicep
通常应包含:
  • 一个应用资源。
  • 从环境定义中发现的现有共享资源(如PostgreSQL和Blob存储)。
  • 一个新的应用容器资源,对于简单应用工作负载通常为
    Applications.Core/containers
  • 当代码需要AI Agent时,添加新的
    Radius.AI/agents
    资源。
  • 当PostgreSQL和Blob存储为必需资源时,建立AI Agent与它们的连接。
  • 当容器仅为前端或瘦客户端时,建立应用容器与AI Agent的连接。
  • 用于仓库详情和长文本值的参数。
有关标准示例和决策规则,请参阅references/app-definition-flow.md

Customer-Agent Target Profile

客户Agent目标配置文件

When the target repository follows the
Reshrahim/customer-agent
structure, use these repo-specific rules:
  • Environment file:
    radius/env.bicep
    defines the environment and registered recipes.
  • Shared resources file:
    radius/shared-resources.bicep
    defines PostgreSQL and blob storage that should be referenced with
    existing
    in the generated
    radius/app.bicep
    .
  • Frontend container:
    src/web/Dockerfile
    indicates a user-facing container workload; generate an
    Applications.Core/containers
    resource such as
    frontend-ui
    for it.
  • Agent runtime code:
    src/agent-runtime/app.py
    indicates the repo expects an AI agent plus PostgreSQL and blob storage connections.
  • Agent connections: the generated
    Radius.AI/agents
    resource must connect to
    contoso-db
    and
    contoso-knowledge-base
    so the runtime receives both database and knowledge-base/search inputs through the recipe.
  • Frontend connections: the generated
    frontend-ui
    container should connect only to the AI agent.
  • Frontend image name: the generated container image should use
    frontend-ui
    as the repository name unless the user overrides it.
  • Frontend port: infer the frontend port from
    src/web/Dockerfile
    and related config files. For customer-agent, use
    3000
    because the Dockerfile exposes
    3000
    and
    src/web/nginx.conf
    listens on
    3000
    .
  • Do not create a second app-level container for
    src/agent-runtime/Dockerfile
    when the
    Radius.AI/agents
    recipe already encapsulates the agent runtime container.
  • Default model: use
    gpt-4.1-mini
    unless the user asks otherwise.
  • Prompt handling: when the user pastes a long or multi-line system prompt, always model it as a
    param
    rather than inlining it.

当目标仓库遵循
Reshrahim/customer-agent
结构时,使用以下仓库特定规则:
  • 环境文件
    radius/env.bicep
    定义环境和已注册的Recipe。
  • 共享资源文件
    radius/shared-resources.bicep
    定义PostgreSQL和Blob存储,需在生成的
    radius/app.bicep
    中使用
    existing
    引用。
  • 前端容器
    src/web/Dockerfile
    表示面向用户的容器工作负载;为其生成
    Applications.Core/containers
    资源(如
    frontend-ui
    )。
  • Agent运行时代码
    src/agent-runtime/app.py
    表示仓库需要AI Agent以及PostgreSQL和Blob存储连接。
  • Agent连接:生成的
    Radius.AI/agents
    资源必须连接到
    contoso-db
    contoso-knowledge-base
    ,以便运行时通过Recipe接收数据库和知识库/搜索输入。
  • 前端连接:生成的
    frontend-ui
    容器应仅连接到AI Agent。
  • 前端镜像名称:生成的容器镜像默认使用
    frontend-ui
    作为仓库名称,除非用户覆盖。
  • 前端端口:从
    src/web/Dockerfile
    及相关配置文件推断前端端口。对于customer-agent,默认使用
    3000
    ,因为Dockerfile暴露了
    3000
    端口,且
    src/web/nginx.conf
    监听该端口。
  • 不要为
    src/agent-runtime/Dockerfile
    创建第二个应用级容器
    ,因为
    Radius.AI/agents
    Recipe已封装了Agent运行时容器。
  • 默认模型:使用
    gpt-4.1-mini
    ,除非用户另有要求。
  • 提示词处理:当用户粘贴长或多行系统提示词时,必须将其建模为参数,而非内嵌。

Part 1: Application Authoring

第一部分:应用编写

Bicep Extension Setup

Bicep扩展设置

Before writing
app.bicep
, configure
bicepconfig.json
:
json
{
  "extensions": {
    "radius": "br:biceptypes.azurecr.io/radius:latest",
    "aws": "br:biceptypes.azurecr.io/aws:latest"
  },
  "experimentalFeaturesEnabled": {
    "extensibility": true,
    "dynamicTypeLoading": true
  }
}
If using
Radius.*
resource types
(from
radius-resource-types
), add custom extensions:
json
{
  "extensions": {
    "radius": "br:biceptypes.azurecr.io/radius:latest",
    "aws": "br:biceptypes.azurecr.io/aws:latest",
    "radiusCompute": "radius-compute.tgz",
    "radiusData": "radius-data.tgz",
    "radiusStorage": "radius-storage.tgz",
    "radiusSecurity": "radius-security.tgz",
    "radiusAi": "radius-ai.tgz"
  },
  "experimentalFeaturesEnabled": {
    "extensibility": true,
    "dynamicTypeLoading": true
  }
}
Generate custom extensions with:
bash
rad bicep publish-extension --from-file <manifest.yaml> --target <output.tgz>
在编写
app.bicep
之前,配置
bicepconfig.json
json
{
  "extensions": {
    "radius": "br:biceptypes.azurecr.io/radius:latest",
    "aws": "br:biceptypes.azurecr.io/aws:latest"
  },
  "experimentalFeaturesEnabled": {
    "extensibility": true,
    "dynamicTypeLoading": true
  }
}
若使用
Radius.*
资源类型
(来自
radius-resource-types
),添加自定义扩展:
json
{
  "extensions": {
    "radius": "br:biceptypes.azurecr.io/radius:latest",
    "aws": "br:biceptypes.azurecr.io/aws:latest",
    "radiusCompute": "radius-compute.tgz",
    "radiusData": "radius-data.tgz",
    "radiusStorage": "radius-storage.tgz",
    "radiusSecurity": "radius-security.tgz",
    "radiusAi": "radius-ai.tgz"
  },
  "experimentalFeaturesEnabled": {
    "extensibility": true,
    "dynamicTypeLoading": true
  }
}
使用以下命令生成自定义扩展:
bash
rad bicep publish-extension --from-file <manifest.yaml> --target <output.tgz>

Resource Type Namespaces

资源类型命名空间

There are two families of resource types:
存在两类资源类型:

Applications.*
(Built-in)

Applications.*
(内置)

Built into Radius.
Applications.Core/containers
is handled directly by the Radius control plane — not recipe-based.
TypeDescription
Applications.Core/applications
Application grouping
Applications.Core/containers
Container workloads (directly managed)
Applications.Core/gateways
HTTP ingress gateways
Applications.Datastores/redisCaches
Redis (recipe-based)
Applications.Datastores/sqlDatabases
SQL databases (recipe-based)
内置在Radius中。
Applications.Core/containers
由Radius控制平面直接处理,不基于Recipe。
类型描述
Applications.Core/applications
应用分组
Applications.Core/containers
容器工作负载(直接管理)
Applications.Core/gateways
HTTP入口网关
Applications.Datastores/redisCaches
Redis(基于Recipe)
Applications.Datastores/sqlDatabases
SQL数据库(基于Recipe)

Radius.*
(from radius-resource-types)

Radius.*
(来自radius-resource-types)

Community/extensible types. ALL are recipe-based, including
Radius.Compute/containers
.
TypeDescription
Radius.Compute/containers
Container workloads (recipe-based)
Radius.Compute/persistentVolumes
Persistent storage volumes
Radius.Compute/routes
HTTP routing (requires Gateway API controller)
Radius.Data/mySqlDatabases
MySQL databases
Radius.Data/postgreSqlDatabases
PostgreSQL databases
Radius.Storage/blobStorages
Blob/object storage
Radius.Security/secrets
Secret stores
Radius.AI/agents
LLM-powered agent runtimes
Radius.Data/redisCaches
is still kept in these skills as a supported custom pattern and example, even though it is not currently listed in the checked-in folders of
radius-resource-types
.
Critical difference:
Applications.Core/containers
is directly managed by Radius.
Radius.Compute/containers
is recipe-based — it needs a registered recipe to deploy.
社区/可扩展类型。所有类型均基于Recipe,包括
Radius.Compute/containers
类型描述
Radius.Compute/containers
容器工作负载(基于Recipe
Radius.Compute/persistentVolumes
持久存储卷
Radius.Compute/routes
HTTP路由(需要Gateway API控制器)
Radius.Data/mySqlDatabases
MySQL数据库
Radius.Data/postgreSqlDatabases
PostgreSQL数据库
Radius.Storage/blobStorages
Blob/对象存储
Radius.Security/secrets
密钥存储
Radius.AI/agents
大语言模型驱动的Agent运行时
Radius.Data/redisCaches
仍作为受支持的自定义模式和示例包含在本技能中,尽管目前未在
radius-resource-types
的签入文件夹中列出。
关键区别
Applications.Core/containers
由Radius直接管理。
Radius.Compute/containers
基于Recipe,需要已注册的Recipe才能部署。

Application Structure

应用结构

Using
Applications.*
Types (Simpler)

使用
Applications.*
类型(更简单)

bicep
extension radius

param environment string
param application string

resource frontend 'Applications.Core/containers@2023-10-01-preview' = {
  name: 'frontend'
  properties: {
    application: application
    container: {                    // singular "container"
      image: 'myregistry/frontend:latest'
      ports: {
        web: { containerPort: 3000 }
      }
    }
    connections: {
      database: { source: db.id }
    }
  }
}

resource db 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = {
  name: 'database'
  properties: {
    environment: environment
    application: application
  }
}
bicep
extension radius

param environment string
param application string

resource frontend 'Applications.Core/containers@2023-10-01-preview' = {
  name: 'frontend'
  properties: {
    application: application
    container: {                    // 单数"container"
      image: 'myregistry/frontend:latest'
      ports: {
        web: { containerPort: 3000 }
      }
    }
    connections: {
      database: { source: db.id }
    }
  }
}

resource db 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = {
  name: 'database'
  properties: {
    environment: environment
    application: application
  }
}

Using
Radius.*
Types (Portable)

使用
Radius.*
类型(可移植)

bicep
extension radius
extension radiusCompute
extension radiusData

param environment string
param application string

resource frontend 'Radius.Compute/containers@2025-08-01-preview' = {
  name: 'frontend'
  properties: {
    environment: environment
    application: application
    containers: {                   // plural "containers" — a map!
      frontend: {
        image: 'myregistry/frontend:latest'
        ports: {
          web: { containerPort: 3000 }
        }
      }
    }
    connections: {
      database: { source: db.id }
    }
  }
}

resource db 'Radius.Data/postgreSqlDatabases@2025-08-01-preview' = {
  name: 'database'
  properties: {
    environment: environment
    application: application
    size: 'S'                       // Required if recipe expects it
  }
}
Schema difference:
Applications.Core/containers
uses
container
(singular object).
Radius.Compute/containers
uses
containers
(plural map where each key is a container name).
bicep
extension radius
extension radiusCompute
extension radiusData

param environment string
param application string

resource frontend 'Radius.Compute/containers@2025-08-01-preview' = {
  name: 'frontend'
  properties: {
    environment: environment
    application: application
    containers: {                   // 复数"containers" — 一个映射!
      frontend: {
        image: 'myregistry/frontend:latest'
        ports: {
          web: { containerPort: 3000 }
        }
      }
    }
    connections: {
      database: { source: db.id }
    }
  }
}

resource db 'Radius.Data/postgreSqlDatabases@2025-08-01-preview' = {
  name: 'database'
  properties: {
    environment: environment
    application: application
    size: 'S'                       // 若Recipe要求则为必填
  }
}
Schema区别
Applications.Core/containers
使用
container
(单数对象)。
Radius.Compute/containers
使用
containers
(复数映射,每个键为容器名称)。

Connections and Environment Variables

连接与环境变量

Applications.Core/containers
— Individual Env Vars

Applications.Core/containers
— 独立环境变量

CONNECTION_<NAME>_HOST
CONNECTION_<NAME>_PORT
CONNECTION_<NAME>_DATABASE
CONNECTION_<NAME>_USERNAME
CONNECTION_<NAME>_PASSWORD
CONNECTION_<NAME>_HOST
CONNECTION_<NAME>_PORT
CONNECTION_<NAME>_DATABASE
CONNECTION_<NAME>_USERNAME
CONNECTION_<NAME>_PASSWORD

Radius.Compute/containers
— JSON Properties Blob

Radius.Compute/containers
— JSON属性Blob

CONNECTION_<NAME>_PROPERTIES={"host":"...","port":"...","database":"..."}
CONNECTION_<NAME>_ID=<resource-id>
CONNECTION_<NAME>_NAME=<connection-name>
CONNECTION_<NAME>_TYPE=<resource-type>
Application code must parse
CONNECTION_<NAME>_PROPERTIES
as JSON.
Write a helper function that supports both formats:
go
// Go
func getConnProp(connName, prop string) string {
    propsJSON := os.Getenv("CONNECTION_" + connName + "_PROPERTIES")
    if propsJSON != "" {
        var props map[string]interface{}
        if err := json.Unmarshal([]byte(propsJSON), &props); err == nil {
            if val, ok := props[strings.ToLower(prop)]; ok {
                return fmt.Sprintf("%v", val)
            }
        }
    }
    return os.Getenv("CONNECTION_" + connName + "_" + prop)
}
javascript
// Node.js
function getConnProp(connName, prop) {
  const propsJson = process.env[`CONNECTION_${connName}_PROPERTIES`];
  if (propsJson) {
    try {
      const props = JSON.parse(propsJson);
      return props[prop.toLowerCase()] || '';
    } catch (e) {}
  }
  return process.env[`CONNECTION_${connName}_${prop}`] || '';
}
CONNECTION_<NAME>_PROPERTIES={"host":"...","port":"...","database":"..."}
CONNECTION_<NAME>_ID=<resource-id>
CONNECTION_<NAME>_NAME=<connection-name>
CONNECTION_<NAME>_TYPE=<resource-type>
应用代码必须将
CONNECTION_<NAME>_PROPERTIES
解析为JSON
。编写支持两种格式的辅助函数:
go
// Go
func getConnProp(connName, prop string) string {
    propsJSON := os.Getenv("CONNECTION_" + connName + "_PROPERTIES")
    if propsJSON != "" {
        var props map[string]interface{}
        if err := json.Unmarshal([]byte(propsJSON), &props); err == nil {
            if val, ok := props[strings.ToLower(prop)]; ok {
                return fmt.Sprintf("%v", val)
            }
        }
    }
    return os.Getenv("CONNECTION_" + connName + "_" + prop)
}
javascript
// Node.js
function getConnProp(connName, prop) {
  const propsJson = process.env[`CONNECTION_${connName}_PROPERTIES`];
  if (propsJson) {
    try {
      const props = JSON.parse(propsJson);
      return props[prop.toLowerCase()] || '';
    } catch (e) {}
  }
  return process.env[`CONNECTION_${connName}_${prop}`] || '';
}

Container Image Requirements

容器镜像要求

  • Cloud registry (ACR, ECR, GHCR): Works if cluster has credentials configured
  • Local dev with kind: Push to a local OCI registry and use
    host.docker.internal:<port>
    as the image host
  • imagePullPolicy
    : The
    Radius.Compute/containers
    recipe may set
    Always
    — images must be pullable, not just loaded with
    kind load
  • 云仓库(ACR、ECR、GHCR):若集群已配置凭证则可正常使用
  • 使用kind的本地开发:推送到本地OCI仓库,并使用
    host.docker.internal:<port>
    作为镜像地址
  • imagePullPolicy
    Radius.Compute/containers
    的Recipe可能设置为
    Always
    ,因此镜像必须可拉取,仅使用
    kind load
    加载镜像无法满足要求

Health Endpoints

健康检查端点

Always add
/healthz
(liveness) and
/readyz
(readiness) endpoints. The readiness probe should check downstream dependencies.

始终添加
/healthz
(存活检查)和
/readyz
(就绪检查)端点。就绪检查应验证下游依赖是否可用。

Part 2: Environment & Recipe Setup

第二部分:环境与Recipe设置

Initialize Radius

初始化Radius

bash
rad initialize
rad workspace create kubernetes default --group default --environment default
rad environment create myenv --namespace my-namespace   # if needed
rad environment switch myenv
bash
rad initialize
rad workspace create kubernetes default --group default --environment default
rad environment create myenv --namespace my-namespace   # 如有需要
rad environment switch myenv

Register Resource Types

注册资源类型

bash
undefined
bash
undefined

Download YAML from radius-resource-types, then register

从radius-resource-types下载YAML,然后注册

rad resource-type create Radius.Data/postgreSqlDatabases --from-file postgreSqlDatabases.yaml rad resource-type show Radius.Data/postgreSqlDatabases # verify
rad resource-type create Radius.Data/postgreSqlDatabases --from-file postgreSqlDatabases.yaml rad resource-type show Radius.Data/postgreSqlDatabases # 验证

Repeat for other repo-backed types such as:

对其他仓库托管的类型重复此操作,例如:

Radius.Data/mySqlDatabases

Radius.Data/mySqlDatabases

Radius.Storage/blobStorages

Radius.Storage/blobStorages

Radius.Security/secrets

Radius.Security/secrets

Radius.Compute/persistentVolumes

Radius.Compute/persistentVolumes

Radius.Compute/routes

Radius.Compute/routes

Radius.AI/agents

Radius.AI/agents

undefined
undefined

Generate Bicep Extensions

生成Bicep扩展

bash
rad bicep publish-extension --from-file postgreSqlDatabases.yaml --target radius-data.tgz
bash
rad bicep publish-extension --from-file postgreSqlDatabases.yaml --target radius-data.tgz

Then add the matching extension key in bicepconfig.json, for example:

然后在bicepconfig.json中添加对应的扩展键,例如:

"radiusData": "radius-data.tgz"

"radiusData": "radius-data.tgz"

"radiusStorage": "radius-storage.tgz"

"radiusStorage": "radius-storage.tgz"

"radiusSecurity": "radius-security.tgz"

"radiusSecurity": "radius-security.tgz"

"radiusAi": "radius-ai.tgz"

"radiusAi": "radius-ai.tgz"


Combine multiple types into one YAML (with `---` separator) to generate a single extension.

可以将多个类型合并到一个YAML文件中(使用`---`分隔),以生成单个扩展。

Publish and Register Recipes

发布并注册Recipe

Critical: Recipes registered from local file paths (
/tmp/recipe.bicep
) will NOT work. The Radius control plane runs inside Kubernetes and cannot access the host filesystem. Always publish to an OCI registry.
bash
undefined
关键注意事项:从本地文件路径(如
/tmp/recipe.bicep
)注册的Recipe无法正常工作。Radius控制平面运行在Kubernetes内部,无法访问主机文件系统。必须始终发布到OCI仓库。
bash
undefined

Publish to OCI registry

发布到OCI仓库

rad bicep publish --file kubernetes-postgresql.bicep
--target br:myregistry.azurecr.io/recipes/postgresql-kubernetes:latest
rad bicep publish --file kubernetes-postgresql.bicep
--target br:myregistry.azurecr.io/recipes/postgresql-kubernetes:latest

For local/insecure registries, add --plain-http

对于本地/非安全仓库,添加--plain-http参数

rad bicep publish --file kubernetes-postgresql.bicep
--target br:localhost:5001/recipes/postgresql-kubernetes:latest --plain-http
rad bicep publish --file kubernetes-postgresql.bicep
--target br:localhost:5001/recipes/postgresql-kubernetes:latest --plain-http

Register (use host.docker.internal for in-cluster access)

注册(使用host.docker.internal实现集群内访问)

rad recipe register postgresql
--resource-type Radius.Data/postgreSqlDatabases
--template-kind bicep
--template-path "host.docker.internal:5001/recipes/postgresql-kubernetes:latest"
--plain-http --environment myenv
undefined
rad recipe register postgresql
--resource-type Radius.Data/postgreSqlDatabases
--template-kind bicep
--template-path "host.docker.internal:5001/recipes/postgresql-kubernetes:latest"
--plain-http --environment myenv
undefined

Recipe Selection Guide

Recipe选择指南

Constitution SaysRecipe PlatformRecipe IaCExample
Azure + Terraform
azure-*
terraform/
azure-cache/terraform
Azure + Bicep
azure-*
bicep/
azure-cache/bicep
AWS + Terraform
aws-*
terraform/
aws-memorydb/terraform
Kubernetes (local)
kubernetes
bicep/
or
terraform/
kubernetes-redis/bicep
平台规范要求Recipe平台Recipe IaC示例
Azure + Terraform
azure-*
terraform/
azure-cache/terraform
Azure + Bicep
azure-*
bicep/
azure-cache/bicep
AWS + Terraform
aws-*
terraform/
aws-memorydb/terraform
Kubernetes(本地)
kubernetes
bicep/
terraform/
kubernetes-redis/bicep

Local Development with kind

使用kind的本地开发

1. Local OCI Registry

1. 本地OCI仓库

bash
docker run -d -p 5001:5000 --name radius-registry registry:2
curl http://localhost:5001/v2/_catalog   # verify
bash
docker run -d -p 5001:5000 --name radius-registry registry:2
curl http://localhost:5001/v2/_catalog   # 验证

2. Host Networking

2. 主机网络

localhost
inside a k8s pod does NOT reach the host machine. Use
host.docker.internal
for all registry and service URLs.
K8s Pod内部的
localhost
无法访问主机。所有仓库和服务URL请使用
host.docker.internal

3. Insecure Registry for containerd

3. 为containerd配置非安全仓库

bash
NODENAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')

docker exec $NODENAME mkdir -p /etc/containerd/certs.d/host.docker.internal:5001
docker exec $NODENAME bash -c 'cat > /etc/containerd/certs.d/host.docker.internal:5001/hosts.toml << EOF
[host."http://host.docker.internal:5001"]
  capabilities = ["pull", "resolve"]
  skip_verify = true
EOF'

docker exec $NODENAME bash -c \
  'sed -i "s|config_path = \"\"|config_path = \"/etc/containerd/certs.d\"|" /etc/containerd/config.toml'
docker exec $NODENAME systemctl restart containerd
bash
NODENAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')

docker exec $NODENAME mkdir -p /etc/containerd/certs.d/host.docker.internal:5001
docker exec $NODENAME bash -c 'cat > /etc/containerd/certs.d/host.docker.internal:5001/hosts.toml << EOF
[host."http://host.docker.internal:5001"]
  capabilities = ["pull", "resolve"]
  skip_verify = true
EOF'

docker exec $NODENAME bash -c \
  'sed -i "s|config_path = \"\"|config_path = \"/etc/containerd/certs.d\"|" /etc/containerd/config.toml'
docker exec $NODENAME systemctl restart containerd

4. Build and Push Images

4. 构建并推送镜像

bash
docker build -t myapp-backend:latest ./backend
docker tag myapp-backend:latest localhost:5001/myapp-backend:latest
docker push localhost:5001/myapp-backend:latest
In
app.bicep
, reference as
host.docker.internal:5001/myapp-backend:latest
.
bash
docker build -t myapp-backend:latest ./backend
docker tag myapp-backend:latest localhost:5001/myapp-backend:latest
docker push localhost:5001/myapp-backend:latest
app.bicep
中,将镜像引用为
host.docker.internal:5001/myapp-backend:latest

Environment Management Commands

环境管理命令

bash
rad environment list
rad environment show myenv
rad recipe list --environment myenv
rad recipe show postgresql --resource-type Radius.Data/postgreSqlDatabases --environment myenv
rad resource-type list
rad resource-type show Radius.Data/postgreSqlDatabases
rad workspace show

bash
rad environment list
rad environment show myenv
rad recipe list --environment myenv
rad recipe show postgresql --resource-type Radius.Data/postgreSqlDatabases --environment myenv
rad resource-type list
rad resource-type show Radius.Data/postgreSqlDatabases
rad workspace show

Part 3: Custom Resource Types & Recipes

第三部分:自定义资源类型与Recipe

Resource Type YAML Schema

资源类型YAML Schema

yaml
namespace: Radius.Data
types:
  postgreSqlDatabases:
    description: |
      A portable PostgreSQL database resource.
    apiVersions:
      '2025-08-01-preview':
        schema:
          type: object
          properties:
            environment:
              type: string
              description: "(Required) The Radius Environment ID."
            application:
              type: string
              description: "(Optional) The Radius Application ID."
            size:
              type: string
              enum: ['S', 'M', 'L']
              description: "(Optional) The size of the database."
            host:
              type: string
              description: The hostname.
              readOnly: true
            port:
              type: string
              description: The port.
              readOnly: true
            database:
              type: string
              description: The database name.
              readOnly: true
            username:
              type: string
              description: The username.
              readOnly: true
            password:
              type: string
              description: The password.
              readOnly: true
          required: [environment]
Conventions:
  • environment
    is always required
  • Input properties are cloud-agnostic, minimal
  • Output properties are marked
    readOnly: true
    — they become connection env vars
  • Combine multiple types in one YAML under the same namespace
yaml
namespace: Radius.Data
types:
  postgreSqlDatabases:
    description: |
      可移植的PostgreSQL数据库资源。
    apiVersions:
      '2025-08-01-preview':
        schema:
          type: object
          properties:
            environment:
              type: string
              description: "(必填) Radius环境ID。"
            application:
              type: string
              description: "(可选) Radius应用ID。"
            size:
              type: string
              enum: ['S', 'M', 'L']
              description: "(可选) 数据库规模。"
            host:
              type: string
              description: 主机名。
              readOnly: true
            port:
              type: string
              description: 端口。
              readOnly: true
            database:
              type: string
              description: 数据库名称。
              readOnly: true
            username:
              type: string
              description: 用户名。
              readOnly: true
            password:
              type: string
              description: 密码。
              readOnly: true
          required: [environment]
规范
  • environment
    始终为必填项
  • 输入属性与云无关,保持最小化
  • 输出属性标记为
    readOnly: true
    ,将成为连接环境变量
  • 同一命名空间下的多个类型可合并到一个YAML文件中

Recipe Directory Structure

Recipe目录结构

<resourceType>/
├── README.md
├── <resourceType>.yaml
└── recipes/
    ├── kubernetes/bicep/kubernetes-<type>.bicep
    ├── azure-<service>/bicep/azure-<service>.bicep
    └── aws-<service>/terraform/main.tf
<resourceType>/
├── README.md
├── <resourceType>.yaml
└── recipes/
    ├── kubernetes/bicep/kubernetes-<type>.bicep
    ├── azure-<service>/bicep/azure-<service>.bicep
    └── aws-<service>/terraform/main.tf

Recipe Context Object

Recipe上下文对象

context.resource.id            // Full resource ID
context.resource.name          // Resource name
context.resource.type          // e.g., "Radius.Data/postgreSqlDatabases"
context.resource.properties    // Developer-set properties from app.bicep
context.runtime.kubernetes.namespace  // Target namespace
Important: Use
context.resource.properties.*
(not
context.properties.*
).
context.resource.id            // 完整资源ID
context.resource.name          // 资源名称
context.resource.type          // 例如:"Radius.Data/postgreSqlDatabases"
context.resource.properties    // 从app.bicep中设置的开发者属性
context.runtime.kubernetes.namespace  // 目标命名空间
重要:使用
context.resource.properties.*
(而非
context.properties.*
)。

Bicep Recipe Template

Bicep Recipe模板

bicep
param context object

var size = contains(context.resource.properties, 'size') ? context.resource.properties.size : 'S'
var name = context.resource.name
var namespace = context.runtime.kubernetes.namespace

// ... deploy k8s resources ...

output result object = {
  properties: {
    host: '${name}-svc.${namespace}.svc.cluster.local'
    port: '5432'
    database: name
    username: 'admin'
    password: 'generated-password'
  }
}
bicep
param context object

var size = contains(context.resource.properties, 'size') ? context.resource.properties.size : 'S'
var name = context.resource.name
var namespace = context.runtime.kubernetes.namespace

// ... 部署K8s资源 ...

output result object = {
  properties: {
    host: '${name}-svc.${namespace}.svc.cluster.local'
    port: '5432'
    database: name
    username: 'admin'
    password: 'generated-password'
  }
}

Terraform Recipe Template

Terraform Recipe模板

hcl
variable "context" {
  type = any
}

locals {
  size      = try(var.context.resource.properties.size, "S")
  name      = var.context.resource.name
  namespace = var.context.runtime.kubernetes.namespace
}

output "result" {
  value = {
    properties = {
      host     = "${local.name}-svc.${local.namespace}.svc.cluster.local"
      port     = "5432"
      database = local.name
      username = "admin"
      password = "generated-password"
    }
  }
}
hcl
variable "context" {
  type = any
}

locals {
  size      = try(var.context.resource.properties.size, "S")
  name      = var.context.resource.name
  namespace = var.context.runtime.kubernetes.namespace
}

output "result" {
  value = {
    properties = {
      host     = "${local.name}-svc.${local.namespace}.svc.cluster.local"
      port     = "5432"
      database = local.name
      username = "admin"
      password = "generated-password"
    }
  }
}

Publishing and Registration

发布与注册

bash
undefined
bash
undefined

1. Publish recipe to OCI registry

1. 将Recipe发布到OCI仓库

rad bicep publish --file kubernetes-postgresql.bicep
--target br:myregistry.azurecr.io/recipes/postgresql-kubernetes:latest
rad bicep publish --file kubernetes-postgresql.bicep
--target br:myregistry.azurecr.io/recipes/postgresql-kubernetes:latest

2. Register resource type

2. 注册资源类型

rad resource-type create Radius.Data/postgreSqlDatabases --from-file manifest.yaml
rad resource-type create Radius.Data/postgreSqlDatabases --from-file manifest.yaml

3. Register recipe

3. 注册Recipe

rad recipe register postgresql
--resource-type Radius.Data/postgreSqlDatabases
--template-kind bicep
--template-path "myregistry.azurecr.io/recipes/postgresql-kubernetes:latest"
rad recipe register postgresql
--resource-type Radius.Data/postgreSqlDatabases
--template-kind bicep
--template-path "myregistry.azurecr.io/recipes/postgresql-kubernetes:latest"

4. Generate Bicep extension

4. 生成Bicep扩展

rad bicep publish-extension --from-file manifest.yaml --target radius-data.tgz
rad bicep publish-extension --from-file manifest.yaml --target radius-data.tgz

5. Test

5. 测试

rad run app.bicep

---
rad run app.bicep

---

Common Pitfalls

常见陷阱

ProblemCauseFix
extension "radius" is not recognized
Missing
bicepconfig.json
Create it with the Radius extension registry URL
RecipeDownloadFailed: not a valid repository/tag
Recipe registered from local file pathPublish to OCI registry, re-register
RecipeDownloadFailed: connection refused
localhost
used inside k8s pod
Use
host.docker.internal
instead
RecipeDownloadFailed: HTTPS required
containerd defaults to HTTPSConfigure
certs.d/hosts.toml
in kind node
property 'size' doesn't exist
Recipe expects property not set in app.bicepAdd the property or add a safe default in recipe
RecipeNotFoundFailure
No recipe registered for resource type
rad recipe register
ImagePullBackOff
Image not accessible from clusterPush to registry;
kind load
won't work with
Always
pull policy
CONNECTION_X_HOST
is empty
Using
Radius.Compute/containers
(JSON format)
Parse
CONNECTION_X_PROPERTIES
JSON blob instead
Bicep validation errors on
Radius.*
types
No Bicep extension generated
rad bicep publish-extension
container
vs
containers
schema error
Wrong property name for container type
Applications.Core
= singular
container
;
Radius.Compute
= plural
containers
map
问题原因解决方法
extension "radius" is not recognized
缺失
bicepconfig.json
使用Radius扩展仓库URL创建该文件
RecipeDownloadFailed: not a valid repository/tag
Recipe从本地文件路径注册发布到OCI仓库后重新注册
RecipeDownloadFailed: connection refused
在K8s Pod中使用了
localhost
改用
host.docker.internal
RecipeDownloadFailed: HTTPS required
containerd默认要求HTTPS在kind节点中配置
certs.d/hosts.toml
property 'size' doesn't exist
Recipe期望的属性未在app.bicep中设置添加该属性,或在Recipe中设置安全默认值
RecipeNotFoundFailure
未为资源类型注册Recipe执行
rad recipe register
ImagePullBackOff
集群无法访问镜像推送到仓库;
kind load
无法满足
Always
拉取策略的要求
CONNECTION_X_HOST
为空
使用了
Radius.Compute/containers
(JSON格式)
解析
CONNECTION_X_PROPERTIES
JSON Blob
Radius.*
类型出现Bicep验证错误
未生成Bicep扩展执行
rad bicep publish-extension
container
containers
Schema错误
容器类型的属性名称使用错误
Applications.Core
使用单数
container
Radius.Compute
使用复数
containers
映射

References

参考资料

TopicReferenceUse for
Bicep Patternsreferences/bicep-patterns.mdMulti-container apps, gateways, parameterization
App Definition Flowreferences/app-definition-flow.mdScaffolding
app.bicep
from environment and repo discovery
Connection Conventionsreferences/connection-conventions.mdEnv var formats, JSON parsing, portable code
Resource Type Catalogreferences/resource-type-catalog.mdAvailable types, schemas, properties
Local Developmentreferences/local-development.mdkind, local registry, containerd, Dockerfiles
Resource Type YAMLreferences/resource-type-yaml.mdYAML schema definition format
Recipe Authoringreferences/recipe-authoring.mdBicep/Terraform recipes, context object
Environment Configreferences/environment-config.mdWorkspaces, environments, namespaces
Cloud Providersreferences/cloud-providers.mdAzure, AWS credentials for Radius
Recipe Structurereferences/recipe-structure.mdDirectory layout in radius-resource-types
Contribution Guidereferences/contribution-guide.mdContributing to radius-resource-types
主题参考链接用途
Bicep模式references/bicep-patterns.md多容器应用、网关、参数化
应用定义流程references/app-definition-flow.md从环境和仓库发现搭建
app.bicep
连接规范references/connection-conventions.md环境变量格式、JSON解析、可移植代码
资源类型目录references/resource-type-catalog.md可用类型、Schema、属性
本地开发references/local-development.mdkind、本地仓库、containerd、Dockerfile
资源类型YAMLreferences/resource-type-yaml.mdYAML Schema定义格式
Recipe编写references/recipe-authoring.mdBicep/Terraform Recipe、上下文对象
环境配置references/environment-config.md工作区、环境、命名空间
云服务商references/cloud-providers.mdRadius的Azure、AWS凭证
Recipe结构references/recipe-structure.mdradius-resource-types中的目录布局
贡献指南references/contribution-guide.md向radius-resource-types贡献代码

Guardrails

约束规则

  • Always check the platform constitution before suggesting resource types, recipes, or cloud-specific patterns.
  • Use portable resource types (
    Radius.*
    ) instead of cloud-specific resources unless explicitly needed.
  • Never hardcode infrastructure details in application definitions — let recipes handle it.
  • Always include
    environment
    — required for all Radius resources.
  • Handle both connection env var formats (
    _PROPERTIES
    JSON and individual vars) for portability.
  • Set all recipe-expected properties in Bicep (e.g.,
    size
    ), or use safe defaults in recipes.
  • Always configure
    bicepconfig.json
    — the Radius Bicep extension won't resolve without it.
  • When scaffolding
    app.bicep
    , inspect before asking.
    Infer shared resources and container workloads from the workspace whenever possible.
  • When shared resources already exist in the environment, declare them with
    existing
    instead of provisioning duplicates.
  • When shared resources are declared in workspace files such as
    env.bicep
    or
    shared-resources.bicep
    , declare them with
    existing
    in the generated
    app.bicep
    instead of duplicating them there.
  • Always ask for the OCI registry host when it cannot be inferred from the repository.
  • Always ask before setting boolean AI options such as
    enableObservability
    when there is no clear project default.
  • Move long or multi-line prompt text into a parameter instead of embedding it directly in the AI agent resource.
  • When an app uses an AI agent plus shared data resources, prefer agent-to-resource connections over container-to-resource connections.
  • Never register recipes from local file paths — publish to an OCI registry first.
  • Use
    host.docker.internal
    instead of
    localhost
    for in-cluster access to host services.
  • Use
    --plain-http
    when working with insecure (HTTP) registries.
  • Generate Bicep extensions after registering resource types for IDE validation.
  • Keep resource type interfaces cloud-agnostic — cloud details belong in recipes, not schemas.
  • Always handle missing optional properties in recipes with safe defaults.
  • Use
    containers
    (plural map) for
    Radius.Compute
    and
    container
    (singular) for
    Applications.Core
    .
  • Test with
    rad run
    before deploying to production.
  • 始终先检查平台规范,再推荐资源类型、Recipe或云特定模式。
  • 使用可移植资源类型
    Radius.*
    )而非云特定资源,除非明确需要。
  • 永远不要在应用定义中硬编码基础设施细节,让Recipe处理这些内容。
  • 始终包含
    environment
    —— 所有Radius资源都需要该参数。
  • 同时支持两种连接环境变量格式
    _PROPERTIES
    JSON和独立变量)以保证可移植性。
  • 在Bicep中设置所有Recipe期望的属性(如
    size
    ),或在Recipe中使用安全默认值。
  • 始终配置
    bicepconfig.json
    —— 没有它,Radius Bicep扩展无法正常解析。
  • 搭建
    app.bicep
    时,先检查再询问
    。尽可能从工作区推断共享资源和容器工作负载。
  • 当共享资源已在环境中存在时,使用
    existing
    声明
    ,而非重复创建。
  • 当共享资源在
    env.bicep
    shared-resources.bicep
    等工作区文件中已声明时,在生成的
    app.bicep
    中使用
    existing
    声明
    ,而非重复创建。
  • 当无法从仓库推断时,始终询问OCI仓库地址
  • 当没有明确的项目默认值时,设置布尔AI选项(如
    enableObservability
    )前必须询问用户
  • 将长或多行提示词移至参数中,而非直接内嵌到AI Agent资源。
  • 当应用使用AI Agent加共享数据资源时,优先建立Agent到资源的连接,而非容器到资源的连接
  • 永远不要从本地文件路径注册Recipe —— 先发布到OCI仓库。
  • 使用
    host.docker.internal
    而非
    localhost
    实现集群内对主机服务的访问。
  • 使用
    --plain-http
    参数
    处理非安全(HTTP)仓库。
  • 注册资源类型后生成Bicep扩展,以支持IDE验证。
  • 保持资源类型接口与云无关 —— 云相关细节应放在Recipe中,而非Schema。
  • 在Recipe中始终处理缺失的可选属性,使用安全默认值。
  • Radius.Compute
    使用
    containers
    (复数映射)
    Applications.Core
    使用
    container
    (单数)。
  • 部署到生产环境前,使用
    rad run
    测试