<aside> <img src="/icons/reorder_gray.svg" alt="/icons/reorder_gray.svg" width="40px" />

Navigation

Overview

Install

Architecture


Contact Us

</aside>

What is kite?

Kite is a declarative IaC language designed for consistently provisioning cloud resources. With a single Kite file, you describe the exact infrastructure you need, then reuse that file throughout your development lifecycle to deploy and update environments reliably.

Kite’s clean, concise syntax and strong type safety help you catch errors early, while its modular approach lets you share and reuse code across projects. The result is a streamlined experience that keeps your deployments predictable and maintainable.

Why use it?

Write once, provision anywhere

Define resources once and provision across multiple cloud providers like AWS, GCP, Azure. You can extend a resource or a group of resources using a powerful and flexible feature named mixins

resource Bucket photos {
  name = "my-photos"
}
// Resource properties tailored to each cloud provider
mixin gcp on photos { uniform_bucket_level_access = true }
mixin aws on photos { account_id = "us-east-1" }

// type specific properties on all instances
mixin gcp on Bucket { uniform_bucket_level_access = true }
mixin aws on Bucket { account_id = "us-east-1" }

// properties on all gcp resources
mixin gcp on * { tags = { env: 'prod' } }
// properties on all aws resources
mixin aws on * { tags = { env: 'prod' } }

// general properties for all buckets
mixin Bucket { tags = { env: 'prod' } }

As you can see, you don’t need to refine multiple resources for each cloud provider, just declare one and we’re doing the rest for you

Refactor fearlessly

We support intelligent resource renames that complete instantly. Consider this Terraform example

resource "aws_s3_bucket" "example" {
  bucket = "main-bucket"
}

// later we would like to rename "example" to "main"
resource "aws_s3_bucket" "main" {
  bucket = "main-bucket"
}

Terraform resource rename destroys and recreates the resource! not only that but it takes a lot of time for this to happen

the output:

**# aws_s3_bucket.example** will be destroyed
# (because aws_s3_bucket.example is not in configuration)
- resource "aws_s3_bucket" "example" {
    - arn                         = "arn:aws:s3:::main-bucket" -> null
    - bucket                      = "main-bucket" -> null
  }

# aws_s3_bucket.kite will be created
+ resource "aws_s3_bucket" "kite" {
    + bucket                      = "main-bucket"
  }

Plan: 1 to add, 0 to change, 1 to destroy.

Kite renames are a breeze

resource Bucket example {
  bucket = "logs"
}

// rename "example" to "kite". A simple resource name change is enough
resource Bucket kite {
  bucket = "logs"
}

the output:

# DummyResource.example will be renamed to DummyResource.kite
resource DummyResource example -> kite {
	bucket = "kite-bucket"
}

Plan: 0 to add, 0 to change, 0 to destroy, 1 to rename.

Notice the -> operator which is used to indicate a resource rename. We detect resource renames so that you can focus on more important things

Easy resource imports

We use the existing keyword to reference and import and existing cloud resource into code

existing resource Bucket example {
  bucket = "kite-bucket"
}

Database-backed state

<aside> 💽

Kite stores state in PostgreSQL instead of a flat files.

</aside>

By using PostgreSQL, we build on a database that’s both powerful and familiar. Teams get enterprise-grade features out of the box, and because PostgreSQL is so widely adopted, your engineers already know how to secure it, back it up, restore it, and query it.

Across cloud providers setting up Terraform state means wiring together buckets, databases, roles, and profiles just to track and lock resources. With Kite, state management is built-in - no extra services to configure, no cloud-specific boilerplate, just a classic database.

Among other features, we believe it helps us in:

Strong typing with clean syntax

Types are enforced without verbose provider prefixes like aws_ or gcp_. Thanks to imports, your code stays short and readable.

import Bucket from "aws.s3.Bucket"

resource Bucket photos {
  name = "my-photos"
}

Built in constraints

inputs and variables can have validations through decorators or type aliases

@allow(['us-east-1'])
input string location = 'us-east-1'
@minLen
input string name     = 'bucket name'

resource Bucket photos {
  name     = name
  location = location
}

// or use a type alias
type Location = 'us-east-1' | 'us-west-1'
input Location location = 'us-east-1'