Hello, World

This section will guide you through the process of initialising an empty Charm template, and explain the purpose of each file.


The Charmcraft tool is used throughout the Charm development process, from initialising early directory structure, to publishing your finished Charm to Charmhub.

To get started, let’s create a new Charm named hello-operator, placing the template in its own directory:

# Create the Charm directory
$ mkdir hello-operator
# Initialise the Charm directory
$ charmcraft init --project-dir hello-operator --name hello-operator

This will create a skeleton directory structure, described below:

# Documentation
├── README.md            # The front page documentation for your charm
├── LICENSE              # Your Charm's license, we recommend Apache 2
# Charm specification and requirements
├── metadata.yaml        # Charmed Operator package description and metadata
├── requirements.txt     # PyPI requirements for the charm runtime environment
# Runtime features
├── config.yaml          # Configuration schema for your operator
├── actions.yaml         # Day 2 action declarations, e.g. backup, restore
# Development files
├── requirements-dev.txt # PyPI requirements for development environment
├── run_tests            # Bash script to run Charm tests
# Charm code and tests
├── src                  # Top-level source code directory for Charm
│ └── charm.py           # Minimal operator using Charmed Operator Framework
└── tests # Top-level directory for Charm tests
├── __init__.py
└── test_charm.py        # Skeleton unit tests for generated charm

The metadata.yaml file is critical, and has a detailed spec that enables you to specify where your Charm should run, how it communicates with other Charms using relations, and any Resources it depends on. We’ll cover these concepts in greater detail later in the docs.

In most Charms, the majority of the operator code is likely to live in src/charm.py, and it is the default entrypoint for the Charm.

Deploy the charm

We can now build and deploy our (very minimal!) Charm. Before we do that, let’s configure the Juju model to display DEBUG level log messages and watch the output. Open another terminal and run the following:

# Set the default log level to DEBUG
$ juju model-config logging-config="<root>=WARNING;unit=DEBUG"
# Tail the Juju log
$ juju debug-log

Now, back to our original terminal:

# Build the Charm package (outputs ./hello-operator.charm)
$ charmcraft pack
# Deploy the packaged Charm
$ juju deploy ./hello-operator.charm --resource httpbin-image=kennethreitz/httpbin
# Watch the Juju status to see the Charm's progress
$ watch -n1 --color "juju status --color"

We have to specify the httpbin-image resource to tell Juju which OCI image to deploy for the default container in the template. When your charms are published, this is no longer necessary because the OCI image resource is attached to the charm when you release it. Read more in Publishing and Resources.

The deployment will take about 30 seconds, and you should see the various operator events being triggered in the juju debug-log output. If all goes well, you should see output similar to the following:

Model        Controller  Cloud/Region        Version  SLA          Timestamp
development  micro       microk8s/localhost  2.9.0    unsupported  10:25:35+01:00

App             Version  Status  Scale  Charm           Store  Channel  Rev  OS          Address  Message
hello-operator           active      1  hello-operator  local             0  kubernetes           

Unit               Workload  Agent  Address       Ports  Message
hello-operator/0*  active    idle                

Note that you can inspect the content of your Charm easily - the bundle is just a zip file! Go ahead and open up hello-operator.charm in your native archive viewer to see how the Charm gets packaged up.

Now the charm is deployed, you should be able to browse to the Pod IP (if you’re using MicroK8s) and see the httpbin user interface. You can confirm it’s working with:

# curl the pod ip (using the example above)
$ curl

Cleaning Up

Now you’ve deployed your charm, you might want to clear up your cluster and remove what we’ve done. You have a few options:

# ⚠ Destroy the model, removing the application and machines with it
$ juju destroy-model --force --no-wait development
# ⚠ Destroy the controller, and also any associated models and deployed applications
# ⚠ Note that you will need to bootstrap again before using Juju on the cluster
$ juju kill-controller -y -t0 micro

Last updated 13 days ago.