Skip to content
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

Add clusterName parameter to recipe context #6321

Open
Tracked by #11
Reshrahim opened this issue Mar 16, 2023 · 0 comments
Open
Tracked by #11

Add clusterName parameter to recipe context #6321

Reshrahim opened this issue Mar 16, 2023 · 0 comments

Comments

@Reshrahim
Copy link
Contributor

Reshrahim commented Mar 16, 2023

Overview of the feature request

For AWS redis recipe, we build a subnet group from the cluster's existing subnet group so that both the app and the memoryDB are within the same VPC and the security group to talk to each other. If we think through the experience in real time, a developer has to inject eksClusterName as a parameter to consume this recipe. The cluster information might not be easily available to a developer as they are created and administered by Operators. This feature request is to have the cluster name as part of context.runtime.kubernetes so that an operator uses the cluster information directly from the runtime context and the developer doesn't have to pass it as parameter

Current 'as-is' experience

Below is the recipe for provisioning a memory db cluster. This recipe is created in a simplistic way by leveraging the EKS cluster's default VPC and security group without having to create a separate VPC

import aws as aws

@description('Radius-provided object containing information about the resource calling the Recipe')
param context object

@description('Name of the EKS cluster used for app deployment')
param eksClusterName string

@description('List of subnetIds for the subnet group')
param subnetIds array = []

resource eksCluster 'AWS.EKS/Cluster@default' existing = {
  alias: eksClusterName
  properties: {
    Name: eksClusterName
  }
}

param subnetGroupName string = 'subnet-group-memorydb-${uniqueString(context.resource.id)}'
resource subnetGroup 'AWS.MemoryDB/SubnetGroup@default' = {
  alias:subnetGroupName
  properties: {
    SubnetGroupName: subnetGroupName
    SubnetIds: ((empty(subnetIds)) ? eksCluster.properties.ResourcesVpcConfig.SubnetIds : concat(subnetIds,eksCluster.properties.ResourcesVpcConfig.SubnetIds))
  }
}

param memoryDBClusterName string = 'memorydb-${uniqueString(context.resource.id)}'
resource memoryDBCluster 'AWS.MemoryDB/Cluster@default' = {
  alias: memoryDBClusterName
  properties: {
    ClusterName: memoryDBClusterName
    NodeType: 'db.t4g.small'
    ACLName: 'open-access'
    SecurityGroupIds: [eksCluster.properties.ClusterSecurityGroupId] 
    SubnetGroupName: subnetGroup.name
    NumReplicasPerShard: 0
  }
}

output result object = {
  values: {
    host: memoryDBCluster.properties.ClusterEndpoint.Address
    port: memoryDBCluster.properties.ClusterEndpoint.Port
    tls: true
  }
}

And a developer would consume this recipe like belo passing in the clusterName

resource db 'Applications.Link/redisCaches@2022-03-15-privatepreview' = {
  name: 'db'
  properties: {
    environment: environment
    tls: true
    recipe: {
      name: 'aws'
      parameters: {
        eksClusterName: eksClusterName
      }
    }
  }
}
  1. Developer has to know the name of the cluster where the Radius environment is setup
  2. Developer has to add the parameter eksclusterName to the link schema and update the app definition when moving his code from local to AWS

Envisioned to-be experience

What if the clusterName is already available in the recipe context which can be accessed by context.runtime.kubernetes.clusterName

Below is how the recipe definition would look like

import aws as aws

@description('Radius-provided object containing information about the resource calling the Recipe')
param context object

@description('Name of the EKS cluster used for app deployment')
param eksClusterName string = context.resource.kubernetes.clusterName

@description('List of subnetIds for the subnet group')
param subnetIds array = []

resource eksCluster 'AWS.EKS/Cluster@default' existing = {
  alias: eksClusterName
  properties: {
    Name: eksClusterName
  }
}

param subnetGroupName string = 'subnet-group-memorydb-${uniqueString(context.resource.id)}'
resource subnetGroup 'AWS.MemoryDB/SubnetGroup@default' = {
  alias:subnetGroupName
  properties: {
    SubnetGroupName: subnetGroupName
    SubnetIds: ((empty(subnetIds)) ? eksCluster.properties.ResourcesVpcConfig.SubnetIds : concat(subnetIds,eksCluster.properties.ResourcesVpcConfig.SubnetIds))
  }
}

param memoryDBClusterName string = 'memorydb-${uniqueString(context.resource.id)}'
resource memoryDBCluster 'AWS.MemoryDB/Cluster@default' = {
  alias: memoryDBClusterName
  properties: {
    ClusterName: memoryDBClusterName
    NodeType: 'db.t4g.small'
    ACLName: 'open-access'
    SecurityGroupIds: [eksCluster.properties.ClusterSecurityGroupId] 
    SubnetGroupName: subnetGroup.name
    NumReplicasPerShard: 0
  }
}

output result object = {
  values: {
    host: memoryDBCluster.properties.ClusterEndpoint.Address
    port: memoryDBCluster.properties.ClusterEndpoint.Port
    tls: true
  }
}

And a developer would consume the recipe like below

resource db 'Applications.Link/redisCaches@2022-03-15-privatepreview' = {
  name: 'db'
  properties: {
    environment: environment
    tls: true
    recipe: {
      name: 'aws'
      }
    }
  }
}

Futuristically when we have recipe packs feature, maybe the AWS environment has all the recipes needed for the application to run on AWS. We can simplify this further with developer not needing to pass the recipe name and link definitions picks the aws recipe registered in the environment

Questions

  1. Where do we get the clusterName from? Should the user need to pass this as part of the environment or is this information available to Radius somehow?
  2. Are we using eksClusterName as a proxy to leverage VPC information? Should we use VPC directly?
    • Yes, to keep things simple we use the default VPC and security group that gets created when an EKS cluster is created and create memorydb cluster also in the same VPC for the app to talk to memoryDB. There can be more advanced scenarios with creating a VPC and leveraging that in recipes. VPC is currently a non-idempotent resource type in Bicep. We need to bring support for non-idempotent AWS resource types before we can start modeling them in Bicep and building recipe templates. Maybe we can leverage terraform recipes to see how the experience pans out and we need a way for the operator to pass the VPC information via environment.

Acceptance criteria

Add ClusterName to the context properties

AB#6594

AB#9526

@Reshrahim Reshrahim changed the title Add clusterName to the context parameter Add clusterName parameter to recipe context Jul 18, 2023
@willtsai willtsai transferred this issue from radius-project/radius Sep 19, 2023
@AaronCrawfis AaronCrawfis transferred this issue from another repository Sep 19, 2023
@willtsai willtsai moved this to 📋 Backlog in Radius Roadmap Dec 15, 2023
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

No branches or pull requests

1 participant