-
Notifications
You must be signed in to change notification settings - Fork 11
Add redis resource type and Kubernetes Recipe in Bicep and Tf #13
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
base: main
Are you sure you want to change the base?
Changes from all commits
9832917
77c6cba
b1e1eb0
e165f01
129e778
ad088fc
d9ab418
f89fb24
5b0670b
11db5a8
b30855f
8971eed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
## Overview | ||
|
||
The Radius.Data/redisCaches Resource Type represents Redis, an in-memory, key/value store used as an application cache. This Resource Type allows developers to create and easily connect to Redis caches as part of their Radius applications. | ||
|
||
Developer documentation is embedded in the Resource Type definition YAML file. Developer documentation is accessible via `rad resource-type show Radius.Data/redisCaches`. | ||
|
||
## Recipes | ||
|
||
A list of available Recipes for this Resource Type, including links to the Bicep and Terraform templates: | ||
|
||
|Platform| IaC Language| Recipe Name | Stage | | ||
|---|---|---|---| | ||
| Kubernetes | Bicep | kubernetes-redis.bicep | Alpha | | ||
| Kubernetes | Terraform | kubernetes/main.tf | Alpha | | ||
|
||
## Recipe Input Properties | ||
|
||
Properties for the redisCaches resource are provided to the Recipe via the [Recipe Context](https://docs.radapp.io/reference/context-schema/) object. These properties include: | ||
|
||
- `context.properties.capacity`(enum, optional): The capacity of the Redis server. Available options are S-Small, M-Medium, and L-Large. This property allows the developer to specify the size of the Redis cache instance. If not specified, Recipes should assume `S` as the capacity. | ||
|
||
## Recipe Output Properties | ||
|
||
The RedisCaches Resource Type expects the following output properties to be set in the Results object in the Recipe: | ||
|
||
- `context.properties.host` (string): The hostname used to connect to the Redis server. | ||
- `context.properties.port` (integer): The port number used to connect to the Redis server. | ||
- `context.properties.tls` (boolean): Indicates if TLS is enabled for the Redis server. | ||
- `context.properties.username` (string): The username for connecting to the Redis server. | ||
- `context.properties.password` (string): The password for connecting to the Redis server. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,109 @@ | ||||||
@description('Information about the resource calling this Recipe. Generated by Radius. For more information visit https://docs.radapp.io/reference/context-schema/ ') | ||||||
param context object | ||||||
|
||||||
extension kubernetes with { | ||||||
kubeConfig: '' | ||||||
namespace: context.runtime.kubernetes.namespace | ||||||
} as kubernetes | ||||||
|
||||||
@description('Memory limits for the Redis container') | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we setting limits? This makes me wonder if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I think we should configure the memory capacity in addition to the container limits for K8s. For Azure and AWS |
||||||
var memory ={ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
S: { | ||||||
memoryRequest: '512Mi' | ||||||
memoryLimit: '1024Mi' | ||||||
} | ||||||
M: { | ||||||
memoryRequest: '1Gi' | ||||||
memoryLimit: '2Gi' | ||||||
} | ||||||
L: { | ||||||
memoryRequest: '2Gi' | ||||||
memoryLimit: '4Gi' | ||||||
} | ||||||
} | ||||||
|
||||||
resource redis 'apps/Deployment@v1' = { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once Container Recipes are available, this will be updated to use Radius.Compute/Containers |
||||||
metadata: { | ||||||
name: 'redis-${uniqueString(context.resource.id)}' | ||||||
} | ||||||
spec: { | ||||||
selector: { | ||||||
matchLabels: { | ||||||
app: 'redis' | ||||||
resource: context.resource.name | ||||||
Comment on lines
+32
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are our labeling standards? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not know if we have a labelling standard. We can create a standard and publish it to the guidelines. I think Radius Environment name makes sense but application wouldn't if this is a shared resource. |
||||||
} | ||||||
} | ||||||
template: { | ||||||
metadata: { | ||||||
labels: { | ||||||
app: 'redis' | ||||||
resource: context.resource.name | ||||||
} | ||||||
} | ||||||
spec: { | ||||||
containers: [ | ||||||
{ | ||||||
name: 'redis' | ||||||
image: 'redis' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make the image and image tag a parameter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. U mean parameter local to the Recipe that PE's can change ? |
||||||
ports: [ | ||||||
{ | ||||||
containerPort: 6379 | ||||||
} | ||||||
] | ||||||
resources: { | ||||||
requests: { | ||||||
memory: memory[context.resource.properties.?capacity ?? 'S'].memoryRequest | ||||||
} | ||||||
limits: { | ||||||
memory: memory[context.resource.properties.?capacity ?? 'S'].memoryLimit | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tested with .? and it worked. I think Bicep accepts both forms of safe access. |
||||||
} | ||||||
} | ||||||
} | ||||||
{ | ||||||
// This container will connect to redis and stream logs to stdout for aid in development. | ||||||
name: 'redis-monitor' | ||||||
image: 'redis' | ||||||
args: [ | ||||||
'redis-cli' | ||||||
'-h' | ||||||
'localhost' | ||||||
'MONITOR' | ||||||
] | ||||||
Comment on lines
+63
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this here? Does the redis container image not stream logs to stdout? That would be very weird if that was the case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Retained this is from local-dev Recipe implementation. |
||||||
} | ||||||
] | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
resource svc 'core/Service@v1' = { | ||||||
metadata: { | ||||||
name: 'redis-${uniqueString(context.resource.id)}' | ||||||
} | ||||||
spec: { | ||||||
type: 'ClusterIP' | ||||||
selector: { | ||||||
app: 'redis' | ||||||
resource: context.resource.name | ||||||
} | ||||||
ports: [ | ||||||
{ | ||||||
port: 6379 | ||||||
} | ||||||
] | ||||||
} | ||||||
} | ||||||
|
||||||
output result object = { | ||||||
// This workaround is needed because the deployment engine omits Kubernetes resources from its output. | ||||||
// This allows Kubernetes resources to be cleaned up when the resource is deleted. | ||||||
// Once this gap is addressed, users won't need to do this. | ||||||
Comment on lines
+98
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there an issue to reference? |
||||||
resources: [ | ||||||
'/planes/kubernetes/local/namespaces/${svc.metadata.namespace}/providers/core/Service/${svc.metadata.name}' | ||||||
'/planes/kubernetes/local/namespaces/${redis.metadata.namespace}/providers/apps/Deployment/${redis.metadata.name}' | ||||||
] | ||||||
values: { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are five read-only properties. They should all be set. |
||||||
host: '${svc.metadata.name}.${svc.metadata.namespace}.svc.cluster.local' | ||||||
port: 6379 | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
terraform { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Output from tflint:
|
||
required_providers { | ||
kubernetes = { | ||
source = "hashicorp/kubernetes" | ||
version = ">= 2.0" | ||
} | ||
} | ||
} | ||
|
||
locals { | ||
uniqueName = "redis-${substr(sha1(var.context.resource.id), 0, 8)}" | ||
port = 6379 | ||
namespace = var.context.runtime.kubernetes.namespace | ||
} | ||
|
||
resource "kubernetes_deployment" "redis" { | ||
metadata { | ||
name = local.uniqueName | ||
namespace = local.namespace | ||
labels = { | ||
app = "redis" | ||
} | ||
} | ||
spec { | ||
selector { | ||
match_labels = { | ||
app = "redis" | ||
resource = local.uniqueName | ||
} | ||
} | ||
template { | ||
metadata { | ||
labels = { | ||
app = "redis" | ||
resource = local.uniqueName | ||
} | ||
} | ||
spec { | ||
container { | ||
name = "redis" | ||
image = "redis:6" | ||
resources { | ||
requests = { | ||
memory = var.memory[try(var.context.resource.properties.capacity, "S")].memoryRequest | ||
} | ||
limits = { | ||
memory= var.memory[try(var.context.resource.properties.capacity, "S")].memoryLimit | ||
} | ||
} | ||
port { | ||
container_port = local.port | ||
} | ||
|
||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
resource "kubernetes_service" "redis" { | ||
metadata { | ||
name = local.uniqueName | ||
namespace = local.namespace | ||
} | ||
spec { | ||
type = "ClusterIP" | ||
selector = { | ||
app = "redis" | ||
resource = local.uniqueName | ||
} | ||
port { | ||
port = local.port | ||
target_port = local.port | ||
} | ||
} | ||
} | ||
|
||
output "result" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is resources not required here as it is in the Bicep recipe? If so, be sure to include the same comment from the Bicep file. |
||
value = { | ||
values = { | ||
host = "${kubernetes_service.redis.metadata[0].name}.${kubernetes_service.redis.metadata[0].namespace}.svc.cluster.local" | ||
port = local.port | ||
Comment on lines
+81
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are five read-only properties. They should all be set. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a rule for Recipes that all read-only properties must be set? This Recipe implementation is similar to a alpha stage contribution not covering all the scenarios(e.g configuring TLS) and hence some properties are not set. |
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
variable "context" { | ||
description = "Information about the resource calling this Recipe. Generated by Radius. For more information visit https://docs.radapp.io/reference/context-schema/" | ||
type = any | ||
} | ||
|
||
variable "memory" { | ||
description = "Memory limits for the Redis container" | ||
type = map(object({ | ||
memoryRequest = string | ||
memoryLimit = string | ||
})) | ||
default = { | ||
S = { | ||
memoryRequest = "512Mi" | ||
memoryLimit = "1024Mi" | ||
}, | ||
M = { | ||
memoryRequest = "1Gi" | ||
memoryLimit = "2Gi" | ||
} | ||
L = { | ||
memoryRequest = "2Gi" | ||
memoryLimit = "4Gi" | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,74 @@ | ||||||||||||||||||||||||||||||||||||||
namespace: Radius.Data | ||||||||||||||||||||||||||||||||||||||
types: | ||||||||||||||||||||||||||||||||||||||
redisCaches: | ||||||||||||||||||||||||||||||||||||||
description: | | ||||||||||||||||||||||||||||||||||||||
The Radius.Data/redisCaches Resource Type deploys Redis, an in-memory, key/value store used as an application cache. | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
To deploy a new Redis cache, add a RedisCaches resource to the application definition Bicep file. | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
param environment string | ||||||||||||||||||||||||||||||||||||||
resource redisCache 'Radius.Data/redisCaches@2025-08-01-preview' = { | ||||||||||||||||||||||||||||||||||||||
name: 'redisCache' | ||||||||||||||||||||||||||||||||||||||
properties: { | ||||||||||||||||||||||||||||||||||||||
environment: environment | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+9
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I've been making sure the examples were whole. |
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
When `capacity` is not set, the value is assumed to be `S`(Small) in Recipes. | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be in the property description, not here. |
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
To connect your application to the Redis Cache, establish a connection from the container to the Redis Cache as shown below. Once connected, all Redis Cache properties are automatically injected as environment variables into the container. | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
resource myContainer 'Radius.Compute/containers@2025-08-01-preview' = { | ||||||||||||||||||||||||||||||||||||||
name: 'myContainer' | ||||||||||||||||||||||||||||||||||||||
properties: { | ||||||||||||||||||||||||||||||||||||||
environment: environment | ||||||||||||||||||||||||||||||||||||||
application: myApplication.id | ||||||||||||||||||||||||||||||||||||||
containers: { | ||||||||||||||||||||||||||||||||||||||
frontend: { | ||||||||||||||||||||||||||||||||||||||
image: 'frontend:1.25' | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
connections: { | ||||||||||||||||||||||||||||||||||||||
redis:{ | ||||||||||||||||||||||||||||||||||||||
source: redis.id | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
apiVersions: | ||||||||||||||||||||||||||||||||||||||
'2025-08-01-preview': | ||||||||||||||||||||||||||||||||||||||
schema: | ||||||||||||||||||||||||||||||||||||||
type: object | ||||||||||||||||||||||||||||||||||||||
properties: | ||||||||||||||||||||||||||||||||||||||
environment: | ||||||||||||||||||||||||||||||||||||||
type: string | ||||||||||||||||||||||||||||||||||||||
description: (Required) The Radius Environment ID. Typically set by the rad CLI. Typically value should be `environment`. | ||||||||||||||||||||||||||||||||||||||
application: | ||||||||||||||||||||||||||||||||||||||
type: string | ||||||||||||||||||||||||||||||||||||||
description: (Optional) The Radius Application ID. `myApplication.id` for example. | ||||||||||||||||||||||||||||||||||||||
capacity: | ||||||||||||||||||||||||||||||||||||||
type: string | ||||||||||||||||||||||||||||||||||||||
enum: [S, M, L] | ||||||||||||||||||||||||||||||||||||||
description: (Optional) The capacity of the Redis server. | ||||||||||||||||||||||||||||||||||||||
host: | ||||||||||||||||||||||||||||||||||||||
type: string | ||||||||||||||||||||||||||||||||||||||
description: (Read-Only) The hostname used to connect to the Redis server. | ||||||||||||||||||||||||||||||||||||||
readOnly: true | ||||||||||||||||||||||||||||||||||||||
port: | ||||||||||||||||||||||||||||||||||||||
type: integer | ||||||||||||||||||||||||||||||||||||||
description: (Read-Only) The port used to connected to the Redis server. | ||||||||||||||||||||||||||||||||||||||
readOnly: true | ||||||||||||||||||||||||||||||||||||||
tls: | ||||||||||||||||||||||||||||||||||||||
type: boolean | ||||||||||||||||||||||||||||||||||||||
description: (Read-Only) Set to true if the Redis server requires a TLS/SSL connection. | ||||||||||||||||||||||||||||||||||||||
readOnly: true | ||||||||||||||||||||||||||||||||||||||
username: | ||||||||||||||||||||||||||||||||||||||
type: string | ||||||||||||||||||||||||||||||||||||||
description: (Read-Only) The username used to connected to the Redis server. | ||||||||||||||||||||||||||||||||||||||
readOnly: true | ||||||||||||||||||||||||||||||||||||||
password: | ||||||||||||||||||||||||||||||||||||||
type: string | ||||||||||||||||||||||||||||||||||||||
description: (Read-Only) The password used to connected to the Redis server. | ||||||||||||||||||||||||||||||||||||||
readOnly: true | ||||||||||||||||||||||||||||||||||||||
required: | ||||||||||||||||||||||||||||||||||||||
- environment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.