In Juju, the PaaS App charmer is a charm SDK supplement specialised in applications written using various specific frameworks (e.g., Flask or Django).
For each framework, the PaaS App Charmer provides a coordinated, framework-specific suite consisting of:
- a Rockcraft profile + matching extension and
- a matching Charmcraft profile + matching extension
designed to help you build a functional rock and charm in just a couple of steps.
tl;dr: Rock-n'-charm a Flask application using the PaaS App Charmer's 'flask-framework' suite
Rock:
- Initialise the rock:
rockcraft init --profile flask-framework
, which will generate all the basic structure and content you’ll need for the rock, including arockcraft.yaml
withextensions: ["flask-framework"]
. - Pack the rock:
rockcraft pack
, which will pack the rock into an artifact you can upload to a container image registry.
Charm:
- Initialise the charm:
charmcraft init --profile flask-framework
. This will generate all the basic structure content you’ll need for the charm, including acharmcraft.yaml
pre-loaded withextensions: ["flask-framework"]
and asrc/charm.py
pre-loaded withpaas_app_charmer.flask
. - (optional) Edit the
charmcraft.yaml
file to declare a configuration or an integration, from the list supported by the PaaS App Charmer for the Flask framework. - Pack the charm:
charmcraft pack
, which will pack the charm into an artifact you can (optionally, publish on Charmhub and) deploy and manage with Juju.
The PaaS App Charmer thus makes it easy and fast to integrate certain classes of applications into the charm ecosystem.
The PaaS App Charmer is especially suitable for Juju users who find themselves in the position where they have to fill the gap between
- applications that are general purpose and already have a public charm and
- applications that are specific to their business and thus lack a charm and may never have a public charm. the PaaS App Charmer (at least, for 12-factor / web apps)
Contents:
List of PaaS App Charmer suites
This section documents all of the PaaS App Charmer suites – their names and the specific charm they produce, especially the knobs they expose that you can use to customise the charm further in the various supported ways.
All of these knobs are related in one way or another to the rockcraft.yaml
or charmcraft.yaml
file.
To learn about these files and their generic keys in general see Rockcraft | File rockcraft.yaml
and, respectively, Charmcraft | File charmcraft.yaml
.
To find out about more about these files in the form generated by the PaaS App Charmer, examine these files and their contents in your rock/charm directory, either in the default, abbreviated form or by expanding the content contributed by the extension in use by running rockcraft expand-extension
/ charmcraft expand-extension
. See more: Manage extensions > View details about an extension in use.
The documentation below will focus on the latter, highlighting especially the bits that you can customise to take full advantage of the capabilities supported out-of-the-box by the PaaS App Charmer.
flask-framework
The flask-framework
suite (resulting in a Rockcraft profile, a Rockcraft extension, a Charmcraft profile, and a Charmcraft extension of the same name) supports Flask applications. Most of the functionality is already built in, but the suite also exposes certain knobs that you can customise. These are as below.
rockcraft.yaml
> parts
> flask-framework/dependencies:
> stage-packages
You can use this key to specify any dependencies required for your Flask application. For example, below we use it to specify libpq-dev
:
parts:
flask-framework/dependencies:
stage-packages:
# list required packages or slices for your flask application below.
- libpq-dev
rockcraft.yaml
> parts
> flask-framework/install-app:
> prime
You can use this key to specify the files to be included in your rock upon rockcraft pack
, in flask/app/<filename>
notation. For example:
parts:
flask-framework/install-app:
prime:
- flask/app/.env
- flask/app/app.py
- flask/app/webapp
- flask/app/templates
- flask/app/static
Some files, if they exist, are included by default. These include: app
, app.py
, migrate
, migrate.sh
, migrate.py
, static
, templates
.
Regarding the migrate.sh
file:
If your app depends on a database it is common to run a database migration
script before app startup which, for example, creates or modifies tables. This
can be done by including the migrate.sh
script in the root of your project. It
will be executed with the same environment variables and context as the Flask
application.
If the migration script fails, the app won’t be started and the app charm will go into blocked state. The migration script will be run on every unit and it is assumed that it is idempotent (can be run multiple times) and that it can be run on multiple units at the same time without causing issues. This can be achieved by, for example, locking any tables during the migration.
charmcraft.yaml
> config
> options
You can use the predefined options (run charmcraft expand-extension
for details) or add some of your own. In the latter case, any option you define will be used to generate environment variables, on the template config option name
→ FLASK_CONFIG_OPTION_NAME
. In either case, a user of your charm will be able to set it in the usual way by running juju config <application> <option>=<value>
.
For example, if you define an option called token
, as below, this will generate a FLASK_TOKEN
environment variable, and a user of your charm can set it by running juju config <application> token=<token>
.
config:
options:
token:
description: The token for the service.
type: string
required: true
charmcraft.yaml
> peers
, provides
, requires
Your charm already has some peers
, provides
, and requires
endpoints
Expand to view pre-loaded endpoints
peers:
secret-storage:
interface: secret-storage
provides:
metrics-endpoint:
interface: prometheus_scrape
grafana-dashboard:
interface: grafana_dashboard
requires:
logging:
interface: loki_push_api
ingress:
interface: ingress
limit: 1
In addition to that you may also add one or more of the following additional endpoint definitions, as needed.
requires:
# Enable integration with the mysql and the mysql-k8s charm:
mysql:
interface: mysql_client
limit: 1
# Enable integration with the postgresql and the postgresql-k8s charm:
postgresql:
interface: postgresql_client
limit: 1
# Enable integration with the mongodb charm:
mongodb:
interface: mongodb_client
limit: 1
# Enable integration with the redis charm:
redis:
interface: redis
limit: 1
Your charm’s code is already set up to interpret them and enable integration with any charms that support the same endpoint interface but have the opposite role simply by running juju integrate app1 app2
.
After the integration has been established, the connection string (required to be able to connect to the database) will be available as one of the following environment variables:
MYSQL_DB_CONNECT_STRING
POSTGRESQL_DB_CONNECT_STRING
MONGODB_DB_CONNECT_STRING
REDIS_DB_CONNECT_STRING
.