Skip to content

AWS Resources

Franklin García edited this page Sep 6, 2026 · 2 revisions

AWS Resources

Timonel includes focused AWS/EKS helpers for patterns that are useful across Helm charts. They are not a replacement for the broader cdk8s/cdk8s-plus APIs.

Resource strategy

Use the same typed-first order as the rest of Timonel:

  1. use cdk8s-plus when it already models the resource well;
  2. use a Timonel AWS helper when it provides a focused, tested abstraction;
  3. use a typed/object ApiObject for CRDs without a higher-level construct.

EBS StorageClass

chart.addAWSEBSStorageClass({
  name: 'gp3',
  volumeType: 'gp3',
  encrypted: true,
  iops: 3000,
  throughput: 125,
  allowVolumeExpansion: true,
  reclaimPolicy: 'Delete',
  volumeBindingMode: 'WaitForFirstConsumer',
});

The helper uses the ebs.csi.aws.com provisioner.

Supported options include:

name volumeType encrypted iops throughput fsType
reclaimPolicy allowVolumeExpansion volumeBindingMode labels annotations

EFS StorageClass

chart.addAWSEFSStorageClass({
  name: 'efs',
  fileSystemId: 'fs-0123456789abcdef0',
  directoryPerms: '0755',
  basePath: '/dynamic',
  reclaimPolicy: 'Retain',
});

The helper uses the efs.csi.aws.com provisioner.

Supported options include:

name fileSystemId directoryPerms gidRangeStart gidRangeEnd basePath
reclaimPolicy volumeBindingMode labels annotations

IRSA ServiceAccount

const serviceAccount = chart.addAWSIRSAServiceAccount({
  name: 'orders',
  roleArn: 'arn:aws:iam::123456789012:role/orders',
  automountServiceAccountToken: true,
  labels: {
    'app.kubernetes.io/name': 'orders',
  },
});

This returns a real cdk8s-plus-33 ServiceAccount and adds the eks.amazonaws.com/role-arn annotation.

Image pull secrets can be referenced by name:

chart.addAWSIRSAServiceAccount({
  name: 'orders',
  roleArn: 'arn:aws:iam::123456789012:role/orders',
  imagePullSecrets: [{ name: 'registry-credentials' }],
});

ECR ServiceAccount

chart.addAWSECRServiceAccount({
  name: 'ecr-reader',
  roleArn: 'arn:aws:iam::123456789012:role/ecr-reader',
});

The current helper also returns a cdk8s-plus ServiceAccount and uses the IRSA role annotation. It does not create the IAM role, ECR repository, or AWS-side trust policy.

ALB Ingress

chart.addAWSALBIngress({
  name: 'public-api',
  scheme: 'internet-facing',
  targetType: 'ip',
  healthCheckPath: '/health',
  ingressClassName: 'alb',
  rules: [
    {
      host: 'api.example.com',
      paths: [
        {
          path: '/',
          pathType: 'Prefix',
          backend: {
            service: {
              name: 'api',
              port: { number: 8080 },
            },
          },
        },
      ],
    },
  ],
});

Optional ALB settings include certificate ARN, SSL redirect, TLS secret configuration, labels, and additional annotations.

The helper constructs Kubernetes resources only. The AWS Load Balancer Controller and its AWS permissions must already exist in the target cluster.

Karpenter NodePool

chart.addKarpenterNodePool({
  name: 'general',
  template: {
    spec: {
      nodeClassRef: {
        apiVersion: 'karpenter.k8s.aws/v1',
        kind: 'EC2NodeClass',
        name: 'general',
      },
      requirements: [
        {
          key: 'karpenter.sh/capacity-type',
          operator: 'In',
          values: ['on-demand', 'spot'],
        },
      ],
    },
  },
  limits: {
    cpu: '100',
  },
});

The current Timonel NodePool and NodeClaim helpers synthesize the Karpenter v1 API.

Karpenter NodeClaim

chart.addKarpenterNodeClaim({
  name: 'special-node',
  nodeClassRef: {
    apiVersion: 'karpenter.k8s.aws/v1',
    kind: 'EC2NodeClass',
    name: 'general',
  },
});

EC2NodeClass

chart.addKarpenterEC2NodeClass({
  name: 'general',
  amiFamily: 'AL2023',
  role: 'KarpenterNodeRole',
  subnetSelectorTerms: [
    { tags: { 'karpenter.sh/discovery': 'cluster-name' } },
  ],
  securityGroupSelectorTerms: [
    { tags: { 'karpenter.sh/discovery': 'cluster-name' } },
  ],
});

The current helper emits karpenter.k8s.aws/v1beta1 for EC2NodeClass. Verify this against the CRDs installed in your cluster before adopting the helper for a Karpenter version that expects a different API version.

Convenience NodePool builders

Disruption

chart.addKarpenterNodePoolWithDisruption({
  name: 'cost-optimized',
  nodeClassRef: {
    apiVersion: 'karpenter.k8s.aws/v1',
    kind: 'EC2NodeClass',
    name: 'general',
  },
  consolidationPolicy: 'WhenEmptyOrUnderutilized',
  consolidateAfter: '30s',
  disruptionBudgets: [{ nodes: '20%' }],
});

Scheduling

chart.addKarpenterNodePoolWithScheduling({
  name: 'gpu',
  nodeClassRef: {
    apiVersion: 'karpenter.k8s.aws/v1',
    kind: 'EC2NodeClass',
    name: 'gpu',
  },
  requirements: [
    {
      key: 'node.kubernetes.io/instance-type',
      operator: 'In',
      values: ['g5.xlarge'],
    },
  ],
  terminationGracePeriod: '60s',
});

What Timonel does not provision

These helpers generate Kubernetes manifests. They do not create:

  • IAM roles or policies;
  • EBS/EFS file systems;
  • ECR repositories;
  • the AWS Load Balancer Controller;
  • Karpenter controllers or CRDs;
  • AWS networking or cluster infrastructure.

Provision cloud infrastructure with the infrastructure tool appropriate for your platform, then use Timonel for the Kubernetes/Helm layer.

Clone this wiki locally