# Juju: a Go orchestration engine that deploys and integrates applications through charms

> Juju is Canonical's open source application orchestration engine, written in Go and driven by operators called charms. It targets teams that need the same deployment and integration workflow on Kubernetes and on non-Kubernetes infrastructure.

**juju/juju** — Orchestration engine that enables the deployment, integration and lifecycle management of applications at any scale, on any infrastructure (Kubernetes or otherwise).

- Repository: https://github.com/juju/juju
- Website: https://juju.is
- Stars: 2,673 · Forks: 604
- Language: Go
- License: NOASSERTION
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/juju-juju

## The problem Juju solves: deployment and integration as one operation

Most deployment tooling stops at getting a workload running. The harder part is what happens when two workloads need to talk to each other, and the connection details change every time you redeploy either one. Juju's README frames the project as an engine that covers deployment, integration and lifecycle management together, on Kubernetes or otherwise, at development or production scale, "typically, one line of code". The unit of that work is the charm, which the README describes as a special operator.

The audience is operations teams that manage more than a handful of services and want the relationship between them declared rather than scripted. A team running a database, a queue and an application server on Kubernetes has to wire three sets of credentials, endpoints and network policies. Juju's claim is that the wiring is expressed once in the charm relation and re-established on every deployment. That is a different proposition from a general-purpose configuration management tool, which would have you write the wiring yourself and keep it correct as the topology changes.

## How the engine is put together: controller, API server, agents and domains

The repository layout describes the data flow without needing the documentation. The top level carries api/, apiserver/, controller/, agent/, caas/, environs/, domain/, core/, rpc/ and cmd/. A controller process runs the apiserver, which exposes the RPC surface in rpc/; machine and unit agents connect to it and carry out the work. The caas/ directory is where container-as-a-service concerns live, which is how the same controller drives Kubernetes workloads alongside machines.

The domain/ directory is the part worth noticing. It is a domain-driven layout, and the repository ships AGENTS.core-domain-rules.md and AGENTS.architecture-rules.md as explicit rule files for that structure. This is a codebase that has decided its internal boundaries are a first-class artefact, not an accident of package history. The dependency list in go.mod backs that up: it pulls in the AWS, Azure and Google Cloud SDKs directly, plus github.com/canonical/lxd, github.com/canonical/pebble and github.com/canonical/go-dqlite/v3. Cloud provider integration is compiled into the controller rather than pushed out to plugins, and the controller's own state lives in Dqlite, Canonical's SQLite-based distributed database.

That choice has a cost. A controller binary that links the AWS SDK, the Azure SDK and the Google Cloud SDK is large, and the provider surface is tied to the release cadence of those SDKs. The upside is that a single controller can drive several clouds and Kubernetes without a separate provider installation step.

## Installing Juju and deploying your first application

The README points at the snap badge and at the tutorial under documentation.ubuntu.com/juju/latest/tutorial/, and the repository ships a snap/ directory and a snap.yml workflow, so the snap is the distribution path the project itself builds.

If you are building from source rather than installing the snap, the Makefile is the entry point. It sets CGO_ENABLED=0 for the build, includes scripts/dqlite/Makefile, and derives JUJU_VERSION by running scripts/version/main.go. Build artefacts land under _build/${GOOS}_${GOARCH}/bin, and simplestreams archives are written to _build/simplestreams. The Makefile's help target extracts lines beginning with ## from the makefile list:

```bash
make help
```

Run that first to see the targets this revision actually defines, because the Makefile is long. The README does not list the bootstrap or deploy commands, so check the tutorial for the exact cloud names and flags your environment needs before running anything. The shape of the workflow is a bootstrap followed by a deploy, and the README's own description of the payoff is that an application operation is "typically, one line of code".

## Where Juju is the wrong tool

Juju orchestrates charms. If your application is a container image with no charm, the engine has nothing to act on, and writing the charm becomes your project before Juju does anything for you. That is a real adoption cost that the README's one-line-of-code framing does not surface.

There is also a version-line problem. The release list shows v4.0.15 published on 2026-09-22 and v3.6.28 published on 2026-09-01, so two major lines are being maintained in parallel. Teams that adopt 4.0 inherit the newer domain-based internals; teams on 3.6 stay on the older structure. The repository does not state an end-of-life date for 3.6, so treat the choice as a commitment you need to confirm with the project rather than something you can infer from the release tags.

Finally, the licence. The repository's licence field reads NOASSERTION, and the root contains a file named LICENCE rather than LICENSE. GitHub could not classify it, which means the terms are not a standard identifier you can assume. If your organisation has a licence review step, this file goes through it before anything else does.

## Juju compared with Ansible and Terraform

Ansible and Terraform both describe infrastructure, and both are commonly reached for when a team first hits the problem Juju targets. The difference is what the description is attached to. Ansible runs tasks against hosts in order; Terraform reconciles a declared resource graph against a provider API. Neither one has a first-class notion of two applications negotiating an integration at runtime.

Juju's charm carries that notion. The charm declares what it provides and what it requires, and the engine establishes the relation when both sides are deployed. The consequence is that adding a second unit, or moving the workload from a machine to Kubernetes, does not require rewriting the wiring: the relation is re-established by the controller. With Ansible you would re-run the playbook and hope the templated credentials still match. With Terraform you would be managing the cloud resources underneath rather than the application relationship on top.

That does not make Juju a replacement for either. Terraform still provisions the VPC and the cluster. Juju starts where the cluster already exists and asks what runs on it and how those things connect. The two are complementary, and the repository's cloud SDK dependencies suggest the project expects to be given credentials for infrastructure that something else created.

## Maintenance, releases and the licence file

The last push to the repository was on 2026-09-24, and the most recent release, v4.0.15, was published on 2026-09-22. The 3.6 line also saw a release on 2026-09-01. Both lines are receiving tagged releases, and the repository is not archived. Whatever else you conclude, this is not an abandoned codebase.

The upgrade cost sits in the two-line split. A controller on 3.6 and a controller on 4.0 are different generations of the same product, and the internal restructuring visible in the domain/ directory and the AGENTS rule files is the kind of change that ripples through charm compatibility. The README does not document migration between the lines. That is a gap worth flagging to whoever owns your deployment before you pick a line.

On licensing: the repository ships a LICENCE file that GitHub reports as NOASSERTION, which means the classifier could not match it to a known licence. This article is not legal advice. Read that file, and if the terms are not obvious to you, get them reviewed, because NOASSERTION tells you only that the classifier gave up, not what the terms actually permit.

## Conclusion

Adopt Juju if you already run Ubuntu or Kubernetes estates and want deployment plus integration expressed as charms rather than hand-written pipelines. Do not adopt it if your applications are not packaged as charms and you have no intention of packaging them, because the engine has nothing to orchestrate without them. Before committing, verify that a charm exists for each workload you depend on, check which of the v4.0.x and v3.6.x release lines your controller will run, and read the LICENCE file in the repository root rather than relying on the repository's NOASSERTION licence label.

## FAQ

### What is Juju?

Juju is an open source application orchestration engine that handles deployment, integration and lifecycle management for applications on Kubernetes or other infrastructure. It works through operators called charms, and the README describes a typical operation as one line of code.

### Does Juju work on Kubernetes and on machines?

The README states that Juju enables application operations on any infrastructure, Kubernetes or otherwise. The repository has a caas/ directory for container-as-a-service concerns alongside the machine-oriented directories, and go.mod links github.com/canonical/lxd and github.com/canonical/pebble.

### How do I install Juju?

The README links to the snap badge, and the repository contains a snap/ directory and a snap.yml workflow, so the snap is the distribution path the project builds. The README also points to the tutorial at documentation.ubuntu.com/juju/latest/tutorial/ for the getting-started steps.

### What is a charm in Juju?

The README describes charms as special operators through which Juju performs application operations. The repository contains a testcharms/ directory, which is where the project keeps charms used for testing.

### Is Juju actively maintained?

The repository is not archived, its last push was on 2026-09-24, and it published v4.0.15 on 2026-09-22 and v3.6.28 on 2026-09-01. Two major release lines are receiving tagged releases.

### What language is Juju written in?

Juju is written in Go. The go.mod file declares module github.com/juju/juju with go 1.26.6, and Go is listed as the repository's primary language.

## Sources

- [Issues](https://github.com/juju/juju/issues)
- [juju/juju on GitHub](https://github.com/juju/juju)
- [Project website](https://juju.is)
- [README](https://github.com/juju/juju/blob/main/README.md)
- [Releases](https://github.com/juju/juju/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/juju-juju
