charmcraft.yaml file

Important

charmcraft.yaml file is the only yaml file generated by charmcraft init and the only yaml file in a charm project that a charm author should edit directly.

Charmcraft will use the information you provide here to generate actions.yaml file, config.yaml file, and metadata.yaml file, as well as all the other files it usually does.

charmcraft.yaml is a file in your charm project that contains keys that allow you to declare information about the project in a form that can be used by Charmcraft.

Note

If you’re starting from an empty file, the only required key is the type key. However, depending on what value you set it to (charm or bundle), other keys become required as well.

Expand to view a full charm with sample content all at once
actions:
  snapshot:
    description: Take a snapshot of the database.
    params:
      filename:
        type: string
        description: The name of the snapshot file.
      compression:
        type: object
        description: The type of compression to use.
        properties:
          kind:
            type: string
            enum:
            - gzip
            - bzip2
            - xz
          quality:
            description: Compression quality
            type: integer
            minimum: 0
            maximum: 9
    required:
    - my-favourite-photo.tiff
    additionalProperties: false
analysis:
  ignore:
    attributes:
    - framework
    linters:
    - entrypoint
assumes:
  - any-of:
    - juju >= 2.9.23
    - all-of:
      - juju >= 3.5
      - juju < 4.0
  - k8s-api
base: [email protected]
build-base: ubuntu@devel
charm-libs:
  - lib: postgresql.postgres_client
    version: "1"
  - lib: mysql.mysql
    version: "0.5"
config:
  options:
    name:
      default: Wiki
      description: The name, or Title of the Wiki
      type: string
    logo:
      description: URL to fetch logo from
      type: string
    admins:
      description: 'Comma-separated list of admin users to create: user:pass[,user:pass]+'
      type: string
    debug:
      default: false
      type: boolean
      description: turn on debugging features of mediawiki
    port:
      default: 80
      type: int
      description: port on which to serve the wiki
    timeout:
      default: 60.0
      type: float
      description: maximum time before rendering a page will fail
    certificate:
      type: secret
      description: TLS certificate to use for securing connections
containers:
  super-app:
    resource: super-app-image
    mounts:
    - storage: logs
      location: /logs
description: |
  This is a long description of the charm. It gets used when the charm is uploaded to
  Charmhub. It is a string, but can easily be made a multiline string or any other
  YAML string format.
devices:
  super-cool-gpu:
    type: amd.com/gpu
    description: Some sweet AMD GPU
    countmin: 69
    countmax: 420
  lame-gpu:
    type: nvidia.com/gpu
    description: A GPU I regret buying
    countmin: 0
    countmax: 1
extra-bindings:
  Ring of Power:
links:
  contact: Please send your answer to Old Pink, care of the Funny Farm, Chalfont
  documentation: https://juju.is/docs/sdk/charmcraft-yaml
  issues:
  - https://launchpad.net/~charmcraft-team
  - https://github.com/canonical/charmcraft/issues
  source:
  - https://github.com/canonical/charmcraft
  website:
  - https://snapcraft.io/charmcraft
name: full-charm
parts:
  my-charm:
    plugin: charm
    source: .
    charm-entrypoint: src/charm.py
    charm-binary-python-packages: []
    charm-python-packages: []
    charm-requirements: [requirements.txt]
    charm-strict-dependencies: false
  another-part:
    plugin: nil
    source:
peers:
  friend:
    interface: life
    limit: 150
    optional: true
    scope: container
platforms:
  all:
    build-on:
      - amd64
      - arm64
      - riscv64
      - s390x
      - ppc64el
      - armhf
    build-for: [all]
  amd64:
    build-on: [amd64]
    build-for: [amd64]
  arm64:
    build-on:
      - amd64
      - arm64
    build-for:
      - arm64
provides:
  self:
    interface: identity
requires:
  parent:
    interface: birth
    limit: 2
    optional: false
    scope: global
resources:
  water:
    type: file
    filename: /dev/h2o
  super-app-image:
    type: oci-image
    description: OCI image for the Super App (hub.docker.com/_/super-app)
storage: # Possible storage for the charm
  jbod:
    type: block
    description: A nice block storage for me to use as swap space
    shared: false
    properties:
    - transient
subordinate: false
summary: A fully-defined charm, making use of all the available charm keywords.
terms:
 - Butterscotch is regal
 - Cara is adorable
title: My awesome charm
type: charm

actions

Definition owned by Juju. Used by Charmcraft, Charmhub, Juju.

Status: Optional.

Purpose: Defines actions the charm can take.

Name: String = user-defined action name.

Value: Mapping.

The value of this key is the contents of actions.yaml file.

Example
actions:
  snapshot:
    description: Take a snapshot of the database.
    params:
      filename:
        type: string
        description: The name of the snapshot file.
      compression:
        type: object
        description: The type of compression to use.
        properties:
          kind:
            type: string
            enum:
            - gzip
            - bzip2
            - xz
          quality:
            description: Compression quality
            type: integer
            minimum: 0
            maximum: 9
    required:
    - my-favourite-photo.tiff
    additionalProperties: false

analysis

Definition owned by Charmcraft. Used by Charmcraft.

Status: Optional.

Purpose: Defines how the analysis done on the package will behave. This analysis is run implicitly as part of the pack command but can be called explicitly with the charmcraft analyse command.

Structure:

analysis:
  ignore:
    attributes: [<check-name>,...]
    linters: [<check-name>,...]
Example
analysis:
  ignore:
    attributes:
    - framework
    linters:
    - entrypoint

assumes

Status: Optional. Recommended for Kubernetes charms.

Purpose: Allows charm authors to explicitly state in the metadata of a charm various features that a Juju model must be able to provide to ensure that the charm can be successfully deployed on it. When a charm comes preloaded with such requirements, this enables Juju to perform a pre-deployment check and to display user-friendly error messages if a feature requirement cannot be met by the model that the user is trying to deploy the charm to. If the assumes section of the charm metadata is omitted, Juju will make a best-effort attempt to deploy the charm, and users must rely on the output of juju status to figure out whether the deployment was successful.

Structure: The key consists of a list of features that can be given either directly or, depending on the complexity of the condition you want to enforce, nested under one or both of the boolean expressions any-of or all-of, as shown below. In order for a charm to be deployed, all entries in the assumes block must be satisfied.

assumes:
 - <feature>
 - any-of:
   - <feature>
   - <feature>
 - all-of:
   - <feature>
   - <feature>
Supported features

Structure

Description

Examples

Juju versions

juju <comparison predicate> <version number>

The charm deploys iff the model runs agent binaries with the specified Juju version(s).

juju >= 3.0 juju < 4.0

Since 2.9.23

k8s-api

The charm deploys iff the backing cloud for the model is Kubernetes.

k8s-api

Since Juju 2.9.23

Simple example
assumes:
 - juju >= 2.9.23
 - k8s-api
Complex example
assumes:
  - any-of:
    - juju >= 2.9.23
    - all-of:
      - juju >= 3.5
      - juju < 4.0
  - k8s-api

base

Status: Required in most cases if type is charm.

Purpose: Specifies the operating system on which the charm will build and run.

Structure:

base: <distro>@<series>

Example:

bases

Note

bases is deprecated, replaced by base, build-base, and platforms.

See more

The bases key is only accepted for bases supported before 2024-01-01.

# The run time base, the base format is <os-name>@<os-release>,
# accepted bases are:
# - [email protected]
# - [email protected]
base: <base>
# The build time base. Only used if the runtime base is not stable.
# Accepts all runtime bases and ``ubuntu@devel``
build-base: <base>

# The supported platforms
platforms:
  <platform-name>:
    build-on: <list-of-arch> | <arch>
    build-for: <list-of-arch> | <arch>

Status: Deprecated. Conflicts with the base, build-base, and platforms keys. Not allowed if type is bundle.

Purpose: Specifies a list of environments (OS version and architecture) where the charm must be built on and run on.

Structure: This key supports a list of bases where the charm can be built, and where that build can run. Each item can be expressed using two different internal structures, a short and a long form. The long one is more explicit:

bases:
  - build-on:
      - name: <name>
    channel: <channel>
    architectures:
      - <arch>
    run-on:
      - name: <name>
    channel: <channel>
    architectures:
      - <arch>

The run-on part of each entry is optional and defaults to what’s specified in the corresponding build-on. In both structures the list of architecture strings is also optional, defaulting to the architecture of the current machine.

The short form is more concise and simple (at the cost of being less flexible):

bases:
  - name: <name>
    channel: <channel>
    architectures:
      - <arch>

It implies that the specified base is to be used for both build-on and run-on. As above, the list of architecture strings is also optional, defaulting to the machine architecture.

Example
bases:
  - build-on:
      - name: ubuntu
    channel: '22.04'
    architectures:
      - amd64
      - riscv64
      - name: ubuntu
    channel: '20.04'
    architectures:
      - amd64
      - arm64
    run-on:
      - name: ubuntu
    channel: '22.04'
    architectures:
      - amd64
      - name: ubuntu
    channel: '22.04'
    architectures:
      - riscv64
      - name: ubuntu
    channel: '22.04'
    architectures:
      - arm64
  - build-on:
      - name: ubuntu
    channel: '24.04'
    run-on:
      - name: ubuntu
    channel: '24.04'
    architectures:
      - amd64
      - arm64
      - riscv64
      - s390x
      - ppc64el
      - armhf

build-base

Status: Only valid if base is a development base.

Purpose: Specifies the operating system on which the charm will be built.

Structure:

build-base: <distro>@<series>

Example:

base: ubuntu@devel

charm-libs

Status: Optional.

Purpose: Declares charm libraries for Charmcraft to include in the charm project. For each lib, include both the lib name (in <charm>.<library> format) and the lib version (in "<api version>[.<patch version>]" string format).

Structure:

charm-libs:
  - lib: <charm>.<library>
    version: "<api>[.<patch>]"  # Must be a string, not a number.

Example:

charm-libs:
  - lib: postgresql.postgres_client
    version: "1"
  - lib: mysql.mysql
    version: "0.5"

charmhub

Caution

This key is only meaningful in Charmcraft 2. Use the environment variables CHARMCRAFT_STORE_API_URL, CHARMCRAFT_UPLOAD_URL and CHARMCRAFT_REGISTRY_URL for newer versions of Charmcraft.

Status: Deprecated and nonfunctional in Charmcraft 3.

Purpose: Configures Charmcraft’s interaction with store servers.

Structure: This key allows for the configuration of three values—the base URL for the Charmhub API, the base URL to push binaries to Charmhub and the URL of the container registry for OCI image uploads. These keys are also optional.

charmhub:
  api-url: <api url>
  storage-url: <storage url>
  registry-url: <registry url>

The key is used mostly in the context of “private” charm stores, defaulting to the standard Canonical services to operate with charms.

Example
charmhub:
  api-url: https://api.staging.charmhub.io
  storage-url: https://storage.staging.snapcraftcontent.com

config

Status: Optional.

Purpose: Creates user-facing configuration options for the charm.

Structure:

config:
  options:
    # Each option name is the name by which the charm will query the option.
    <option name>:
      # (Required) The type of the option
      type: string | int | float | boolean | secret
      # (Optional) The default value of the option
      default: <a reasonable default value of the same type as the option>
      # (Optional): A string describing the option. Also appears on charmhub.io
      description: <description string>

If type is secret, this is a string that needs to correspond to the secret URI.

Example
config:
  options:
    name:
      default: Wiki
      description: The name, or Title of the Wiki
      type: string
    logo:
      description: URL to fetch logo from
      type: string
    admins:
      description: 'Comma-separated list of admin users to create: user:pass[,user:pass]+'
      type: string
    debug:
      default: false
      type: boolean
      description: turn on debugging features of mediawiki
    port:
      default: 80
      type: int
      description: port on which to serve the wiki
    timeout:
      default: 60.0
      type: float
      description: maximum time before rendering a page will fail
    certificate:
      type: secret
      description: TLS certificate to use for securing connections

containers

Status: Required for Kubernetes charms (except for proxy charms running on Kubernetes).

Purpose: The containers key allows you to define a map of containers to be created adjacent to the charm (as a sidecar, in the same pod).

Structure: This key consists of a list of containers along with their specification. Each container can be specified in terms of resource, bases, uid, gid and mounts, where one of either the resource or the bases subkeys must be defined, and mounts is optional. resource stands for the OCI image resource used to create the container; to use it, specify an OCI image resource name (that you will then define further in the resources block). bases is a list of bases to be used for resolving a container image, in descending order of preference; to use it, specify a base name (for example, ubuntu, centos, windows, osx, opensuse), a channel, and an architecture. mounts is a list of mounted storages for this container; to use it, specify the name of the storage to mount from the charm storage and, optionally, the location where to mount the storage. Starting with Juju 3.5.0, uid and gid are the UID and, respectively, GID to run the Pebble entry process for this container as; they can be any value from 0-999 or any value from 10,000 (values from 1000-9999 are reserved for users) and the default is 0 (root).

containers:
  <container name>:
    resource: <resource name>
    bases:
      - name: <base name>
    channel: <track[/risk][/branch]>
    architectures:
      - <architecture>
    mounts:
      - storage: <storage name>
    location: <path>
    uid: <unix UID>
    gid: <unix GID>
Example
containers:
  super-app:
    resource: super-app-image
    mounts:
    - storage: logs
      location: /logs

description

Status: Required if the type key is set to charm. Recommended otherwise.

Example:

description: |
  This is a long description of the charm. It gets used when the charm is uploaded to
  Charmhub. It is a string, but can easily be made a multiline string or any other
  YAML string format.

devices

Status: Optional

Purpose: Defines the device requests for the charm, for example a GPU.

Structure:

devices:
    # Each key represents the name of the device
    <device name>:
    # (Required) The type of device requested
    type: gpu | nvidia.com/gpu | amd.com/gpu
    # (Optional) Description of the requested device
    description: <description>
    # (Optional) Minimum number of devices required
    countmin: <n>
    # (Optional) Maximum number of devices required
    countmax: <n>
Example
devices:
  super-cool-gpu:
    type: amd.com/gpu
    description: Some sweet AMD GPU
    countmin: 69
    countmax: 420
  lame-gpu:
    type: nvidia.com/gpu
    description: A GPU I regret buying
    countmin: 0
    countmax: 1

extra-bindings

Status: Optional.

Purpose: Extra bindings for the charm. For example binding extra network interfaces.

Structure: A key-only map; key represents the name of the binding:

extra-bindings:
  <binding name>:

Example:

extra-bindings:
  Ring of Power:

name

Status: Required if the type key is set to charm.

Purpose: The name of the charm. Determines the .charm file name and, if the charm is published on Charmhub, the charm page URL in Charmhub. As a result, it also determines the name administrators will ultimately use to deploy the charm. E.g. juju deploy <name>.

Structure:

name: <name>

Example:

      filename:
        type: string
        description: The name of the snapshot file.
      compression:
        type: object
        description: The type of compression to use.
        properties:
          kind:
            type: string
            enum:
            - gzip
            - bzip2
            - xz
          quality:
            description: Compression quality
            type: integer
            minimum: 0
            maximum: 9
    required:
    - my-favourite-photo.tiff
    additionalProperties: false
analysis:
  ignore:
    attributes:
    - framework
    linters:
    - entrypoint
assumes:
  - any-of:
    - juju >= 2.9.23
    - all-of:
      - juju >= 3.5
      - juju < 4.0
  - k8s-api
base: ubuntu@24.04
build-base: ubuntu@devel
charm-libs:
  - lib: postgresql.postgres_client
    version: "1"
  - lib: mysql.mysql
    version: "0.5"
config:
  options:
    name:
      default: Wiki
      description: The name, or Title of the Wiki
      type: string
    logo:
      description: URL to fetch logo from
      type: string
    admins:
      description: 'Comma-separated list of admin users to create: user:pass[,user:pass]+'
      type: string
    debug:
      default: false
      type: boolean
      description: turn on debugging features of mediawiki
    port:
      default: 80
      type: int
      description: port on which to serve the wiki
    timeout:
      default: 60.0
      type: float
      description: maximum time before rendering a page will fail
    certificate:
      type: secret
      description: TLS certificate to use for securing connections
containers:
  super-app:
    resource: super-app-image
    mounts:
    - storage: logs
      location: /logs
description: |
  This is a long description of the charm. It gets used when the charm is uploaded to
  Charmhub. It is a string, but can easily be made a multiline string or any other
  YAML string format.
devices:
  super-cool-gpu:
    type: amd.com/gpu
    description: Some sweet AMD GPU
    countmin: 69
    countmax: 420
  lame-gpu:
    type: nvidia.com/gpu
    description: A GPU I regret buying
    countmin: 0
    countmax: 1
extra-bindings:
  Ring of Power:
links:
  contact: Please send your answer to Old Pink, care of the Funny Farm, Chalfont
  documentation: https://juju.is/docs/sdk/charmcraft-yaml
  issues:
  - https://launchpad.net/~charmcraft-team
  - https://github.com/canonical/charmcraft/issues
  source:
  - https://github.com/canonical/charmcraft
  website:
  - https://snapcraft.io/charmcraft
name: full-charm

parts

Status: Recommended.

Purpose: Configures the various mechanisms to obtain, process and prepare data from different sources that end up being a part of the final charm.

Structure: Mapping. Keys are user-defined part names. The value of each key is a map where keys are part properties.

See more: Part properties

Example
parts:
  my-charm:
    plugin: charm
    source: .
    charm-entrypoint: src/charm.py
    charm-binary-python-packages: []
    charm-python-packages: []
    charm-requirements: [requirements.txt]
    charm-strict-dependencies: false
  another-part:
    plugin: nil
    source:
Details

Charmcraft offers three custom parts plugins specifically for writing charms:

The charm plugin

Used to pack a Charm that is based on the Operator framework.

Supports the following configuration:

parts:
  my-charm:
    plugin: charm
    charm-entrypoint: <path to an entrypoint script>
    charm-requirements: <list of requirements files>
    charm-python-packages: <list of package names>
    charm-binary-python-packages: <list of package names>
    prime: <list of paths to extra files>

In detail:

  • charm-entrypoint: The charm entry point, relative to the project directory. It is optional if not defined defaults to src/charm.py.

  • charm-requirements: A list of requirements files specifying Python dependencies. It is optional; if not defined, defaults to a list with one requirements.txt entry if that file is present in the project directory.

  • charm-python-packages: A list of Python packages to install before installing requirements. These packages will be installed from sources and built locally at packing time. It is optional, defaults to empty.

  • charm-binary-python-packages: A list of python packages to install before installing requirements and regular Python packages. Binary packages are allowed, but they may also be installed from sources if a package is only available in source form. It is optional, defaults to empty.

The bundle plugin

Used to pack a charm bundle, a collection of charms which have been carefully combined and configured in order to automate a multi-charm solution.

Supports the following configuration:

parts:
  my-bundle:
    plugin: bundle

The reactive plugin

Used to pack charms using the reactive framework.

Note that this is a framework that has now been superseded by the Operator framework. Please use that framework instead of reactive. Support for reactive in Charmcraft is only to ease the transition of old charms into the new framework.

Supports the following configuration:

parts:
  charm:
    source: .
    plugin: reactive
    build-snaps: [charm]
    reactive-charm-build-arguments: <list of command line options>

The reactive_charm_build_arguments allows to include extra command line arguments in the underlying charm build call.

peers, provides, and requires

Example featuring all three keys
peers:
  friend:
    interface: life
    limit: 150
    optional: true
    scope: container
provides:
  self:
    interface: identity
requires:
  parent:
    interface: birth
    limit: 2
    optional: false
    scope: global
The full schema for a chosen endpoint role
<endpoint role>: # 'peers', 'provides', or 'requires'
  # Each key represents the name of the endpoint as known by this charm
  <endpoint name>:
    # (Required) The interface schema that this relation conforms to
    interface: <endpoint interface name>

    # (Optional) Maximum number of supported connections to this relation
    # endpoint. This field is an integer
    limit: <n>

    # (Optional) Defines if the relation is required. Informational only.
    optional: true | false

    # (Optional) The scope of the relation. Defaults to "global"
    scope: global | container

<endpoint role>

Status: If you want to define any kind of integration, required.

Purpose: To define an integration endpoint.

Structure:

Name: Depending on what kind of an integration you are trying to define: peers, provides, or requires.

Type: Map.

Value: One or more key-value pairs denoting a relation and its associated properties.

<endpoint role>.<endpoint name>

Status: Required.

Purpose: To define the name of the relation as known by this charm.

Structure:

Name: User-defined.

Type: string.

<endpoint role>.<endpoint name>.interface

Status: Required.

Purpose: To define the interface schema that this relation conforms to.

Structure:

Type: String.

Value: The name of the interface. Usually defined by the author of the charm providing the interface. Cannot be juju. Cannot begin with juju-. Must only contain characters a-z and - and cannot start with -.

Caution

The interface name is the only means of establishing whether two charms are compatible for integration; and carries with it nothing more than a mutual promise that the provider and requirer know the communication protocol implied by the name.

<endpoint role>.<endpoint name>.limit

Status: Optional.

Purpose: To define the maximum number of supported connections to this relation endpoint.

Structure:

Type: Integer.

<endpoint role>.<endpoint name>.optional

Status: Optional.

Purpose: To define if the relation is required. Informational only.

Structure:

Type: Boolean.

Default value: false

<endpoint role>.<endpoint name>.scope

Status: Optional.

Purpose: To define the scope of the relation, that is, the set of units from integrated applications that are reported to the unit as members of the integration.

Structure:

Type: String.

Possible values: container, global.

Container-scoped integrations are restricted to reporting details of a single principal unit to a single subordinate, and vice versa, while global integrations consider all possible remote units. Subordinate charms are only valid if they have at least one requires integration with container scope.

Default value: global.

resources

Status: Optional.

Purpose: To define a resource for your charm.

Note

Kubernetes charms must declare an oci-image resource for each container they define in the containers mapping.

Structure:

resources:
  <resource-name>:
    type: <file> or <oci-image>
    description: <string description of the resource>
    filename: <path to resource if it is a file>
File resource example
resources:
  water:
    type: file
    filename: /dev/h2o
OCI image example
resources:
  super-app-image:
    type: oci-image
    description: OCI image for the Super App (hub.docker.com/_/super-app)

storage

Status: Optional.

Purpose: Storage requests for the charm.

Structure:

storage:
  # Each key represents the name of the storage
  <storage name>:

    # (Required) Type of the requested storage
    # The filesystem type requests a directory in which the charm may store files.
    # If the storage provider only supports provisioning disks, then a disk will be
    # created, attached, partitiioned, and a filesystem created on top, and the
    # filesystem will be presented to the charm as normal.
    # The block type requests a raw block device, typically disks or logical volumes.
    type: filesystem | block

    # (Optional) Description of the storage requested
    description: <description>

    # (Optional) The mount location for filesystem stores. For multi-stores
    # the location acts as the parent directory for each mounted store.
    location: <location>

    # (Optional) Indicates if all units of the application share the storage
    shared: true | false

    # (Optional) Indicates if the storage should be made read-only (where possible)
    read-only: true | false

    # (Optional) The number of storage instances to be requested
    multiple:
    range: <n> | <n>-<m> | <n>- | <n>+

    # (Optional) Minimum size of requested storage in forms G, GiB, GB. Size
    # multipliers are M, G, T, P, E, Z or Y. With no multiplier supplied, M
    # is implied.
    minimum-size: <n>| <n><multiplier>

    # (Optional) List of properties, only supported value is "transient"
    properties:
      - transient
Example
storage: # Possible storage for the charm
  jbod:
    type: block
    description: A nice block storage for me to use as swap space
    shared: false
    properties:
    - transient

subordinate

Status: Optional.

Purpose: Configures whether the charm is meant to be deployed as a subordinate to a principal charm.

Structure:

subordinate: true | false

Example:

subordinate: false

summary

Status: Required if the type key is set to charm.

Structure: A short, one-line description of the charm. No more than 78 characters.

Example
summary: A Juju charm to run a Traefik-powered ingress controller on Kubernetes.

terms

Status: Optional.

Purpose: Lists the terms that any charm user agree to when they’re using the charm.

Structure: The list of terms:

terms:
  - <term>
Example
terms:
 - Butterscotch is regal
 - Cara is adorable

title

Status: Optional, but recommended

Purpose: A human-readable name for your charm

Example
title: My awesome charm

type

Status: Required.

Purpose: Indicates whether charmcraft will pack a charm or a bundle.

Structure:

Type: String.

Value: charm or bundle.

Example
type: charm