Skip to content

Instantly share code, notes, and snippets.

@manics
Last active January 26, 2026 13:18
Show Gist options
  • Select an option

  • Save manics/6535bbbcb7293f6a813d422d379dc778 to your computer and use it in GitHub Desktop.

Select an option

Save manics/6535bbbcb7293f6a813d422d379dc778 to your computer and use it in GitHub Desktop.

Example of Kube Resource Orchestrator on AWS

An example of using Kube Resource Orchestrator (kro) to orchestrate AWS Controllers for Kubernetes (ACK).

ACK providers CRDs to manage individual AWS resources. kro enables orchestration of multiple AWS resource CRDs, including parameterisation.

  1. Create a ResourceGraphDefinition. This defines a new CRD ApplicationFoo:
kubectl apply -f kro-aws-application-rgd.yaml
  1. Check CRD is created
kubectl get crd applicationfoos.kro.run
  1. Create an instance of ApplicationFoo:
kubectl apply -f kro-aws-application-instance-example.yaml
  1. Check instance is created
kubectl get applicationfoos
---
apiVersion: kro.run/v1alpha1
kind: ApplicationFoo
metadata:
name: kro-demo
spec:
name: kro-demo
instance:
# image: string
# type: string
keyname: KEYNAME
# volumeSize: integer
network:
vpcId: vpc-0123456789abcdef0
subnetId: subnet-0123456789abcdef0
prefixList: pl-0123456789abcdef0
accessPort: 22
# https://kro.run/docs/getting-started/deploy-a-resource-graph-definition
---
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: application-foo
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
# This is the name of the custom CRD
kind: ApplicationFoo
spec:
# Spec fields that users can provide.
name: string
instance:
image: string | default="ami-0ab54db41b3bd815e" # Amazon Linux 2023 eu-west-2
type: string | default="t2.micro"
keyname: string
volumeSize: integer | default=20
network:
vpcId: string
subnetId: string
prefixList: string
accessPort: integer | default=22
status:
# Fields the controller will inject into instances status.
# .status doesn't exist immediately, .?status avoids warnings
instanceConditions: ${workspace.?status.conditions}
securitygroupConditions: ${securitygroup.?status.conditions}
instanceID: ${workspace.?status.instanceID}
state: ${workspace.?status.state.name}
privateDNSName: ${workspace.?status.privateDNSName}
# Define the resources this API will manage.
resources:
# https://aws-controllers-k8s.github.io/docs/api-reference/#ec2/SecurityGroup
- id: securitygroup
template:
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: SecurityGroup
metadata:
name: ${schema.spec.name}-sg
spec:
name: ${schema.spec.name}-sg
description: Allow SSH inbound
vpcID: ${schema.spec.network.vpcId}
ingressRules:
- ipProtocol: tcp
fromPort: ${schema.spec.network.accessPort}
toPort: ${schema.spec.network.accessPort}
prefixListIDs:
- prefixListID: ${schema.spec.network.prefixList}
tags:
- key: Name
value: ${schema.spec.name}-sg
# https://aws-controllers-k8s.github.io/docs/api-reference/#ec2/Instance
- id: workspace
template:
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: Instance
metadata:
name: ${schema.spec.name}-instance
spec:
imageID: ${schema.spec.instance.image}
instanceType: ${schema.spec.instance.type}
iamInstanceProfile:
name: AmazonSSMManagedInstanceCore
keyName: ${schema.spec.instance.keyname}
subnetID: ${schema.spec.network.subnetId}
securityGroupIDs:
# Note this leads to some harmless errors in the logs since status.id doesn't immediately exist
# https://github.com/kubernetes-sigs/kro/issues/336
- ${securitygroup.status.id}
# ACK allows you to map existing volumes or define them in blockDeviceMappings
blockDeviceMappings:
- deviceName: /dev/xvda
ebs:
# encrypted:
# kmsKeyID:
volumeSize: ${schema.spec.instance.volumeSize}
volumeType: gp3
tags:
- key: Name
value: ${schema.spec.name}-instance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment