<a id="controller"></a>

# Controller

See also: [How to manage controllers](https://documentation.ubuntu.com/juju/4.0/howto/manage-controllers.md#manage-controllers)

In software design, a **controller** is an architectural component responsible for managing the flow of data and interactions within a system, and for mediating between different parts of the system. In Juju, it is defined in the same way, with the mention that:

- It is set up via the boostrap process.
- It refers to the initial controller [unit](https://documentation.ubuntu.com/juju/4.0/reference/unit.md#unit) as well as any units added later on (for machine clouds, for the purpose of [high-availability](https://documentation.ubuntu.com/juju/4.0/reference/high-availability.md#high-availability)) – each of which includes
  - a [unit agent](https://documentation.ubuntu.com/juju/4.0/reference/agent.md#unit-agent),
  - [`juju-controller`](https://charmhub.io/juju-controller) charm code, and
  - a [controller agent](https://documentation.ubuntu.com/juju/4.0/reference/agent.md#controller-agent) running, among other things, the Juju API server and an in-process embedded [Dqlite](https://canonical.com/dqlite) [database](https://documentation.ubuntu.com/juju/4.0/reference/database.md#database). <p>
- It is responsible for implementing all the changes defined by a Juju [user](https://documentation.ubuntu.com/juju/4.0/reference/user.md#user) via a Juju client post-bootstrap.
- It stores state in the internal Dqlite [database](https://documentation.ubuntu.com/juju/4.0/reference/database.md#database).

<a id="controller-storage"></a>

## Controller storage

A Juju controller has two basic persistent storage needs: [database](https://documentation.ubuntu.com/juju/4.0/reference/database.md#database) access and blob storage. By default, Juju will use the filesystem of the controller’s supporting infrastructure.

<!-- ADD BACK IN WHEN WE MOVE THOSE VALUES INTO SECRETS.

However, either during bootstrap or later, you can (and, in a production-setting, should!) specify any S3-compatible object store you want (e.g., AWS S3, MicroCeph, MinIO, etc.) using the object-store-related controller configuration keys ({ref}\`controller-config-object-store-type\`, {ref}\`controller-config-object-store-s3-endpoint\`, {ref}\`controller-config-object-store-s3-static-key\`, {ref}\`controller-config-object-store-s3-static-secret\`, {ref}\`controller-config-object-store-s3-static-session\`, {ref}\`controller-config-object-store-s3-region\`).

Also, Juju will apply default S3 policy permissions, but you are free to change them, so long as they satisfy the following as a minimum (at least, during model creation):

\`\`\`text
{
   "Version" : "2012-10-17",
   "Statement" : [
      {
         "Effect" : "Allow",
         "Action" : [
            "s3:CreateBucket",
            "s3:PutBucketPolicy",
            "s3:PutBucketTagging",
            "s3:PutBucketVersioning",
            "s3:PutBucketObjectLockConfiguration"
         ],
         "Resource" : "arn:aws:s3:::\*"
      },
      {
         "Effect" : "Allow",
         "Action" : [
            "s3:ListBucket",
            "s3:ListBucketVersions",
            "s3:ListAllMyBuckets",
            "s3:GetBucketLocation",
            "s3:GetBucketPolicy",
            "s3:GetBucketTagging",
            "s3:GetBucketVersioning",
            "s3:GetBucketObjectLockConfiguration",
            "s3:GetObject",
            "s3:GetObjectLegalHold",
            "s3:GetObjectRetention",
            "s3:PutObject",
            "s3:PutObjectLegalHold",
            "s3:BypassGovernanceRetention",
            "s3:PutObjectRetention",
            "s3:DeleteObject"
         ],
         "Resource" : "arn:aws:s3:::\*"
      }
   ]
}
\`\`\` -->
