name: app-modeling description: > Analyze a source code repository and generate a Radius application definition (.radius/app.bicep). Use when asked to create an application definition, model an application for Radius, or generate a Radius Bicep file. Resolves resource types from radius-project/resource-types-contrib and follows deterministic rules for validated output.
Radius Application Modeling
Use this skill to generate a Radius application definition (app.bicep) from a source code repository.
Output Format
Your entire visible response must follow this exact sequence. No headings, no step labels, no explanations, no source analysis, no "Let me read..." preamble.
- Say: I will create an application definition for
<app-name>. - Say: First, let me review the platform constitution.
- Show exactly these lines as a single blockquote:
Read cloud-native application architecture patterns. Read available resource types. Read resource types composition rules. Read resource types dependencies. Read naming conventions. Read secret handling requirements.
- Say: I see this repository has a single application called
<app-name>. - Say: I will identify what abstract application resources this application uses.
- Say: It has these application resources:
- List resources as a numbered list (e.g. "1. Container: todo-list-frontend")
- Say: An application definition has been created for
<app-name>. - Output the
.radius/app.bicepcode block. - Say: Would you like me to create a pull request with this file?
That is the COMPLETE chat response. Nothing before step 1, nothing after step 10. Do NOT automatically create a pull request. Wait for the user to confirm.
If the user confirms, create a pull request adding .radius/app.bicep to the repository. The PR title should be Add Radius application definition. The PR body should say Add .radius/app.bicep for <app-name>. — nothing else.
Internal Workflow (do NOT show these steps to the user)
Internally, before producing the output above:
- Analyze the source repository (package manifest, Dockerfile/compose, entry point, persistence layer, env vars).
- Classify into exactly one architecture pattern. Read architecture-patterns.md.
- Resolve resource types from
radius-project/resource-types-contrib— MUST match existing schemas. Read only the relevant YAML schema files. - Read bicep-structure-rules.md for correct Bicep structure.
- Read naming-conventions.md and apply the Deterministic Naming Rules below.
- Read secrets-handling.md.
- Generate the Bicep and validate against the checklist.
Then produce the output in the exact format above. Do NOT output anything while performing these steps.
Deterministic Naming Rules
These rules eliminate ambiguity. Apply them exactly.
Symbolic names (left side of = in Bicep)
| Resource | Symbolic name |
|---|---|
| Application | <shortName>App where <shortName> is the app name without hyphens, camelCase (e.g., todo-list-app → todoApp) |
| Container | <shortName>Container (e.g., todoContainer) |
| Container image | demoImage (always) |
| Database | database (always) |
| Database secret | dbSecret (always) |
| Route | <shortName>Route (e.g., todoRoute) |
Resource name properties (string values in Bicep)
| Resource | Name value |
|---|---|
| Application | Repository name in kebab-case (e.g., 'todo-list-app') |
| Container | '<app-name>-frontend' for single-container apps (e.g., 'todo-list-frontend') |
| Container image | 'demo-image' (always) |
| Database | Short name of the database engine: 'mysql', 'postgres', 'neo4j' |
| Database secret | 'dbsecret' (always) |
Connection keys
| Connection | Key |
|---|---|
| Database | mysqldb, postgresdb, neo4jdb (engine name + db) |
| Container image | demoContainerImage (always) |
Other fixed values
| Field | Value |
|---|---|
| Database secret USERNAME | 'todo_list_app_user' (always) |
Container key in containers map |
Short name derived from app (e.g., todo for todo-list-app) |
Port key in ports map |
web (always, for HTTP) |
build.context for containerImages |
'/app/demo' (always) |
Extension order
Always declare extensions in this exact order:
extension radiusextension radiusComputeextension radiusSecurityextension radiusData
Resource Type Resolution
Built-in types (from radius-project/radius)
| Need | Resource Type | API Version |
|---|---|---|
| Application grouping | Applications.Core/applications |
2023-10-01-preview |
Applications.Core/applications is built into Radius. It uses extension radius — no additional extension needed. Its API version is 2023-10-01-preview. Do NOT use Radius.Core/applications — it does not exist.
Extensible types (from radius-project/resource-types-contrib)
Read the resource type YAML schema files from the radius-project/resource-types-contrib repository. Each resource type has a YAML file at <Category>/<typeName>/<typeName>.yaml.
| Need | Resource Type | Schema file in resource-types-contrib |
|---|---|---|
| Container images (build from Dockerfile) | Radius.Compute/containerImages |
Compute/containerImages/containerImages.yaml (PR #126 — read from willdavsmith:containerimages-v2 branch until merged) |
| Containers | Radius.Compute/containers |
Compute/containers/containers.yaml |
| MySQL | Radius.Data/mySqlDatabases |
Data/mySqlDatabases/mySqlDatabases.yaml |
| PostgreSQL | Radius.Data/postgreSqlDatabases |
Data/postgreSqlDatabases/postgreSqlDatabases.yaml |
| Neo4j | Radius.Data/neo4jDatabases |
Data/neo4jDatabases/neo4jDatabases.yaml |
| Persistent storage | Radius.Compute/persistentVolumes |
Compute/persistentVolumes/persistentVolumes.yaml |
| External ingress | Radius.Compute/routes |
Compute/routes/routes.yaml |
| Secrets | Radius.Security/secrets |
Security/secrets/secrets.yaml |
This is the COMPLETE list. Do NOT use any type not listed above. Do NOT invent properties. All extensible types use API version 2025-08-01-preview.
Extension naming
Bicep extensions are named by namespace, NOT by individual type:
| Namespace | Extension name |
|---|---|
Applications.Core |
radius |
Radius.Compute |
radiusCompute |
Radius.Data |
radiusData |
Radius.Security |
radiusSecurity |
Use extension radiusCompute — NOT extension containerImages or extension containers.
app.bicep Structure (mandatory order)
Declare resources in this order (do NOT output this as code — it is only for your reference):
- Extensions:
radius, thenradiusCompute,radiusSecurity,radiusData(only those needed) - Params:
environment, then@secure() passwordif needed, then@description(...) imageif needed - Application resource (
Applications.Core/applications@2023-10-01-preview) — always exactly one - Data / infrastructure resources (databases, caches)
- Secret resources (database credentials, API keys)
- Container image resources (if building from Dockerfile)
- Container resources (with connections to images and infra)
- Routes (only if external ingress needed)
Rules:
- Always start with
extension radiusthen namespace-level extensions in the fixed order, then params. - Always declare exactly ONE
Applications.Core/applications@2023-10-01-previewresource. - If the app has a Dockerfile but no published image, add a
Radius.Compute/containerImagesresource. Use aparam image stringfor the image reference. The container must reference the image viademoImage.properties.imageand have a connection todemoImage.id. - For database credentials, create a
Radius.Security/secretsresource and reference it viasecretNameon the database resource. - Use
@secure() paramfor passwords — NEVER hardcode them. - For each container service, emit exactly one
Radius.Compute/containersresource. - For each backing data store, emit the matching
Radius.Data/*resource. - Only add
Radius.Compute/routesif the app needs external ingress.
Connections
Wire containers to infrastructure via connections. Read connection-conventions.md for the correct env var format.
Rules:
- NEVER duplicate auto-injected env vars with manual
enventries. - Only add explicit
enventries for app-specific variables NOT covered by connection auto-injection.
Secrets
Read secrets-handling.md.
Database resources reference secrets via secretName: dbSecret.name. Username is always 'todo_list_app_user'. Use @secure() param for the password.
Bicep Structure Rules
Read bicep-structure-rules.md for all structural rules.
Validation Checklist
Before outputting, verify ALL:
- Application resource uses
Applications.Core/applications@2023-10-01-preview - Every
Radius.*type matches a YAML schema inresource-types-contrib -
Radius.*types use2025-08-01-preview;Applications.Coreuses2023-10-01-preview - Extensions are in order:
radius,radiusCompute,radiusSecurity,radiusData - All names follow the Deterministic Naming Rules exactly
-
param environment stringis declared -
@secure() param password stringdeclared if database credentials are needed -
param image stringdeclared if building container images - Exactly one
Applications.Core/applicationsresource - Database resources have
secretNamereferencingdbSecret.name - Secret USERNAME is
'todo_list_app_user' -
connectionsis a top-level property underproperties, NOT insidecontainers -
connectionsis an object map, NOT an array - Container images use
param image string, not hardcoded - Ports use
containerPort, NOTport -
build.contextis'/app/demo' - No comments or explanations in the generated Bicep
- No source analysis, step headings, or reasoning shown in chat
Guardrails
- Use
Applications.Core/applications@2023-10-01-preview— NOTRadius.Core/applications. - Do NOT set readOnly properties.
- Do NOT reference readOnly properties of other resources in Bicep.
- Do NOT use array syntax where the schema specifies object maps.
- Do NOT place
connectionsinsidecontainers. - Do NOT include comments in generated Bicep.
- Do NOT use a bare runtime base image when the app has a Dockerfile.
- Do NOT use
extension containerImagesorextension containers— useextension radiusCompute. - Do NOT generate or output bicepconfig.json.
- ALWAYS create
Radius.Security/secretsfor database credentials. - ALWAYS use
@secure() paramfor passwords. - ALWAYS use
param image stringfor container image references when building from Dockerfile.
Example
Read todo-list-app-example.md for a complete worked example. The generated Bicep in that example is the expected correct output for dockersamples/todo-list-app.