Skip to content

End-to-end UDT feature spec #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: main
Choose a base branch
from

Conversation

zachcasper
Copy link
Contributor

Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
@zachcasper zachcasper requested review from a team as code owners February 10, 2025 22:28
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Copy link
Member

@brooke-hamilton brooke-hamilton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: typo: ingress

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very cool


**`webservice-resource-type.bicep`**:

`````yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this illustrating that composite types can be defined using YAML? would we recommend users against this and point them to defining composite types via Bicep/Terraform Recipes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is illustrating that the composite resource type has an interface, this YAML, and an implementation—either in Terraform or Bicep.

+ const: true
+ then:
+ required: hostname
```
Copy link
Contributor

@lakshmimsft lakshmimsft May 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concern on this. if/then is not recognised by OpenAPI3.0 spec. Something similar may be achieved perhaps with:

      # …
      required:
        - environment
        - container
      anyOf:
        - properties:
            ingress:
              const: false
          # when ingress is false, no extra requirement
        - properties:
            ingress:
              const: true
          required:
            - hostname

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We authored schema design based on openapi 3.0 which brings in structural schema. 3.1 is not widely adopted in field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. The if/then/else construct is much easier for users than the oneOf/anyOf/allOf. We can discuss in the technical design. If it's not feasible to do if/then/else than anyOf is acceptable.


**Rename of template-kind and template-path** – Radius is not opinionated about which infrastructure as code solution to use. Therefore, it is important that Radius is not biased towards one solution versus another. The parameter `--template-kind` and `--template-path` are biased towards Bicep as Bicep files are called templates and Terraform files are configurations.

Given this, the `--template-kind` and `--template-path` arguments will be renamed `--recipe-kind` and `--recipe-path`. The previous commands will be retained for backwards compatibility.
Copy link
Contributor

@kachawla kachawla May 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous commands will be retained for backwards compatibility.

Do we eventually plan to deprecate older version of this command?

Comment on lines 907 to 910
connection: {
jira:
source: jira.id
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What functionality does this block enable for users when it's defined?


**Retirement of named recipes** – Today, Radius supports named recipes. When deploying a portable resource type, developers can override the default recipe by specifying a recipe name in their application definition. This enables developers to punch through the separation of concerns between platform and developers. Based on strong user feedback, user-defined resource types will not implement the ability to punch through and use alternate recipes.

Furthermore, once portable resource types are refactored into user-defined resource types, the ability to specify a recipe name will be retired. The command will change from ``rad recipe register <recipeName>` to `rad recipe register`. This also has the benefit of not having to build developer documentation for discovering available recipes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worry that taking away the ability to punch through will cause issues for users down the line who want to use this functionality in ways we don't fully understand yet

> [!CAUTION]
>
> Today, Radius enforces the ARM API versioning standard. From the [source code](https://github.com/radius-project/radius/blob/main/pkg/cli/manifest/validation.go#L33) `An API version must be a date in YYYY-MM-DD format, and may optionally have the suffix '-preview'. Example: 2025-01-01"`. However, Kubernetes and most cloud-native project follow a [different versioning scheme](https://kubernetes.io/docs/reference/using-api/). The [Terraform versioning scheme](https://developer.hashicorp.com/terraform/plugin/best-practices/versioning) is similar to Kubernetes. Because Radius is cloud provider-agnostic, Radius will not enforce a specific API versioning scheme on the user.
>
Copy link
Contributor

@nithyatsu nithyatsu May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to confirm this. Since UCP has a long term vision of replacing ARM, we might still want radius resource versioning to be compliant with ARM.

name: 'jira'
}

// webservice resource, not core container
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If webservices deploys multiple containers front-end, reverse-proxy and security scanner,
how would we know which container to set the environement variable on?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why my webservice recipe manually sets the environment variables.

zachcasper added 6 commits May 9, 2025 13:26
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
application:
type: string
description: "Optional: The application which the resource is associated with"
connectionString:
Copy link
Contributor

@nithyatsu nithyatsu May 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

connectionString is outputs of recipe (here without a recipe, something thats accessible?), and marked readonly, correct?

Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
Signed-off-by: Zach Casper <zachcasper@microsoft.com>
| ------------------------------------------------------ | ------------------------------------------ |
| `CONNECTIONS_ORDERSDB_PROPERTIES_ENVIRONMENT` | `ordersDB.properties.environment` |
| `CONNECTIONS_ORDERSDB_PROPERTIES_APPLICATION` | `ordersDB.properties.application` |
| `CONNECTIONS_ORDERSDB_PROPERTIES_DATABASE` | `ordersDB.properties.database` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we decided to leave out env id and app id right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

today for portable resources what we inject is CONNECTIONS_ORDERSDB_DATABASE, there is no "PROPERTIES" - Did we want it different for UDTs?

Copy link
Contributor

@nithyatsu nithyatsu Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on yesterday's discussion, confirming CONNECTION_ORDERSDB_DATABASE for env names and context.resource.connections.ordersDB.database for recipe context. We are leaving out "properties" since it is redundant.

Copy link
Member

@brooke-hamilton brooke-hamilton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀


**Summary**

All resource in Radius will support connections to other resources, no matter the type. When a connection exists from a connecting resource (destination) to another connected resource (source), the source resource's properties will be available within the destination resource. In the case of `Applications.Core/containers` these properties are manifested as environment variables.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
All resource in Radius will support connections to other resources, no matter the type. When a connection exists from a connecting resource (destination) to another connected resource (source), the source resource's properties will be available within the destination resource. In the case of `Applications.Core/containers` these properties are manifested as environment variables.
All resources in Radius will support connections to other resources, no matter the type. When a connection exists from a connecting resource (destination) to another connected resource (source), the source resource's properties will be available within the destination resource. In the case of `Applications.Core/containers` these properties are manifested as environment variables.


The following environment variables are automatically created in the container:

| Environment Variable Name | Property Name |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will nested properties be displayed, especially arrays, like ordersDB.properties.fruit.[0] = 'orange'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONNECTIONS_ORDERSDB_PROPERTIES_CREDENTIALS_USERNAME is an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For arrays, I believe in OpenAPI every item has a name correct?


When a developer adds a connection to a `Applications.Core/containers` resource, environment variables for each of the source resource's properties are created within the environment.

For example, the developer creates a connection to the PostgreSQL resource type from User Story 1.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from User Story 1

Might be helpful to just paste the whole type here again to make it easier to follow/read.


If the developer prefers for these environment variables to not be created, he/she can set the existing `disableDefaultEnvVars` boolean property to TRUE.

### User Story 9 – Connections into recipes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would help if you could extend the example to include a real scenario of how a user would use it, and an example of the webservice UDT definition.


If the developer prefers for these environment variables to not be created, he/she can set the existing `disableDefaultEnvVars` boolean property to TRUE.

### User Story 9 – Connections into recipes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a third scenario for UDT to UDT connections, or does this cover that?

| `CONNECTIONS_ORDERSDB_PROPERTIES_PORT` | `ordersDB.properties.port` |
| `CONNECTIONS_ORDERSDB_PROPERTIES_CREDENTIALS_USERNAME` | `ordersDB.properties.credentials.username` |
| `CONNECTIONS_ORDERSDB_PROPERTIES_CREDENTIALS_PASSWORD` | `ordersDB.properties.credentials.password` |

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the list of available env vars are defined in the UDT type spec?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, all properties are automatically exported as connection vars


**Summary**

All resource in Radius will support connections to other resources, no matter the type. When a connection exists from a connecting resource (destination) to another connected resource (source), the source resource's properties will be available within the destination resource. In the case of `Applications.Core/containers` these properties are manifested as environment variables.
Copy link
Contributor

@lakshmimsft lakshmimsft Jun 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: We are creating env variables for all udt properties which are simple types: int, float, string


**Summary**

All resource in Radius will support connections to other resources, no matter the type. When a connection exists from a connecting resource (destination) to another connected resource (source), the source resource's properties will be available within the destination resource. In the case of `Applications.Core/containers` these properties are manifested as environment variables.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be "destination's resource's properties will be available within the source resource"

* `context.resource.connections.ordersDB.properties.size`
* `context.resource.connections.ordersDB.properties.host`
* `context.resource.connections.ordersDB.properties.port`
* `context.resource.connections.ordersDB.properties.credentials.username`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no properties here for example context.resource.connections.ordersDB.properties.size ---> context.resource.connections.ordersDB.size

Also, we decided to leave out standard properties:
context.resource.connections.ordersDB.properties.environment
context.resource.connections.ordersDB.properties.application

nithyatsu added a commit to radius-project/radius that referenced this pull request Jun 27, 2025
# Description

This PR adds support for UDt to UDT connections. 

It also adds E2E covering:

1. container2udt connection ( just bicep. The changes are in container's
rendering, therefore the recipe language does not matter)
2. udt2udt connection with bicep recipes
3. udt2udt connection with terraform recipes

Design radius-project/design-notes#81 refer ##
Scenario 3 – Connections
## Type of change

- This pull request adds or changes features of Radius and has an
approved issue (issue link required).


<!--

Please update the following to link the associated issue. This is
required for some kinds of changes (see above).

-->

Partially Fixes: #6688

## Contributor checklist
Please verify that the PR meets the following requirements, where
applicable:

<!--
This checklist uses "TaskRadio" comments to make certain options
mutually exclusive.
See:
https://github.com/mheap/require-checklist-action?tab=readme-ov-file#radio-groups
For details on how this works and why it's required.
-->

- An overview of proposed schema changes is included in a linked GitHub
issue.
    - [X] Yes <!-- TaskRadio schema -->
    - [ ] Not applicable <!-- TaskRadio schema -->
- A design document PR is created in the [design-notes
repository](https://github.com/radius-project/design-notes/), if new
APIs are being introduced.
    - [X] Yes <!-- TaskRadio design-pr -->
    - [ ] Not applicable <!-- TaskRadio design-pr -->
- The design document has been reviewed and approved by Radius
maintainers/approvers.
    - [X] Yes <!-- TaskRadio design-review -->
    - [ ] Not applicable <!-- TaskRadio design-review -->
- A PR for the [samples
repository](https://github.com/radius-project/samples) is created, if
existing samples are affected by the changes in this PR.
    - [X] Yes <!-- TaskRadio samples-pr -->
    - [ ] Not applicable <!-- TaskRadio samples-pr -->
- A PR for the [documentation
repository](https://github.com/radius-project/docs) is created, if the
changes in this PR affect the documentation or any user facing updates
are made.
    - [X] Yes <!-- TaskRadio docs-pr -->
    - [ ] Not applicable <!-- TaskRadio docs-pr -->
- A PR for the [recipes
repository](https://github.com/radius-project/recipes) is created, if
existing recipes are affected by the changes in this PR.
    - [ ] Yes <!-- TaskRadio recipes-pr -->
    - [X] Not applicable <!-- TaskRadio recipes-pr -->

---------

Signed-off-by: nithyatsu <nithyasu@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.