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

Mega Feature: Implement collections (for loops) in ResourceGroups #17

Open
a-hilaly opened this issue Sep 21, 2024 · 2 comments
Open

Mega Feature: Implement collections (for loops) in ResourceGroups #17

a-hilaly opened this issue Sep 21, 2024 · 2 comments

Comments

@a-hilaly
Copy link
Member

Add support for collections in ResourceGroups to allow dynamic creation of multiple similar resources.. This will probably need a design and a review. It also needs the garbage collection mechanisms to be in place.

  • Implement iteration based on a range or list
  • Add current iteration index reference within resource definitions
  • Support specifying "deployment strategies" for collection types

Example:

apiVersion: x.symphony.k8s.aws/v1alpha1
kind: ResourceGroup
metadata:
  name: replicaset.x.symphony.k8s.aws
spec:
  apiVersion: v1alpha1
  kind: ReplicaSet
  definition:
    spec:
      image: string
      replicas: integer
  resources:
  - name: podsCollection
    collection:
      index: ${range(0, spec.replicas)}
      deploymentStrategy: RollingUpdates
      definition:
        apiVersion: v1alpha1
        kind: Pod
        metadata:
          name: pod-unit-${index}
        spec:
          containers:
          - image: ${spec.image}
            replicas: ${spec.replicas}
@gfrey
Copy link

gfrey commented Nov 19, 2024

Index reminds me of Terraform's count iteration concept. This had plenty of downsides when combined with lists of actual configuration values. Any change to the that list would result in modification on all subsequent list items. This was eventually solved with for_each based on sets or dicts. Then the item or key was used as part of the resource address. This made things a lot more stable. Possible solution could be to change the relevant part of the example above to:

collection:
  items: ${range(0, spec.replicas)}
  deploymentStrategy: RollingUpdates
  definition:
    metadata:
      name: pod-unit-${item}

An immediate application for this would be distribution of a VPC's subnets to availability-zones. Then the list of items would be the AZs (or maybe a dictionary from AZ to CIDR block).

A follow-up question would be how the resources of a collection can be queried? In the subnets application I would need to associate a NetworkACL with all these subnets. How could that be done?

@candonov candonov changed the title Implement collections (for loops) in ResourceGroups Mega Feature: Implement collections (for loops) in ResourceGroups Nov 20, 2024
@greghaynes
Copy link
Contributor

greghaynes commented Nov 21, 2024

Would the above solutions be limited in that they cannot allow for multiple sources of iteration within a single resource?

Here's a contrived example: Imagine we want to support a RG which supports defining multiple containers where some values are defaulted below each container.

apiVersion: kro.run/v1alpha1
kind: ResourceGroup
metadata:
  name: Application
spec:
  apiVersion: v1alpha1
  kind: Application
  definition:
    spec:
      name: string
    containers:
      - name: frontend
        image: nginx
      - name: backend
        image: nginx

This would mean it needs to be capable of rendering out a single Deployment resource, but within that deployment resource it iterates over the collection of containers within our RG:

  resources:
    - id: deployment
      definition:
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: ${schema.spec.name}
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: deployment
          template:
            metadata:
              labels:
                app: deployment
            spec:
              containers:
               ${ NEEDS CONTAINER COLLECTION HERE }

One thought on how to approach this is to introduce a vars layer like the following:

apiVersion: kro.run/v1alpha1
kind: ResourceGroup
metadata:
  name: Application
spec:
  apiVersion: v1alpha1
  kind: Application
  definition:
    spec:
      name: string
    containers:
      - name: frontend
        image: nginx
      - name: backend
        image: nginx
  vars:
    - name: deploymentContainers
      function: map
      input: schema.spec.containers
      render:
        - name: ${item.name}
          image: ${item.image}
          resources:
                requests:
                  memory: "64Mi"
                  cpu: "250m"
  resources:
    - id: deployment
      definition:
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: ${schema.spec.name}
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: deployment
          template:
            metadata:
              labels:
                app: deployment
            spec:
              containers:
                ${vars.deploymentContainers}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants