Skip to main content
Version: main

Quick Start

Create your first ResourceGraphDefinition and deploy an application.

What is a ResourceGraphDefinition (RGD)?

A ResourceGraphDefinition (RGD) lets you create new Kubernetes APIs that deploy multiple resources together as a single, reusable unit. In this example, we'll create an RGD that packages a reusable set of resources, including a Deployment, Service, and Ingress. These resources are available in any Kubernetes cluster. Users can then call the API to deploy resources as a single unit, ensuring they're always created together with the right configuration.

Under the hood, when you create an RGD, kro:

  1. Treats your resources as a Directed Acyclic Graph (DAG) to understand their dependencies
  2. Validates resource definitions and detects the correct deployment order
  3. Creates a new API (CRD) in your cluster
  4. Configures itself to watch and serve instances of this API

Prerequisites

Before you begin, make sure you have the following:

  • kro installed and running in your Kubernetes cluster.
  • kubectl installed and configured to interact with your Kubernetes cluster.

Create your Application RGD

Let's create an RGD that combines a Deployment, a Service and Ingress. Save this as resourcegraphdefinition.yaml:

resourcegraphdefinition.yaml
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: my-application
spec:
# kro uses this simple schema to create your CRD schema and apply it
# The schema defines what users can provide when they instantiate the RGD (create an instance).
schema:
apiVersion: v1alpha1
kind: Application
spec:
# Spec fields that users can provide.
name: string
image: string | default="nginx"
replicas: integer | default=3
ingress:
enabled: boolean | default=false
status:
# Fields the controller will inject into instances status.
deploymentConditions: ${deployment.status.conditions}
availableReplicas: ${deployment.status.availableReplicas}

# Define the resources this API will manage.
resources:
- id: deployment
template:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${schema.spec.name} # Use the name provided by user
spec:
replicas: ${schema.spec.replicas} # Use the replicas provided by user
selector:
matchLabels:
app: ${schema.spec.name}
template:
metadata:
labels:
app: ${schema.spec.name}
spec:
containers:
- name: ${schema.spec.name}
image: ${schema.spec.image} # Use the image provided by user
ports:
- containerPort: 80

- id: service
template:
apiVersion: v1
kind: Service
metadata:
name: ${schema.spec.name}-svc
spec:
selector: ${deployment.spec.selector.matchLabels} # Use the deployment selector
ports:
- protocol: TCP
port: 80
targetPort: 80

- id: ingress
includeWhen:
- ${schema.spec.ingress.enabled} # Only include if the user wants to create an Ingress
template:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ${schema.spec.name}-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/healthcheck-path: /health
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60
spec:
rules:
- http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: ${service.metadata.name} # Use the service name
port:
number: 80

Deploy the RGD

  1. Create an RGD manifest file: Create a new file with the RGD definition. You can use the example above.

  2. Apply the RGD: Use the kubectl command to deploy the RGD to your Kubernetes cluster:

    kubectl apply -f resourcegraphdefinition.yaml
  3. Inspect the RGD: Check the status of the RGD using the kubectl command:

    kubectl get rgd my-application -owide

    You should see the RGD in the Active state, along with relevant information to help you understand your application:

    NAME             APIVERSION   KIND          STATE    TOPOLOGICALORDER                     AGE
    my-application v1alpha1 Application Active ["deployment","service","ingress"] 49

Create your Application Instance

Now that your RGD is created, kro has generated a new API (Application) that orchestrates the creation of a Deployment, a Service, and an Ingress. Let's use it!

  1. Create an Application instance: Create a new file named instance.yaml with the following content:

    instance.yaml
    apiVersion: v1alpha1
    kind: Application
    metadata:
    name: my-app-instance
    spec:
    name: my-app
    replicas: 1
    ingress:
    enabled: true
  2. Apply the Application instance: Use the kubectl command to deploy the Application instance to your Kubernetes cluster:

    kubectl apply -f instance.yaml
  3. Inspect the Application instance: Check the status of the resources

    kubectl get applications

    After a few seconds, you should see the Application instance in the Active state:

    NAME              STATE    READY   AGE
    my-app-instance Active True 10s

    When you create an instance, kro automatically creates and manages all the underlying resources:

    Instance Resources

  4. Inspect the resources: Check the resources created by the Application instance:

    kubectl get deployments,services,ingresses

    You should see the Deployment, Service, and Ingress created by the Application instance. Note the deployment has 1 replica as specified:

    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/my-app 1/1 1 1 69s

    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    service/my-app-svc ClusterIP 10.100.167.72 <none> 80/TCP 65s

    NAME CLASS HOSTS ADDRESS PORTS AGE
    ingress.networking.k8s.io/my-app-ingress <none> * 80 62s

Experiment with kro

kro continuously reconciles your resources. Try these experiments:

Change the replica count:

  1. Edit instance.yaml to increase replicas to 3:

    instance.yaml
    apiVersion: kro.run/v1alpha1
    kind: Application
    metadata:
    name: my-app-instance
    spec:
    name: my-app
    replicas: 3
    ingress:
    enabled: true
  2. Apply the change:

    kubectl apply -f instance.yaml
  3. Watch the deployment scale up:

    kubectl get deployment my-app

See kro's automatic reconciliation:

  1. Delete the service:

    kubectl delete service my-app-svc
  2. Watch kro recreate it automatically:

    kubectl get service my-app-svc -w

    kro is watching and will instantly recreate the service to match your RGD definition.

Clean Up

kro can also help you clean up resources when you're done with them.

  1. Delete the Application instance: Clean up the resources by deleting the Application instance:

    kubectl delete application my-app-instance

    Now, the resources created by the Application instance will be deleted.

Brought to you with ♥ by SIG Cloud Provider