Manage 12-factor app charms¶
See also: Juju | Charm taxonomy
Prepare an OCI image for a 12-factor app charm¶
Initialise a 12-factor app charm¶
Use charmcraft init
and specify the relevant profile:
charmcraft init --profile <profile>
Charmcraft automatically creates a charmcraft.yaml
project file, a
requirements.txt
file and source code for the charm in your current directory. You
will need to check the project file and README.md
to verify that the charm’s name
and description are correct.
See also: init
Specify the flask-framework
profile:
charmcraft init --profile flask-framework
Specify the django-framework
profile:
charmcraft init --profile django-framework
Specify the fastapi-framework
profile:
charmcraft init --profile fastapi-framework
Specify the go-framework
profile:
charmcraft init --profile go-framework
Manage configurations for a 12-factor app charm¶
A charm configuration can be added if your 12-factor app
requires environment variables, for example, to pass a
token for a service. Add the configuration in charmcraft.yaml
:
config:
options:
token:
description: The token for the service.
type: string
A user-defined configuration option will correspond to
an environment variable generated by the paas-charm
project to expose the configuration to the Flask workload.
In general, a configuration option config-option-name
will be mapped as FLASK_CONFIG_OPTION_NAME
where the
option name will be converted to upper case, dashes will be
converted to underscores and the FLASK_
prefix will be
added. In the example above, the token
configuration will
be mapped as the FLASK_TOKEN
environment variable. In
addition to the environment variable, the configuration is
also available in the Flask variable app.config
without
the FLASK_
prefix.
A user-defined configuration option will correspond to an
environment variable generated by the paas-charm
project
to expose the configuration to the Django workload. In general,
a configuration option config-option-name
will be mapped as
DJANGO_CONFIG_OPTION_NAME
where the option name will be
converted to upper case, dashes will be converted to underscores
and the DJANGO_
prefix will be added. In the example above,
the token
configuration will be mapped as the DJANGO_TOKEN
environment variable.
A user-defined configuration option will correspond to an environment
variable generated by the paas-charm
project to expose the
configuration to the FastAPI workload. In general, a configuration option
called config-option-name
will be mapped as APP_CONFIG_OPTION_NAME
where the option name will be converted to upper case, dashes will be
converted to underscores and the APP_
prefix will be added. In the
example above, the token
configuration will be mapped as the
APP_TOKEN
environment variable.
A user-defined configuration option will correspond to an environment
variable generated by the paas-charm
project to expose the
configuration to the Go workload. In general, a configuration option
config-option-name
will be mapped as APP_CONFIG_OPTION_NAME
where the option name will be converted to upper case, dashes will be
converted to underscores and the APP_
prefix will be added. In the
example above, the token
configuration will be mapped as the
APP_TOKEN
environment variable.
The configuration can be set on the deployed charm using:
juju config <app name> token=<token>
Manage relations for a 12-factor app charm¶
A charm integration can be added to your charmed 12-factor app by providing the integration and endpoint definition in your project file:
requires:
<endpoint name>:
interface: <endpoint interface name>
optional: false
Here, <endpoint name>
corresponds to the endpoint of the application with which
you want the integration, and <endpoint interface name>
is the endpoint schema
to which this relation conforms. Both the <endpoint name>
and
<endpoint interface name>
must coincide with the structs defined in the
pfoject file of that particular application’s charm. The key optional
with value False
means that the charm will get blocked and stop the services if
the integration is not provided.
You can provide the integration to your deployed 12-factor app using:
juju integrate <app charm> <endoint name>
After the integration has been established, the connection string and other configuration options will be available as environment variables that you may use to configure your 12-factor application.
For example, if you wish to integrate your 12-factor application with PostgreSQL (machine or k8s charm), add the following endpoint definition to your project file:
requires:
postgresql:
interface: postgresql_client
optional: True
Provide the integration to your deployed 12-factor app with:
juju integrate <app charm> postgresql
This integration creates the following environment variables you may use to configure your 12-factor application.
POSTGRESQL_DB_CONNECT_STRING
POSTGRESQL_DB_SCHEME
POSTGRESQL_DB_NETLOC
POSTGRESQL_DB_PATH
POSTGRESQL_DB_PARAMS
POSTGRESQL_DB_QUERY
POSTGRESQL_DB_FRAGMENT
POSTGRESQL_DB_USERNAME
POSTGRESQL_DB_PASSWORD
POSTGRESQL_DB_HOSTNAME
POSTGRESQL_DB_PORT
See also: How to add an integration to a charm
Manage secrets for a 12-factor app charm¶
A user secret can be added to a charm and all the keys and values in the secret will be exposed as environment variables. Add the secret configuration option in your project file:
config:
options:
api-token:
type: secret
description: Secret needed to access some API secret information
Once the charm is deployed, you can add a juju secret to the model:
user@host:~$
juju add-secret my-api-token value=1234 othervalue=5678
secret:cru00lvmp25c77qa0qrg
From this output, you can get the Juju secret ID. Grant the application access to view the value of the secret:
juju grant-secret my-api-token <app name>
Add the Juju secret ID to the application:
juju config <app name> api-token=secret:cru00lvmp25c77qa0qrg
The following environment variables are available for the application:
APP_API_TOKEN_VALUE: "1234"
APP_API_TOKEN_OTHERVALUE: "5678"
See also: How to manage secrets
The following environment variables are available for the application:
DJANGO_API_TOKEN_VALUE: "1234"
DJANGO_API_TOKEN_OTHERVALUE: "5678"
See also: How to manage secrets
The following environment variables are available for the application:
APP_API_TOKEN_VALUE: "1234"
APP_API_TOKEN_OTHERVALUE: "5678"
See also: How to manage secrets
The following environment variables are available for the application:
APP_API_TOKEN_VALUE: "1234"
APP_API_TOKEN_OTHERVALUE: "5678"
See also: How to manage secrets
Use 12-factor app charms¶
(If your charm is a Django charm) Create an admin user¶
Use the create-superuser
action to create a new Django admin account:
juju run <app name> create-superuser username=<username> email=<email>
(If your workload depends on a database) Migrate the database¶
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
12-factor app.
If the migration script fails, it will retry upon update-status
. The migration
script will run on every unit. The script is assumed to be idempotent (in other words,
can be run multiple times) and that it can be run on multiple units simultaneously
without issue. Handling multiple migration scripts that run concurrently
can be achieved by, for example, locking any tables during the migration.