What is a charm?

A charm is software that wraps an application and that contains all of the instructions necessary for deploying, configuring, operating an application on any cloud using Juju.

A charm generally contains the operations (charm) code and the information on where to get the application itself (the workload). Each application has a number of deployed "units" and includes information about the services they offer or require. There is a copy of the charm in each unit of the application, so that the operations code is always right next to the workload it is driving.

Charms include deterministic logic that specifies what happens when specific events occur. Events can be triggered by an administrator (e.g. through the CLI), by other charms or the external environment.

The administrator interacts with a client (CLI, Terraform, python-libjuju or Jimm), which talks to the controller. The controller talks to the agent in the charm, which in turns invokes the charm code to manipulate the application.

Charms are currently of two kinds, depending on the target deployment substrate:


  1. Machine charms: Charms made to deploy on a bare-metal server, virtual machine, or system container.
  2. Kubernetes charms: Charms built to deploy on Kubernetes.

What are agents and workers

An agent is software that works to realise the state declared by an end-user with a client (e.g., the Juju CLI), for an entity (e.g., controller, model, machine, unit) via workers.

A worker is a process that an agent runs in the background on a Juju entity (controller, model, machine, unit, etc.) and that performs a single, specific task. A Juju agent runs one or more workers at the same time.

Agents can be of different types:


  • Controller agent: a process running workers responsible for a controller. This includes, among others, the Juju API server.
  • Machine agent: Found on machine clouds, this is a process running workers responsible for a machine.
  • Model agent: Found on machine and Kubernetes clouds, this is a juju process running workers responsible for all the models associated with a given controller.
  • Unit agent: Found on machine and Kubernetes clouds, this is a process responsible for a unit.

What is pebble

Pebble is a lightweight, API-driven process supervisor. In Kubernetes charms it is used to give workload containers something akin to an init system that will allow the charm container to interact with them.

Pebble allows to start, stop, restart and update services while taking into account service dependencies. Pebble implements custom "health checks" that can be configured to restart services when they fail, as well as the ability to forward logs to a remote Loki server.

Pebble also includes a subsystem called notices, which allows the user to introspect various events that occur in the Pebble server, as well as record custom client events. The server saves notices to disk, so they persist across restarts, and expire after a notice-defined interval.


How do charms work?

A simple explanation of how charms interact with Juju and the workload they operate

The Juju controller is the brain of every deployment and it is a process that runs in the background and it is in between the client, backing cloud, Charmhub, and the various unit agents in a deployment. The controller also maintains the state of the system, as well as other data structures that can be accessed by the charms.


When a client issues a command the following happens:


  1. When the client parses your command it sends a request to the Juju controller API.
  2. The Juju controller parses the command and makes a change to the data structure representing the model, as well as the cloud substrate to represent what the command says (e.g. adding a unit).
  3. The Juju agents, running in each charm unit, constantly interrogate the controller, looking for changes that affect them. When there is a discrepancy between their local state and the one represented in the controller they compute a diff and create some “events”.
  4. The agent then fires events at the charm code, which includes a specific set of actions that need to occur when a specific event occurs, as well as logic to specify their relative ordering.
  5. The charm operates the workload in whatever way appropriate to the event being handled; if necessary, it will interact with the live workload through pebble, to read/write the workload filesystem, run commands, etc…
  6. The state of the unit is aligned with the one represented in the controller.

For more detailed information you can read our charm lifecycle documentation article >

The Juju controller persists a wide ranging set of information about the status of the system and the deployed charms, including:


  • Integration data
  • Charm configuration
  • Unit/application status
  • Charm state
  • Leadership status

Charms at runtime can read/write some data from the controller database and thereby access some configuration parameters to decide which code path to execute and how to manage its workload.

For more detailed information you can read our charm lifecycle documentation article


Read about these next:


Juju integrations are virtual connections between charms to allow the exchange of information.


Charmhub is a curated marketplace for charms which can be readily integrated into any infrastructure

Get started with Juju today

Read Docs