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
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 10.1.215.218
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 10.1.215.218
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