Skip to content

clarify rad deploy environment selection when switching scopes #10307

Closed

Description

@nithyatsu

Overview of feature request

Today, we have the below commands in rad cli

rad group create my-group
rad group switch my-group
rad env create my-env
rad env switch my-env

After creating the group and environment, we make the choice to use them as current context using the expilicit rad <env|group> switch. This can be sometime confusing.

For instance, consider the below sequence:

rad group create my-group
rad group switch my-group

At this point, we are in scope my-group. This means

  • rad env create, the environment resource would be created in the scope /resourceGroups/my-group.
  • rad deploy uses the environment my-group in the same scope /resourceGroups/my-group/providers/applications.core/environment/my-env
rad env create my-env
rad env switch my-env
rad deploy app.bicep

Continue with subequent commands listed below:

rad group create another-group
rad group switch another-group
rad env create my-env
# do not do a rad env switch
rad deploy app.bicep

In the above sequence of commands, rad group switch is effective and my-environment is created as a child resource in this scope ( /resourceGroups/another-group/providers/applications.core/environment/my-env).

However, rad deploy app.bicep will still use the environment in the old scope (with same name) since we missed the rad env switch. rad deploy output only specifies the name of the environment and not full ID, so it is easy to be misinterpreted.

This can be a confusing user experience and needs a fix.

Note: An application should be able to use environment in scopes different from the scope where it is deployed. We have a -e flag for rad deploy which is used to deploy the application using an environment in different scope.

Acceptance criteria

No response

Additional context

No response

Would you like to support us?

  • Yes, I would like to support you

AB#16938

Activity

  1. added
    featureThis issue describes a feature request in Radius
    on Sep 2, 2025
  2. radius-triage commented on Sep 2, 2025

    @radius-triage

    👋 @nithyatsu Thanks for filing this feature request.

    A project maintainer will review this feature request and get back to you soon.

    We also welcome community contributions! If you would like to pick this item up sooner and submit a pull request, please visit our contribution guidelines and assign this to yourself by commenting "/assign" on this issue.

    For more information on our triage process please visit our triage overview

  3. changed the title [-]revisit rad environment switch behavior[/-] [+]rad deploy should be more explicit about the environment in use. [/+] on Sep 2, 2025
  4. changed the title [-]rad deploy should be more explicit about the environment in use. [/-] [+]rad deploy should be more explicit about the environment in use[/+] on Sep 2, 2025
  5. changed the title [-]rad deploy should be more explicit about the environment in use[/-] [+]Improve context Switching Behavior in rad cli to prevent confusing environment usage[/+] on Sep 2, 2025
  6. changed the title [-]Improve context Switching Behavior in rad cli to prevent confusing environment usage[/-] [+]Improve context switching behavior in rad cli to prevent confusing environment usage for rad deploy[/+] on Sep 2, 2025
  7. changed the title [-]Improve context switching behavior in rad cli to prevent confusing environment usage for rad deploy[/-] [+]Improve scope switching behavior in rad cli to prevent confusing environment usage for rad deploy[/+] on Sep 2, 2025
  8. changed the title [-]Improve scope switching behavior in rad cli to prevent confusing environment usage for rad deploy[/-] [+]Clarify rad deploy environment selection when switching scopes[/+] on Sep 2, 2025
  9. changed the title [-]Clarify rad deploy environment selection when switching scopes[/-] [+]clarify rad deploy environment selection when switching scopes[/+] on Sep 2, 2025
  10. radius-triage commented on Sep 2, 2025

    @radius-triage

    👋 @nithyatsu we need more information.

    To help us investigate further, we need additional information to reproduce or understand this issue. Please ensure you have steps to reproduce and information about your OS, rad CLI version, and runtime version.

    A project maintainer will reply on this issue soon to ask for additional specifics if needed.

    For more information on our triage process please visit our triage overview

  11. zachcasper commented on Sep 2, 2025

    @zachcasper
    Contributor

    Reviewing current behavior:

    • rad group create: Creates a group and does not change the workspace
    • rad environment create: Creates an environment in the current group. Does not change the workspace.

    rad workspace show shows the environment but not the group. It will show an environment name even if it is not valid. For example:

    $ rad workspace create kubernetes dev --context $(kubectl config current-context) -g group -e dev
    Creating workspace...
    Set "dev" as current workspace
    
    $ rad group create test
    creating resource group "test" in workspace "dev"...
    
    resource group "test" created
    
    $ rad group switch test
    Switched to resource group "test"
    
    $ rad environment create test
    
    Creating Environment...
    Successfully created environment "test" in resource group "test"
    
    $ rad environment show
    The environment "dev" was not found or has been deleted.
    

    The root of the problem is that we are treating resource groups and environments as two independent things. When in fact, it's a hierarchy.

    I see two options moving forward:

    1. Clean up the CLI output. For example, when creating an environment:
    $ rad environment create dev
    Created the 'dev' environment in the 'default' resource group. 
    Use `rad environment switch` to update the current workspace to use the new environment.
    
    1. When creating a group or an environment, automatically switch to that group or environment.
    $ rad environment create dev
    Created the 'dev' environment in the 'default' resource group. 
    Updated the current workspace 'myWorkspace' to use the 'dev' environment. Use `rad environment switch` to update the current workspace to use the new environment.
    
    1. Rework the way environments and resource groups work. These two concepts are redundant and cause significant user friction. In an ideal Radius world, the user would just create an environment and not have to worry about resource groups at all. Additionally, the workspace could be simplified to be just the current environment. Imagine:
    $ rad environment create dev
    Created the 'dev' environment and resource group.
    Current working environment is set to 'dev'. Use `rad environment switch` to change.
    
    $ rad environment list
    ENVIRONMENT   RESOURCE GROUP   KUBERNETES   CURRENT
    dev           dev              myCluster    <--
    
    $ rad environment create test
    Created the 'test' environment and resource group.
    Current working environment is set to 'test'. Use `rad environment switch` to change.
    
    $ rad environment show
    ENVIRONMENT   RESOURCE GROUP   KUBERNETES   CURRENT
    dev           dev              myCluster
    test          test             myCluster    <--
    
    $ rad environment switch dev
    Current working environment is set to 'dev'. 
    
    $ rad environment show
    ENVIRONMENT   RESOURCE GROUP   KUBERNETES   CURRENT
    dev           dev              myCluster    <--
    test          test             myCluster    
    
    $ rad workspace show
    Error: Unknown command. Use `rad --help` for a list of commands.
    

    Key changes demonstrated here:

    • An environment always resided in its own resource group
    • Current working environment is used rather than workspaces
    • Users switch between environments. They do not switch workspaces or groups.
  12. added
    triagedThis issue has been reviewed and triaged
    and removed on Sep 29, 2025
  13. radius-triage commented on Sep 29, 2025

    @radius-triage

    👍 We've reviewed this issue and have agreed to add it to our backlog. Please subscribe to this issue for notifications, we'll provide updates when we pick it up.

    We also welcome community contributions! If you would like to pick this item up sooner and submit a pull request, please visit our contribution guidelines and assign this to yourself by commenting "/assign" on this issue.

    For more information on our triage process please visit our triage overview

  14. nicolejms commented on Sep 11, 2026

    @nicolejms
    Contributor

    Closing following an issue audit against Radius main at ec97901 and the current referenced implementations.

    The concrete ambiguity in the report is addressed: environment lookup now resolves the selected environment to its full resource ID and the deployment progress message prints that ID, exposing the owning group even when the deployment group differs. Full Radius.Core IDs are looked up in their own scope, with a regression test and merged fix; Applications.Core IDs are also passed through. Group switching intentionally does not change the independently selected environment, preserving the issue's explicit cross-group requirement. The broader workspace redesign alternatives in comments are not necessary to resolve this specified misleading deploy output.

    Evidence:

    • Selected result becomes a full environment ID:
      // Determine which one to use and check for conflicts
      if result.ApplicationsCoreEnv != nil && result.RadiusCoreEnv != nil {
      var appCoreID, radiusCoreID string
      if result.ApplicationsCoreEnv.ID != nil {
      appCoreID = *result.ApplicationsCoreEnv.ID
      }
      if result.RadiusCoreEnv.ID != nil {
      radiusCoreID = *result.RadiusCoreEnv.ID
      }
      return nil, clierrors.Message("Conflict detected: Environment '%s' exists in both Applications.Core and Radius.Core providers. Please specify the full resource ID to disambiguate:\n Applications.Core: %s\n Radius.Core: %s",
      envNameOrID, appCoreID, radiusCoreID)
      }
      if result.ApplicationsCoreEnv != nil {
      result.UseApplicationsCore = true
      if result.ApplicationsCoreEnv.ID != nil {
      r.EnvironmentNameOrID = *result.ApplicationsCoreEnv.ID
      }
      } else if result.RadiusCoreEnv != nil {
      result.UseApplicationsCore = false
      if result.RadiusCoreEnv.ID != nil {
      r.EnvironmentNameOrID = *result.RadiusCoreEnv.ID
      }
    • Progress prints the resolved ID:
      progressText := ""
      if r.ApplicationName == "" {
      progressText = fmt.Sprintf(
      "Deploying template '%v' into environment '%v' from workspace '%v'...\n\n"+
      "Deployment In Progress...", displayPath, r.EnvironmentNameOrID, r.Workspace.Name)
      } else {
      progressText = fmt.Sprintf(
      "Deploying template '%v' for application '%v' and environment '%v' from workspace '%v'...\n\n"+
      "Deployment In Progress... ", displayPath, r.ApplicationName, r.EnvironmentNameOrID, r.Workspace.Name)
      }
    • Cross-group lookup preserves scope encoded in a full ID:
      // Check Applications.Core environment
      if fetchAppCoreEnv {
      // If its ID, use it directly, otherwise construct ID from name
      var appCoreEnvID string
      if !isID {
      appCoreEnvID = r.constructApplicationsCoreEnvironmentID(envNameOrID)
      } else {
      appCoreEnvID = envNameOrID
      }
      appCoreEnv, err := r.getApplicationsCoreEnvironment(ctx, appCoreEnvID)
      if err != nil {
      if !clients.Is404Error(err) {
      return nil, err
      }
      }
      if appCoreEnv != nil {
      result.ApplicationsCoreEnv = appCoreEnv
      }
      }
      if fetchRadiusCoreEnv {
      // If it's a full ID, look it up in the scope encoded in the ID itself (which may
      // differ from the workspace/--group scope, e.g. when the environment lives in a
      // different resource group than the one being deployed into). Otherwise, resolve
      // the name within the current workspace scope.
      var radCoreEnvName string
      radCoreScope := r.Workspace.Scope
      if isID {
      radCoreEnvName = envID.Name()
      radCoreScope = envID.RootScope()
      } else {
      radCoreEnvName = envNameOrID
      }
      radiusCoreEnv, err := r.getRadiusCoreEnvironment(ctx, radCoreScope, radCoreEnvName)
      if err != nil {
      if !clients.Is404Error(err) {
      return nil, err
      }
      }
      if radiusCoreEnv != nil {
      result.RadiusCoreEnv = radiusCoreEnv
    • Regression coverage:
      // Test_FetchEnvironment_RadiusCoreEnvironmentUsesOwnGroup is a regression test for
      // https://github.com/radius-project/radius/issues/12573: a Radius.Core environment
      // referenced by full ID (e.g. the workspace's stored default environment) must be looked
      // up in the resource group encoded in that ID, not in the (possibly different)
      // --group-overridden workspace scope used for the deployment itself.
      func Test_FetchEnvironment_RadiusCoreEnvironmentUsesOwnGroup(t *testing.T) {
      envScope := "/planes/radius/local/resourceGroups/default"
      envID := envScope + "/providers/Radius.Core/environments/default"
      deployScope := "/planes/radius/local/resourceGroups/test"
      // Only succeed when queried in the environment's own scope; 404 for any other scope
      // (such as the --group-overridden deploy scope) to catch a regression.
      envServer := corerpfake.EnvironmentsServer{
      Get: func(
      _ context.Context,
      rootScope string,
      environmentName string,
      _ *v20250801preview.EnvironmentsClientGetOptions,
      ) (resp azfake.Responder[v20250801preview.EnvironmentsClientGetResponse], errResp azfake.ErrorResponder) {
      // The fake HTTP transport strips the leading slash from the rootScope path
      // segment, so compare against the trimmed form.
      if rootScope != strings.TrimPrefix(envScope, "/") {
      errResp.SetError(fmt.Errorf("environment not found"))
      errResp.SetResponseError(404, "Not Found")
      return
      }
      resp.SetResponse(200, v20250801preview.EnvironmentsClientGetResponse{
      Name: to.Ptr(environmentName),
      ID: to.Ptr(envID),
      }, nil)
      return
      },
      }
      factory, err := test_client_factory.NewRadiusCoreTestClientFactory(
      deployScope,
      func() corerpfake.EnvironmentsServer { return envServer },
      nil,
      )
      require.NoError(t, err)
      runner := &Runner{
      RadiusCoreClientFactory: factory,
      Workspace: &workspaces.Workspace{
      // Simulates `-g test` overriding the deploy scope while the workspace's
      // default environment still lives in the "default" resource group.
      Scope: deployScope,
      },
      }
      result, err := runner.FetchEnvironment(t.Context(), envID)
    • Merged related scope fix, not a workspace redesign: Fix rad deploy resolving Radius.Core environment ID in the wrong group #12599
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureThis issue describes a feature request in RadiustriagedThis issue has been reviewed and triaged

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions