The Charmed Operator Software Development Kit (SDK) docs

Juju’s Charmed Operator Software Development Kit (“the SDK”) is a toolkit for building Charmed Operators. It consists of Ops and Charmcraft.

A Charmed Operator (“charm”) is an expansion and generalization of the Kubernetes notion of an operator:

In the Kubernetes tradition, an operator is a container that drives lifecycle management, configuration, integration, and daily actions for an application. It handles instantiation, scaling, configuration, optimisation, networking, service mesh, observability, and Day 2 operations specific to that application. On the principle that an operator should ‘do one thing and do it well’, each operator drives a single application or service. However, it can be composed with other operators to deliver a complex application or service. Because operators package expert knowledge in a reusable and shareable form, they hugely simplify software management and operations.

In Juju, an operator does all that but supports even more uses and more infrastructures: With Charmed Operators (coordinated by Juju’s Charmed Operator Lifecycle Manager) you can not only deploy an application but also connect it to other applications, and you can use not just Kubernetes clusters, but containers, virtual machines, and bare metal machines as well, on public or private cloud.

Ops is a Python framework for developing charms. It uses standard Python structures to make charm development simple and straightforward, and to allow for clean, maintainable, and reusable code. (Note: Like Juju as a whole, Juju’s SDK’s Ops framework is sometimes also called “the Charmed Operator Framework”. However, here it means “a framework for building charms”, whereas there it refers to “a framework for cloud deployment using charms”.)

Charmcraft is a command line tool used alongside Ops to simplify the creation, building, and publication of a charm.

Machine charms

Juju’s beginnings were centered around simplifying the deployment of complex applications and services in a cloud-first world. At the time, many of those applications were run in virtual machines or on bare-metal servers, and deployments to these environments continue to enjoy first-class support. A machine charm can be deployed to a number of different underlying compute/storage resource providers:

  • Bare-metal (perhaps using MAAS)
  • A virtual machine (on public or private cloud)
  • VMware
  • OpenStack
  • A LXD cluster

Kubernetes charms

More recently, the Juju OLM introduced support for Charmed Operators on Kubernetes. Juju can bring the same benefits to applications deployed on Kubernetes, by placing operators alongside workloads to manage them throughout their lifecycle. When a model is created with Juju, a corresponding Kubernetes namespace is created. When a charm is deployed on Kubernetes, it is deployed as a StatefulSet that manages a set of Pods running the specified application containers alongside a sidecar container containing the charm code.

By definition, the sidecar pattern is designed to allow the augmentation of workloads with additional capabilities and features. The pattern is implemented in this case by a small auxiliary container, located in the same Pod as your application, that provides operations functionality - this is exactly how Juju operates in other environments, and a well-established pattern in the Kubernetes community.

By utilising this pattern, we ensure that there is always an operator right next to every unit of the workload, irrespective of how the application is scaled. The operator will always have direct access to shared memory, the same network namespace and the ability to manipulate the workload as required to keep it running smoothly. This approach simplifies the operation of upstream or third-party application images, enabling administrators to make changes at runtime to suit their environment should they wish, without the requirement to maintain a fleet of bespoke container images.

For charm developers, these benefits are realised by utilising Pebble to manage workloads. Pebble is a lightweight, API-driven process supervisor designed for use with Charmed Operators. Pebble enables charm developers to define how they want workloads to run, and provides an API that enables operations code to manage the workloads throughout their life.

Subordinate charms

Subordinate charms were created to enable the development of charms that could be deployed alongside existing charms, to augment them with specific functionality that may not be included in the original application charm. They are, in many ways, analogous to the sidecars described above. All charms are principal charms, except those that are subordinates. A subordinate charm depends on the creation of a relationship to a principal charm, it is never deployed as a standalone application. This is best explained with an example:

Consider the deployment of a large web application scaled to n replicas. Each instance of the charm comprises a unit, in Juju parlance, and an App is the sum of all units of a given charm with the same name. When a large web application is scaled to n replicas, n units will be started by Juju.

The administrators of the web application will likely want to collect logs from the application server. The developer of the application charm may not have included a mechanism for forwarding logs from the service that is compatible with the administrator’s specific environment. By using a subordinate charm such as rsyslog-forwarder, the administrator can ensure that each deployed unit of their web application is automatically configured to forward logs using rsyslog. To do this, they must simply deploy the subordinate and juju relate their web application to it.

Subordinate charms are written in the same way as other charms, with the addition of an extra subordinate flag in the charm’s metadata.

Multi-cloud models

One of the most powerful concepts in Juju deployments is the way application deployments are modelled. A single Juju controller can interact with multiple underlying substrates, be those bare-metal private clouds, public clouds or a hand-crafted Kubernetes cluster. Irrespective of the substrate they are deployed upon, charms can be related using cross-model relations. This enables seamless interoperability between substrates, where the Juju OLM handles all of the networking, permissions and configuration on your behalf.

For example, if you already bootstrapped a database cluster on bare-metal using Juju, but your new web application runs on Kubernetes, you can just juju relate your different charms for seamless integration across clouds.


Level Path Navlink
0 The SDK docs
1 about About the SDK
1 dev-setup Development Setup
1 hello-world Hello, World
0 Charming Essentials
1 charm-anatomy Charm Anatomy
1 events Lifecycle Events
1 constructs Framework Constructs
1 pebble Interacting with Pebble
1 workloads Running Workloads
1 config Handling Configuration
1 actions Handling Actions
1 logging Logging
1 testing Testing
1 charm-documentation Charm Documentation
0 Advanced Topics
1 leadership Leadership
1 relations Relations
1 storage Storage
1 libraries Libraries
1 resources Resources
1 debugging Debugging
0 Charmcraft
1 setting-up-charmcraft Installing Charmcraft
1 charmcraft-config Configuration
1 publishing Publishing Charms
1 publishing-resources Publishing Resources
1 charmcraft-libraries Publishing Libraries
1 bundles Publishing Bundles
1 charmcraft-analyze Analyzers and Linters
1 charmcraft-deprecations Deprecations
1 remote-env-auth Authentication in Remote Environments
1 charmcraft-roadmap Roadmap
0 Get Help
1 discourse Community Discourse
1 chat Community Chat
0 Reference
1 Github
1 API Documentation
1 naming Charm Naming Guide
1 metadata-reference Metadata reference
1 bundle-reference Bundle reference
1 history Charming History


Mapping table
Path Location

There’s a few bugs in this document:

Under the “Kubernetes Charm” header
When a model is created on Kubernetes, a corresponding Kubernetes namespace is created.

This should read “When a model is created in juju, a corresponding…”

1 Like

Thanks, will fix now.

Although the navigation menu here correctly links “Github” to, when rendered it is linked to, which is a 404.

Hmm that’s annoying, I wonder if that’s changed recently :confused:

@toto do you know how to solve that? Trying to link to an external link the nav?

@jkfran Can you please take a look here?

I opened a bug on it a few days back, I believe it is being worked on -

We had a bug in the previous version of our documentation parser with external links. It should be fine now :slight_smile:

1 Like

Hi, here are sum suggestions/fixes/imporvements on the doc.

Hi Kos - top reviewing today!

Have made some adjustments here. I’ve left the charmed operators link pointing at the docs homepage as it has a brief definition and link off to other places with more context. Will review when I find a better end destination!

I made some additional clarifying edits about what a unit is compared to an application as a corollary to the “scale to n replicas” example.